อธิบายหลักการทำงานของ Transformer: ทำความเข้าใจคณิตศาสตร์ที่อยู่เบื้องหลัง
(osanseviero.github.io)- ย่อกระบวนการอนุมานของ Transformer ให้เป็นตัวอย่างการแปล Hello World → Hola Mundo เพื่อให้ไล่ตามด้วยมือได้ตั้งแต่การทำ tokenization ไปจนถึง encoder, decoder และการคำนวณความน่าจะเป็นของ token ถัดไป
- แทนที่จะใช้การตั้งค่าขนาดใหญ่จากบทความต้นฉบับ ตัวอย่างนี้ใช้ embedding 4 มิติ, attention head 2 หัว และชั้น feedforward 8 มิติ เพื่อทำให้ลำดับการคูณเมทริกซ์และ softmax มีขนาดเล็กลง
- Encoder จะบวก positional encoding เข้ากับ token embedding แล้วผ่าน multi-head self-attention และชั้น feedforward เพื่อสร้าง representation เชิงบริบทของลำดับอินพุต
- Decoder เริ่มจาก
SOSและใช้ทั้ง token ที่สร้างก่อนหน้าและผลลัพธ์จาก encoder โดยใน encoder-decoder attention query คำนวณจาก decoder ส่วน key/value คำนวณจากผลลัพธ์ของ encoder - embedding สุดท้ายของ decoder จะผ่านชั้นเชิงเส้นและ softmax เพื่อกลายเป็นความน่าจะเป็นของ token ถัดไป แต่ตัวอย่างนี้ใช้ น้ำหนักแบบสุ่ม จึงไม่ควรคาดหวังคุณภาพการแปลจริง
เป้าหมายและสมมติฐาน
- ตรวจสอบด้วยตัวอย่าง end-to-end ว่า คณิตศาสตร์ระหว่างการอนุมาน ภายในโมเดล Transformer เชื่อมต่อกันอย่างไร
- ลดขนาดโมเดลลงมากเพื่อให้ตามการคำนวณด้วยมือได้ง่าย
- แทนมิติ embedding 512 ในบทความต้นฉบับ ตัวอย่างนี้ใช้ 4 มิติ
- ใช้ attention head 2 หัว แทน 8 หัวในบทความต้นฉบับ
- ใช้มิติ feedforward 8 มิติ แทน 2048 ในบทความต้นฉบับ
- พื้นฐานที่ต้องมีคือพีชคณิตเชิงเส้นระดับพื้นฐาน และการคำนวณส่วนใหญ่ดำเนินไปด้วยการคูณเมทริกซ์
- โฟกัสที่ว่าการคำนวณจริง ดำเนินไปอย่างไร มากกว่าว่า Transformer “คืออะไร”
- ควรอ่านคำอธิบายเชิงสัญชาตญาณร่วมกับ The Illustrated Transformer ส่วนบทความต้นฉบับคือ Attention is all you need
การสร้างอินพุตของ encoder
-
Tokenization
- โมเดล machine learning ประมวลผลตัวเลข ไม่ใช่ข้อความ จึงแปลงข้อความอินพุตเป็น token ID
- เพื่อความเรียบง่าย ตัวอย่างนี้แบ่ง
"Hello World"เป็น token ระดับคำสองคำคือ"Hello"และ"World" - วิธี tokenization จริงอาจแบ่งเป็นแบบอิงคำ แบบอิงตัวอักษร หรือแบบอิง subword
- แบบอิงคำต้องใช้ vocabulary ขนาดใหญ่ และถือว่า
"dog"กับ"dogs"เป็น token คนละตัว - แบบอิงตัวอักษรมี vocabulary เล็ก แต่อาจมีข้อมูลเชิงความหมายน้อย
- subword tokenization อยู่กึ่งกลางระหว่างวิธีแบบคำและแบบตัวอักษร และฝึก tokenizer ด้วยกระบวนการเชิงสถิติ
-
Token embedding
- token ID เองไม่มีความหมาย จึงแปลงแต่ละ token เป็น embedding ซึ่งเป็นเวกเตอร์ขนาดคงที่
- embedding ในตัวอย่างใช้ค่าที่กำหนดขึ้นเอง
Hello -> [1, 2, 3, 4]World -> [2, 3, 4, 5]
- ใน Transformer จริง การแมป embedding ก็ถูกเรียนรู้เช่นกัน และโมเดลจะเรียนรู้ representation ของ token ให้เหมาะกับงาน
- embedding ทั้งสองถูกรวมเป็นเมทริกซ์เดียวเพื่อใช้ในการคูณเมทริกซ์ต่อไป
-
Positional encoding
- embedding อย่างเดียวไม่สามารถบอก ตำแหน่งในประโยค ของคำได้ จึงต้องบวก positional encoding เข้าไป
- บทความต้นฉบับใช้ positional encoding แบบ sine/cosine คงที่ และตัวอย่างนี้ก็ใช้วิธีเดียวกัน
- positional encoding ในตัวอย่างคำนวณได้ดังนี้
Hello -> [0, 1, 0, 1]World -> [0.84, 0.99, 0, 1]
- บวก token embedding กับ positional encoding เพื่อสร้างเมทริกซ์อินพุตของ encoder
Hello -> [1, 3, 3, 5]World -> [2.84, 3.99, 4, 6]
การคำนวณ Self-attention
-
การสร้าง Q, K, V
- self-attention คำนวณ query(Q), key(K) และ value(V) จาก input embedding
- ตัวอย่างนี้ใช้ attention head 2 หัว โดยแต่ละหัวมีเมทริกซ์
WQ,WK,WVของตัวเอง - เมทริกซ์น้ำหนักแต่ละตัวจะแปลง embedding 4 มิติเป็น query/key/value 3 มิติ
- ในหัวแรก นำเมทริกซ์อินพุตไปคูณกับ
WK1,WV1,WQ1เพื่อได้K1,V1,Q1
-
สูตร Attention
- คะแนน attention คำนวณเป็นสี่ขั้นตอน
- คำนวณ dot product ระหว่าง query กับ key แต่ละตัว
- หารด้วยรากที่สองของมิติ key
- แปลงด้วย softmax ให้เป็นน้ำหนักที่เป็นบวกและมีผลรวมเท่ากับ 1
- ใช้น้ำหนักทำ weighted sum กับเวกเตอร์ value
- กระบวนการนี้ถูกย่อเป็นสูตรในบทความต้นฉบับ
- [
- Attention(Q,K,V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V
- ]
- ในตัวอย่างนี้ เนื่องจากมิติเล็กและค่าเริ่มต้นแบบสุ่ม ผลลัพธ์ softmax จึงเอนเอียงไปใกล้ 0 กับ 1 มาก
- ค่า dot product ขนาดใหญ่อาจถูกขยายแรงขึ้นใน softmax จึงจำเป็นต้องมีการ scale ด้วยการหารด้วยรากที่สองของมิติ key
- เพื่อการอธิบาย มีการใช้รูปแบบดัดแปลงที่หารด้วย 30 แทน
sqrt(3)ชั่วคราว แต่ไม่ใช่วิธีแก้ระยะยาว
- คะแนน attention คำนวณเป็นสี่ขั้นตอน
-
ผลลัพธ์ของ multi-head attention
- นำผล attention ของแต่ละหัวมา concatenate กัน แล้วคูณด้วยเมทริกซ์น้ำหนักที่ถูกเรียนรู้ เพื่อแปลงกลับไปเป็นมิติ embedding
- ในตัวอย่างนี้รวมผลของสองหัวเป็นเมทริกซ์ 6 มิติ แล้วแปลงเป็นผลลัพธ์ 4 มิติ
- ผลลัพธ์นี้ถูกส่งต่อไปยังขั้นตอนถัดไปของ encoder block คือชั้น feedforward
ชั้น feedforward และ encoder block
-
ชั้น feedforward
- หลัง self-attention จะมี feedforward neural network (FFN) อยู่
- FFN ประกอบด้วยการแปลงเชิงเส้นสองครั้ง และ ReLU activation อยู่ระหว่างกลาง
- ชั้นเชิงเส้นแรกขยายมิติ และชั้นเชิงเส้นที่สองลดมิติกลับเป็นขนาดเดิม
- ReLU ทำให้ค่าติดลบกลายเป็น 0 และคงค่าบวกไว้ตามเดิม เพื่อเพิ่มความไม่เป็นเชิงเส้น
- ในตัวอย่างนี้ขยายอินพุต 4 มิติเป็น 8 มิติ แล้วลดกลับเป็น 4 มิติ
- [
- \text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2
- ]
-
Encoder block
- encoder block หนึ่งประกอบด้วย multi-head attention และ FFN
- บทความต้นฉบับซ้อน encoder 6 ตัว และโค้ดตัวอย่างก็ทำซ้ำ encoder ด้วย
n=6 - หากส่งค่าผ่าน encoder block หลายตัวแบบตรง ๆ ค่าอาจใหญ่เกินไปจนเกิด overflow ในการคำนวณ softmax และได้
nan
Residual connection และ layer normalization
-
ปัญหาค่าพุ่งสูง
- ในตัวอย่าง เมื่อผ่าน encoder 6 ตัว จะเกิดคำเตือน
overflow encountered in expและinvalid value encountered in divideและผลลัพธ์กลายเป็นnan - ปรากฏการณ์ที่ค่ามีขนาดใหญ่เกินไปและยิ่งใหญ่ขึ้นในชั้นถัดไปเป็นปัญหาที่พบได้บ่อยใน deep neural network
- กรณีที่ gradient ใหญ่เกินไประหว่าง backpropagation เรียกว่า gradient explosion
- ในตัวอย่าง เมื่อผ่าน encoder 6 ตัว จะเกิดคำเตือน
-
Residual connection
- residual connection คือการนำอินพุตของชั้นไปบวกกับเอาต์พุตของชั้นนั้น
- [
- \text{Residual}(x) = x + \text{Layer}(x)
- ]
- ในตัวอย่างนี้ใช้ residual connection กับทั้งผลลัพธ์ attention และผลลัพธ์ FFN
- residual connection ใช้เพื่อบรรเทาปัญหา vanishing gradient
-
Layer normalization
- layer normalization ทำ normalization ให้แต่ละมิติของ embedding มีค่าเฉลี่ย 0 และส่วนเบี่ยงเบนมาตรฐาน 1
- สูตรเป็นดังนี้
- [
- \text{LayerNorm}(x) = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} \times \gamma + \beta
- ]
- (\epsilon) คือค่าขนาดเล็กเพื่อหลีกเลี่ยงปัญหาการหารด้วย 0 เมื่อส่วนเบี่ยงเบนมาตรฐานเป็น 0
- (\gamma) และ (\beta) เป็นพารามิเตอร์ที่เรียนรู้ได้เพื่อควบคุม scaling และ shifting
- หลังเพิ่ม residual connection และ layer normalization แล้ว แม้ผ่าน encoder 6 ตัวก็ได้ค่าปกติโดยไม่มี
nan
โครงสร้างของ decoder
-
อินพุตของ decoder และวิธีการสร้าง
- decoder รับผลลัพธ์จาก encoder และลำดับเอาต์พุตที่สร้างมาแล้วจนถึงตอนนี้เป็นอินพุต
- ระหว่างการอนุมาน จะเริ่มจาก token SOS(start-of-sequence)
- decoder สร้าง token ทีละตัวแบบ autoregressive
- รอบที่ 1: รับ
SOSเป็นอินพุตแล้วสร้าง"hola" - รอบที่ 2: รับ
SOS + holaเป็นอินพุตแล้วสร้าง"mundo" - รอบที่ 3: รับ
SOS + hola + mundoเป็นอินพุตแล้วสร้างEOS
- รอบที่ 1: รับ
- เมื่อสร้าง token
EOS(end-of-sequence)แล้วจะหยุด decoding - encoder สามารถสร้าง representation ได้ด้วย forward pass เพียงครั้งเดียว แต่ decoder ต้องทำ forward pass หลายครั้ง จึงช้ากว่า
-
องค์ประกอบของ decoder block
- decoder block ซับซ้อนกว่า encoder block และประกอบด้วยลำดับต่อไปนี้
- masked self-attention
- residual connection และ layer normalization
- encoder-decoder attention
- residual connection และ layer normalization
- ชั้น feedforward
- residual connection และ layer normalization
- ในตัวอย่างการอนุมาน ใช้
[1, 1, 0, 1]ซึ่งได้จากการบวก positional encoding เข้ากับ embedding ของSOS - ระหว่างการฝึก ใช้ masked self-attention ที่ mask attention score เป็น
-infเพื่อไม่ให้มองเห็น token ในอนาคต
- decoder block ซับซ้อนกว่า encoder block และประกอบด้วยลำดับต่อไปนี้
Encoder-decoder attention
- encoder-decoder attention เป็นขั้นตอนที่ทำให้ decoder โฟกัสกับส่วนที่เกี่ยวข้องของประโยคอินพุต
- วิธีคำนวณเหมือน self-attention แต่แหล่งอินพุตสำหรับสร้าง Q/K/V ต่างกัน
- query คำนวณจากผลลัพธ์ของชั้น decoder ก่อนหน้า
- key และ value คำนวณจาก ผลลัพธ์ของ encoder
- โครงสร้างนี้ทำให้แต่ละตำแหน่งของ decoder อ้างอิงทุกตำแหน่งในลำดับอินพุตได้
- มีประโยชน์กับงานที่ token เอาต์พุตต้องขึ้นกับตำแหน่งที่เกี่ยวข้องในประโยคอินพุต เช่น การแปล
การสร้าง token เอาต์พุต
-
Linear layer และ softmax
- ผลลัพธ์ของ decoder ยังไม่ใช่คำโดยตรง จึงนำ embedding สุดท้ายผ่านชั้นเชิงเส้นเพื่อแปลงเป็นเวกเตอร์ logits ที่มีขนาดเท่ากับ vocabulary
- ขนาด vocabulary ในตัวอย่างคือ 10 และตัวเลือก token ถัดไปมีดังนี้
hello,mundo,world,how,?,EOS,SOS,a,hola,c
- logits ผ่าน softmax เพื่อกลายเป็นการแจกแจงความน่าจะเป็นของแต่ละ token
- ในความน่าจะเป็นของตัวอย่าง
"hola"มีค่าสูงสุด จึงถูกเลือกเป็น token ถัดไป - วิธีเลือก token ที่มีความน่าจะเป็นสูงสุดเสมอเรียกว่า greedy decoding และไม่ได้ดีที่สุดเสมอไป
- อ่านรายละเอียดเพิ่มเติมเกี่ยวกับเทคนิคการสร้างได้ใน บทความของ Hugging Face
-
ลูปการสร้างทั้งหมด
- ขั้นตอนการสร้างทั้งหมดเป็นไปตามลำดับดังนี้
- แปลงลำดับอินพุตเป็น embedding
- encoder สร้าง representation เชิงบริบทของอินพุตทั้งหมด
- decoder เริ่มจาก
SOSและใช้ทั้ง token ที่สร้างก่อนหน้าและผลลัพธ์จาก encoder - ใช้ linear layer และ softmax กับ embedding สุดท้ายของ decoder
- เลือก token ถัดไปที่มีความเป็นไปได้สูงสุดแล้วเพิ่มเข้าในลำดับ
- ทำซ้ำจนกว่า
EOSจะออกมาหรือถึงความยาวสูงสุด
- การรันตัวอย่างสร้าง
SOS hola mundo worldสำหรับอินพุตhello world - เนื่องจากน้ำหนักและ embedding ทั้งหมดถูกใช้แบบสุ่ม ผลลัพธ์จึงไม่ใช่การแปลที่ดี และนี่เป็นพฤติกรรมที่คาดไว้
- ขั้นตอนการสร้างทั้งหมดเป็นไปตามลำดับดังนี้
สรุปและขอบเขต
- ตัวอย่างนี้เชื่อมองค์ประกอบหลักของ Transformer ได้แก่ embedding, positional encoding, self-attention, multi-head attention, FFN, residual connection, layer normalization, encoder-decoder attention และเอาต์พุต softmax ให้เป็นลำดับเดียว
- สถาปัตยกรรม Transformer สมัยใหม่เพิ่มเทคนิคต่าง ๆ เข้ามาอีกหลายอย่าง แต่คณิตศาสตร์หลักอิงกับโครงสร้างที่กล่าวถึงในตัวอย่างนี้
- stack ที่ใช้สามารถแตกต่างกันได้ตามประเภทงาน
- งานที่เน้นความเข้าใจ เช่น classification อาจวาง linear layer ไว้บน encoder stack
- งานที่เน้นการสร้าง เช่น translation อาจใช้ทั้ง encoder stack และ decoder stack ร่วมกัน
- งานสร้างข้อความแบบอิสระอย่าง ChatGPT หรือ Mistral อาจใช้เฉพาะ decoder stack
- ไม่ครอบคลุมกระบวนการฝึก แต่โฟกัสที่การทำความเข้าใจ คณิตศาสตร์ของการอนุมาน เมื่อนำโมเดลที่มีอยู่มาใช้
- สำหรับเนื้อหาคณิตศาสตร์ที่เป็นทางการมากขึ้น สามารถดูได้ที่ PDF นี้
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
“ความลึกลับ” ของ Transformer อยู่ตรงที่ แทนที่จะเอาน้ำหนักและค่าคงที่ในแต่ละชั้นมาคูณกันตามลำดับเชิงเส้น มันสร้าง เมทริกซ์ 3 ตัว จากการเอาอินพุตเดียวกันไปคูณกับน้ำหนักที่เรียนรู้มา แล้วเอาเมทริกซ์เหล่านั้นมาคูณกันเอง
วิธีนี้เพิ่มความขนานและทำงานได้ดี แต่ตัว สูตร attention เองถูกกำหนดตายตัว จึงมีข้อจำกัดมาก
ถ้าจะพัฒนาต่อไป ดูเหมือนต้องมีวิธีทำให้กราฟการคำนวณเองกลายเป็นพารามิเตอร์ที่เรียนรู้ได้ ผมไม่แน่ใจว่าวิธี gradient แบบดั้งเดิมจะทำได้ไหม เพราะผลแบบ chaotic ที่การเปลี่ยนแปลงเล็ก ๆ นำไปสู่ความต่างของประสิทธิภาพอย่างมาก และภายในอาจต้องใช้รูปแบบอย่าง genetic algorithm หรือ particle swarm optimization
ข้อได้เปรียบเชิงทฤษฎีใหญ่เมื่อเทียบกับ RNN คือมันรองรับสิ่งนี้ได้ โดยไม่สูญเสียข้อมูล เพราะแต่ละองค์ประกอบเข้าถึงข้อมูลทั้งหมดขององค์ประกอบอื่นในลำดับ หรือในกรณีตามลำดับเวลา ก็เข้าถึงข้อมูลทั้งหมดขององค์ประกอบก่อนหน้าได้
ในทางกลับกัน RNN และ “Linear Transformer” จะบีบอัดค่าจากอดีต ดังนั้นโดยทั่วไปองค์ประกอบสุดท้ายของลำดับยาว ๆ จึงเข้าถึงข้อมูลทั้งหมดขององค์ประกอบแรกได้ยาก และเป็นไปไม่ได้ เว้นแต่ internal state จะใหญ่มากจนไม่ทิ้งข้อมูลใดเลย
ปัญหาคือสิ่งที่ได้จากตรงนี้มีไม่มากนัก โอเปอเรชันที่ไม่ใช่การคูณเมทริกซ์ มีแนวโน้มว่าจะช้ากว่า หรือเร็วพอ ๆ กันเท่านั้น
แต่ถ้าใส่ flow control เข้าไป ก็เสี่ยงจะกลายเป็น Turing machine ในทางปฏิบัติ และเมื่อเป็นแบบนั้น การเรียนรู้ก็จะกลายเป็นปัญหาอย่างที่พูดไว้ ถึงอย่างนั้นก็อาจไม่ใช่ปัญหาที่รับมือไม่ได้ทั้งหมด
ถ้าต้องการคำอธิบายที่แห้งกว่า เป็นทางการกว่า และกระชับกว่า มี “The Transformer Model in Equations” ของ John Thickstun [0]
ทั้งหมดใส่ได้ใน หน้าเดียว ด้วยสัญกรณ์คณิตศาสตร์มาตรฐาน
[0] https://johnthickstun.com/docs/transformers.pdf
บ่อยครั้งนักวิจัย machine learning ดูเหมือนไม่เคยเรียนคณิตศาสตร์มาเลย
คำอธิบายที่ว่า “เกิด NaN ค่าใหญ่เกินไปจนระเบิดเมื่อส่งต่อไปยัง encoder ถัดไป นี่คือ gradient explosion” เท่าที่ผมเข้าใจนั้นผิด
ตรงนี้ไม่มีจุดไหนที่คำนวณ gradient เลย ดังนั้นจึงไม่ใช่ gradient explosion
ปัญหาดูเหมือนอยู่ที่การ implement softmax และวิธี implement softmax ให้เสถียรเชิงตัวเลขอธิบายไว้ที่นี่ [0]
[0]: https://jaykmody.com/blog/stable-softmax/
อย่างไรก็ตาม neural network ทั้งระบบก็ไวต่อค่าขนาดใหญ่ ดังนั้น softmax ที่เสถียรเชิงตัวเลขอย่างเดียวแก้ไม่ได้ normalization เป็นหัวใจสำคัญเพื่อให้เครือข่ายทำงานได้
บทเรียน Transformer อาจกลายเป็น บทเรียน Monad แบบใหม่ก็ได้ เป็นแนวคิดที่เข้าใจยาก แต่เป็นประเภทที่ต้องฝึกทำตัวอย่างและคลุกคลีกับมันถึงจะเข้าใจ
เหมือนกับหลาย ๆ เรื่องในวิทยาการคอมพิวเตอร์
อ่านไปแค่หกย่อหน้าก็มีคำถามแล้ว
ใน
Hello -> [1,2,3,4] World -> [2,3,4,5]บอกว่าเวกเตอร์เป็นแบบสุ่ม แต่ดูเหมือนมีแพตเทิร์นอยู่ อยากรู้ว่า2ที่อยู่ในทั้งสองเวกเตอร์มีความหมายอะไรไหม หรือว่าชุดทั้งหมดเป็นตัวสร้างความเป็นเอกลักษณ์กันแน่ตรงนี้ห่างกันประมาณ 60 องศา และไปในทิศทางเดียวกันอยู่บ้าง แต่เพราะพยายามไม่ใส่เลขลบในตัวอย่าง จึงทำให้เวกเตอร์ดูคล้ายกันกว่าความเป็นจริง
ข้อเท็จจริงที่ว่าตัวเลขถูกใช้ซ้ำเองไม่มีความหมาย
1ในตำแหน่งแรกแทบไม่เกี่ยวกับ1ในตำแหน่งที่สองเลย เพราะเราไม่ได้ทำ convolution บนเวกเตอร์นี้หลังฝึกแล้ว คำที่คล้ายกันจะมี cosine similarity ในระดับหนึ่ง แต่แทบไม่มีกรณีที่ cosine similarity จะสูงเท่า
[1,2,3,4]กับ[2,3,4,5]แม้จะไม่ใช่คำถามที่เกี่ยวข้องโดยตรงทั้งหมด แต่กำลังมองหาบทความหรือเปเปอร์ที่อธิบายว่าทำไม Transformer ซึ่งดูเหมือนทำงานเป็นเพียง “ตัวทำนายโทเค็นถัดไป” ถึงสามารถจัดการคำถามแบบต่อไปนี้ได้
"sdsfs_ff","fsdf_value"เป็นคอลัมน์น่าจะเป็นคำถามที่พบบ่อย แต่หาไม่เจอว่าควรใช้คีย์เวิร์ดอะไรค้นหา ถ้ามีลิงก์ที่ลงลึกเรื่อง positional embedding ด้วยก็ดี และยังไม่ได้คำตอบที่น่าพอใจว่าทำไมถึงใช้ไซน์/โคไซน์ รวมถึงเรื่องการคูณเทียบกับการบวก
ถ้าโมเดลเห็นว่าจำเป็น ก็สามารถทำซ้ำลำดับที่ไม่รู้จักโดยคัดลอกโทเค็นตัวอักษรเดี่ยว หรือสร้างขึ้นใหม่ได้ถ้าเข้ากับบริบท
P(X_1=x_1, X_2=x_2, X_3=x_3) = P(X_3=x_3 | X_1=X_1, X_2=x_2) • P(X_1=x_1, X_2=x_2)= P(X_3=x_3 | X_1=X_1, X_2=x_2) • P(X_2=x_2 | X_1=x_1) • P(X_1=x_1)กล่าวคือ หากมี การแจกแจงความน่าจะเป็นแบบมีเงื่อนไข ที่ถูกต้องสำหรับโทเค็นถัดไป เมื่อกำหนดโทเค็นก่อนหน้าไว้แล้ว ก็จะได้การแจกแจงความน่าจะเป็นที่ถูกต้องสำหรับลำดับโทเค็นทั้งหมดด้วย
“การแจกแจงความน่าจะเป็นที่ถูกต้องสำหรับลำดับโทเค็น” หรือการแจกแจงความน่าจะเป็นแบบมีเงื่อนไขที่ถูกต้องของลำดับโทเค็นเมื่อมีเงื่อนไขบางอย่างกำหนดไว้ แทบจะสามารถใช้อธิบายพฤติกรรมอินพุต/เอาต์พุตได้เกือบทุกประเภท
ดังนั้น การบอกว่า “ทำงานโดยทำนายโทเค็นถัดไป” โดยหลักการแล้วจึงไม่ใช่ข้อจำกัดใหญ่ต่อพฤติกรรมอินพุต/เอาต์พุตที่มันสามารถทำได้
ไม่ว่ามันจะทำสิ่งที่น่าประทับใจแค่ไหน เอาต์พุตนั้นก็มาจาก
P(X_{n+1}=x_{n+1} | X_1=x_1, ..., X_n=x_n)หรือก็คือข้อเท็จจริงที่ว่าเป็น “การทำนายโทเค็นถัดไป” ซึ่งไม่ได้ขัดกันการทำนายโทเค็นถัดไปเป็นงานที่มีความฉลาดมากกว่าที่ฟังดู
เห็นด้วยกับคำกล่าวที่ว่า “ความซับซ้อนมาจากจำนวนขั้นตอนและจำนวนพารามิเตอร์”
โมเดล Transformer ที่เรียบง่ายพอให้เราเข้าใจนั้นทำสิ่งที่น่าสนใจไม่ได้ ส่วน Transformer ที่ซับซ้อนพอจะทำสิ่งที่น่าสนใจได้ก็ดูซับซ้อนเกินกว่าที่เราจะเข้าใจ
อยากลองศึกษา โมเดลขนาดกลาง ที่เรียบง่ายพอให้เข้าใจ แต่ก็ซับซ้อนพอจะทำสิ่งที่น่าสนใจได้
ถ้าใช้แนวคิดโดยไม่ได้นิยามหรือแนะนำก่อนก็เข้าใจยาก ส่วน Encoder เริ่มต้นทันทีโดยไม่อธิบายว่ามันคืออะไร หรืออยู่ตรงไหนในกระบวนการทั้งหมด
เข้าใจว่าผู้เขียนพยายามทำอะไร แต่ขาดโครงสร้างพื้นฐานของบทความที่ควรแนะนำไอเดียก่อน อธิบาย แล้วค่อยนำไปใช้
ถ้าไม่ใช่คนที่กำลังศึกษาเรื่องนี้อยู่แล้วและเข้าใจไปได้ครึ่งหนึ่ง บทความทั้งชิ้นจะรู้สึกสับสน
เคยเขียน ANN ตั้งแต่ศูนย์และไม่ได้ใช้ TensorFlow แต่คำอธิบายนี้ก็ยังทำให้สับสนอยู่ดี
ลองขอให้ ChatGPT อธิบายวิธีเปลี่ยน ANN พื้นฐานให้ไป implement self-attention โดยไม่ใช้คำว่า
MatrixหรือVectorก็ได้คำอธิบายที่ค่อนข้างเรียบง่ายมา ยังไม่ได้ลอง implement เองชอบคิดทุกอย่างในมุมของโหนด น้ำหนัก และเลเยอร์มากกว่า เมทริกซ์กับเวกเตอร์ทำให้เชื่อมโยงกับสิ่งที่เกิดขึ้นจริงภายใน ANN ได้ยากขึ้น
ในวิธีเขียน ANN ที่คุ้นเคย อินพุตแต่ละโหนดเป็นสเกลาร์ แต่อัลกอริทึม forward propagation จะคูณน้ำหนักกับอินพุตทุกโหนดแล้วนำมาบวกกัน จึงดูเหมือนการคูณเวกเตอร์-เมทริกซ์ รู้สึกเหมือนกำลังเข้าหาคำอธิบายเหล่านี้ด้วยกรอบคิดที่ผิด และอาจเป็นเพราะขาดพื้นฐานที่จำเป็นอยู่ก็ได้