คู่มือ Transformer — ลบทุกอย่าง เหลือแค่กราฟ
เข้าใจ Transformer ถึงแก่นจากคำถามเดียว — ทำไมการลบสิ่งที่มนุษย์ออกแบบด้วยมือทิ้ง กลับทำให้เครื่องเก่งขึ้น ตั้งแต่ Software 1.0 จนอ่านโค้ด attention ออกทีละบรรทัด
ลบสิ่งที่มนุษย์ออกแบบด้วยมือทิ้ง แล้วเครื่องกลับเก่งขึ้น — ทำไม (เล่มข้างทางของบันไดสาย AI · อ่านตอนไหนก็ได้ ไม่ต้องต่อจากเล่มไหน) · บันไดสาย AI สอนวิธีใช้โมเดล เล่มนี้เปิดฝาดูข้างในมัน — พาจากคนที่รู้แค่ว่า "AI ตอบคำถามได้" ไปจนอ่านโค้ด attention ออกทีละบรรทัด และตอบได้ว่าทำไมสถาปัตยกรรมเดียวกันจึงกินรวบทั้งภาพ เสียง และภาษา · เน้นกลไกและเหตุผลเชิงออกแบบ ไม่ใช่การท่องสูตร
- ระดับ: เริ่มจากศูนย์ → ระดับเทพ
- เวลาอ่าน: ~70 นาที
- ภาษา: ไทย พร้อมไดอะแกรมและโค้ดที่รันได้จริง
เล่มนี้เรียบเรียงจากการบรรยายของ Andrej Karpathy ที่ Stanford (อดีต Director of AI ของ Tesla และหนึ่งในทีมก่อตั้ง OpenAI) ซึ่งเล่าวิวัฒนาการของการสั่งงานคอมพิวเตอร์ต่อเนื่องไปถึงกลไกภายในของ Transformer ในคราวเดียว ตัวเลขและเหตุการณ์ทางประวัติศาสตร์ทุกจุดในเล่มถูกตรวจกับต้นทางอีกชั้นก่อนเขียนลง และจุดที่ยังเป็นคำบอกเล่าจะระบุไว้ตรง ๆ ว่าเป็นคำบอกเล่า
LEVEL 0 · ปูพื้นจากศูนย์
ลบอะไรออก แล้วมันเก่งขึ้น#
บทนี้สำคัญที่สุดในเล่ม ถ้าเข้าใจคำถามเดียวในบทนี้ อีกสิบเอ็ดบทที่เหลือจะกลายเป็นเรื่องที่ "เดาได้" แทนที่จะต้องท่องจำ
ประวัติศาสตร์ของปัญญาประดิษฐ์มักถูกเล่าเป็นเรื่องของการ เพิ่ม — เพิ่มข้อมูล เพิ่มชั้นในโมเดล เพิ่มการ์ดจอ ซึ่งไม่ผิด แต่มันเล่าไม่ครบและทำให้พลาดใจความ เพราะทุกครั้งที่วงการก้าวกระโดดจริง ๆ สิ่งที่เกิดขึ้นคือมีการลบของบางอย่างที่มนุษย์ประดิษฐ์ไว้ด้วยมือออกไป
ลองดูสี่จังหวะสำคัญเรียงกัน แล้วสังเกตว่าคอลัมน์ซ้ายคือของที่มนุษย์เคยภูมิใจว่าออกแบบเอง
| จังหวะ | ลบอะไรออก | เหลืออะไรให้เครื่องเรียนเอง |
|---|---|---|
| Software 1.0 → 2.0 | อัลกอริทึมที่มนุษย์เขียนทีละขั้น | ข้อมูล + กระบวนการหาค่าที่เหมาะสม |
| ก่อนปี 2012 → หลัง | ตัวอธิบายลักษณะเฉพาะทางที่ทำมือ | ชั้นในเครือข่ายที่หาลักษณะเอง |
| LSTM → ปี 2017 | การไล่ลำดับทีละคำ | การมองหากันเองระหว่างทุกตำแหน่ง |
| Software 2.0 → 3.0 | รอบการเทรนโมเดล | ข้อความที่พิมพ์เข้าไปตอนใช้งาน |
สังเกตว่าทุกแถวเป็นเรื่องเดียวกัน: มนุษย์ยอมถอนสมมติฐานที่ตัวเองใส่เข้าไป แล้วปล่อยที่ว่างนั้นให้ข้อมูลกับการคำนวณเติมแทน ชื่อของการบรรยายที่เล่มนี้เรียบเรียงมาคือ "Delete Everything, Keep Graph" — ลบทุกอย่าง เหลือแค่กราฟ ซึ่งเป็นการสรุปทั้งเรื่องไว้ในสี่คำ
การก้าวกระโดดของ AI แต่ละครั้ง คือการลบข้อสมมติของมนุษย์ออกหนึ่งชั้น
แต่คำถามที่แสบกว่าและยังไม่ได้ตอบคือ ทำไมลบแล้วดีขึ้น ถ้าความรู้ที่มนุษย์ใส่เข้าไปมีประโยชน์ การถอนออกก็ควรทำให้แย่ลงสิ ไม่ใช่ดีขึ้น
คำตอบมีสามข้อและมันเกี่ยวพันกันอย่างที่คาดไม่ถึง — ข้อหนึ่งเกี่ยวกับสิ่งที่โมเดลแสดงออกได้ ข้อสองเกี่ยวกับความง่ายในการเทรน และข้อสามเกี่ยวกับรูปร่างของฮาร์ดแวร์ที่เราบังเอิญมีอยู่ในโลกนี้ เล่มนี้จะยังไม่ตอบตรงนี้ เพราะจะเข้าใจจริงได้ต้องเห็นกลไกก่อน ปริศนานี้ถูกไขในบทที่ 12 และบทที่ 9 กับ 11 จะเตรียมของให้ครบก่อนถึงตรงนั้น
💡 โทเค็น (token) — คำที่จะโผล่ทั้งเล่ม หมายถึงชิ้นข้อความที่โมเดลมองเป็นหนึ่งหน่วย ไม่ใช่ตัวอักษรและไม่ใช่คำเสมอไป ประโยคหนึ่งจะถูกหั่นเป็นโทเค็นหลายชิ้นก่อนเข้าโมเดล เวลาเห็นคำนี้ให้นึกถึง "ชิ้นข้อความหนึ่งชิ้น" ไว้ก่อน
Software 1.0 — มนุษย์เขียนวิธีทำ#
ยุคแรกคือยุคที่คนเขียนโปรแกรมยังเป็นคนคิดวิธีแก้ปัญหาทั้งหมดเอง เขียนออกมาเป็นคำสั่งทีละขั้นในภาษาอย่าง C++ หรือ Python แล้วเครื่องทำตามอย่างซื่อสัตย์ ตำราคลาสสิกของ Donald Knuth คือหัวใจของยุคนี้ — ความเก่งของโปรแกรมคือความเก่งของอัลกอริทึมที่มนุษย์คิดออก
วิธีนี้ไม่ได้ล้าสมัยและไม่ได้ตายไปไหน ระบบเรียงลำดับ ระบบบัญชี ระบบจองห้อง ยังเขียนแบบนี้และควรเขียนแบบนี้ต่อไป เพราะมันมีคุณสมบัติที่วิธีอื่นให้ไม่ได้: อ่านโค้ดแล้วรู้ว่ามันจะทำอะไร และเมื่อมันผิด เราชี้ได้ว่าผิดบรรทัดไหน
2.1 เพดานที่ชนแล้วไปต่อไม่ได้
ปัญหาเกิดขึ้นตอนเจองานที่มนุษย์ทำได้แต่อธิบายวิธีทำไม่ได้ ลองตอบคำถามนี้จริงจัง: เขียนขั้นตอนสำหรับดูรูปแล้วบอกว่ามีแมวอยู่ในรูปหรือไม่ ให้เป็นคำสั่งที่เครื่องทำตามได้
พอเริ่มเขียนจะพบว่าตอบไม่ได้เลย จะบอกว่า "หาหูสามเหลี่ยมสองอัน" ก็เจอแมวหันข้าง แมวหูพับ แมวในเงามืด แมวที่โดนโต๊ะบังครึ่งตัว ทุกกฎที่เพิ่มเข้าไปสร้างข้อยกเว้นใหม่สามข้อ กองกฎบวมขึ้นเรื่อย ๆ แต่ความแม่นไม่ขยับ
💡 ทำไมตัวอย่างแมวถึงเป็นตัวอย่างประจำ — เพราะมันแยกสองสิ่งที่คนมักปนกันออกจากกันได้คมที่สุด: ความสามารถในการทำ กับ ความสามารถในการอธิบายวิธีทำ เด็กสามขวบมีข้อแรกเต็มร้อย และมีข้อสองเป็นศูนย์ Software 1.0 ต้องการข้อสองเสมอ
งานประเภทนี้มีเยอะกว่าที่คิด — รู้จำเสียงพูด แปลภาษา ขับรถ ตอบคำถามปลายเปิด ทั้งหมดคือ "ทำได้แต่อธิบายวิธีไม่ได้" และทั้งหมดคือกำแพงที่ Software 1.0 ชนแล้วไปต่อไม่ได้ ไม่ใช่เพราะโปรแกรมเมอร์ไม่เก่งพอ แต่เพราะตัววิธีการมันต้องการสิ่งที่มนุษย์ไม่มีจะให้
Software 2.0 — ข้อมูลเขียนโปรแกรมแทนเรา#
ทางออกของกำแพงในบทที่แล้วคือการเปลี่ยนคำถาม จากเดิมถามว่า "จะเขียนวิธีจำแนกแมวยังไง" เปลี่ยนเป็น "จะหาชุดตัวเลขที่ทำให้ผลลัพธ์ตรงกับตัวอย่างที่เรามีได้ยังไง" สองคำถามนี้ต่างกันคนละโลก เพราะคำถามที่สองไม่ต้องการให้มนุษย์รู้วิธีเลย ขอแค่มนุษย์ชี้ถูกได้ว่าอะไรถูก
นี่คือ Software 2.0 คำที่ Karpathy เสนอไว้ตั้งแต่ปี 2017 มนุษย์เลิกเขียนตัวโปรแกรม แล้วย้ายไปทำสองอย่างแทน: สะสมชุดข้อมูลกับกำหนดโครงของโมเดล ส่วนตัว "โค้ด" จริง ๆ คือค่าน้ำหนักหลายล้านตัวที่ได้จากการเทรน ซึ่งไม่มีมนุษย์คนไหนเขียนหรืออ่านมันเลย
💡 น้ำหนัก (weights) — ตัวเลขในโมเดลที่ถูกปรับระหว่างเทรน มองเป็น "โค้ดที่ถูกเขียนโดยกระบวนการหาค่าที่เหมาะสม" ได้ตรงตัว มันคือโปรแกรมจริง ๆ ที่ทำงาน เพียงแต่อยู่ในรูปที่มนุษย์อ่านไม่ออก
3.1 กงล้อที่หมุนเองได้ — data engine
จุดที่ทำให้ Software 2.0 ทรงพลังไม่ใช่การเทรนครั้งเดียว แต่คือการทำให้มันเป็นวงจรที่หมุนกลับมาปรับปรุงตัวเองได้ ซึ่ง Karpathy เรียกว่า data engine และเป็นสิ่งที่เขาสร้างจริงตอนทำระบบขับขี่อัตโนมัติที่ Tesla
วงจรเดินอย่างนี้: รวบรวมข้อมูล → เทรนโมเดล → ปล่อยใช้งานจริง → ดักจับเคสที่โมเดลพลาด → ติดป้ายกำกับเคสเหล่านั้นเพิ่ม → ป้อนกลับเข้าชุดข้อมูล → เทรนใหม่ แล้ววนอีกรอบ
หัวใจอยู่ที่ขั้นที่สี่ ไม่ใช่ขั้นที่สอง คนมักคิดว่างานหลักคือการเทรน ความจริงคืองานหลักคือการหาว่าโมเดลพลาดตรงไหน เพราะข้อมูลที่มีค่าที่สุดไม่ใช่ข้อมูลที่เยอะที่สุด แต่คือข้อมูลในจุดที่โมเดลยังไม่รู้เรื่อง ถ่ายรูปถนนโล่งเพิ่มอีกล้านรูปแล้วโมเดลไม่เก่งขึ้น แต่รูปถนนตอนฝนตกกลางคืนที่มีเงาสะท้อนไฟหน้ารถอีกพันรูปเปลี่ยนผลลัพธ์ได้จริง
💡 อุปมาที่ใช้ได้และจุดที่มันพัง — data engine เหมือนครูที่ออกข้อสอบใหม่จากข้อที่นักเรียนทำผิด ดีตรงที่สื่อว่าความผิดพลาดคือวัตถุดิบ แต่พังตรงที่ ครูรู้ว่านักเรียนคิดผิดเพราะอะไร ส่วนเราไม่รู้ว่าโมเดลคิดผิดเพราะอะไรเลย เรารู้แค่ว่ามันตอบผิด แล้วเติมตัวอย่างเข้าไปให้มันปรับเอง
💡 ใครเป็นคนบอกว่าอะไรถูก — คำถามนี้ตอบยากกว่าที่คิด และมีคำตอบที่เป็นรูปธรรมมาก ตอนวงการเอา ImageNet มาวัดว่าเครื่องเก่งเท่ามนุษย์หรือยัง ตัวเลข "ความแม่นของมนุษย์" ที่ถูกอ้างกันต่อมา ไม่ได้มาจากการสำรวจคนหมู่มาก — มันมาจาก Karpathy นั่งจำแนกภาพแข่งกับโมเดลด้วยตัวเอง แล้วได้ค่าความผิดพลาด 5.1% ซึ่งเขาเขียนไว้เองว่าที่ผิดส่วนใหญ่คือจำพันธุ์สุนัขไม่ได้ ไม่ใช่มองภาพไม่ออก เกร็ดนี้บอกอะไรที่สำคัญกับทั้งบท: เพดานของ Software 2.0 ไม่ได้อยู่ที่โมเดล แต่อยู่ที่คุณภาพของคนที่ชี้ว่าอะไรถูก
3.2 สิ่งที่เราจ่ายไปเพื่อแลกมา
การลบอัลกอริทึมออกไม่ได้ฟรี ราคาที่จ่ายคือคุณสมบัติที่เคยเป็นจุดแข็งของยุคก่อน: อ่านน้ำหนักหลายล้านตัวแล้วไม่มีทางรู้ว่ามันจะตอบอะไร และเมื่อมันผิด ไม่มี "บรรทัดที่ผิด" ให้ชี้ วิธีแก้บั๊กเปลี่ยนจากการแก้โค้ดเป็นการเติมข้อมูล ซึ่งเป็นทักษะคนละชุดกันโดยสิ้นเชิง
เก็บข้อสังเกตนี้ไว้ เพราะในบทที่ 4 เราจะลบอะไรออกอีกชั้น แล้วจะเห็นว่าราคาที่จ่ายเป็นแบบเดียวกันเป๊ะ
LEVEL 1 · พื้นฐานที่ใช้ทุกวัน
Software 3.0 — ข้อความที่พิมพ์ คือซอร์สโค้ด#
Software 2.0 ยังเหลือสิ่งที่มนุษย์ต้องทำอยู่หนึ่งอย่างที่หนักมาก: ทุกครั้งที่ต้องการความสามารถใหม่ ต้องกลับไปเก็บข้อมูล ติดป้าย แล้วเทรนใหม่ทั้งรอบ ยุคที่สามคือยุคที่ขั้นตอนนั้นถูกลบออกด้วย
โมเดลภาษาขนาดใหญ่ถูกเทรนมาแล้วรอบเดียวจากข้อความมหาศาล จากนั้นการสั่งให้มันทำงานใหม่ไม่ต้องเทรนอีก — พิมพ์บอกมันเป็นภาษาคน ประโยคที่ Karpathy พูดจนกลายเป็นวลีติดปากของวงการคือ "ภาษาอังกฤษคือภาษาโปรแกรมที่ใหม่และร้อนแรงที่สุด"
4.1 มองโมเดลเป็นคอมพิวเตอร์ ไม่ใช่เครื่องเดาคำ
นี่คือแบบจำลองความคิดที่ต้องเปลี่ยนให้ได้ก่อนอย่างอื่น และคนส่วนใหญ่ติดอยู่ตรงนี้
ความเข้าใจผิดที่พบบ่อยคือมองโมเดลเป็น "เครื่องสุ่มคำที่เดาคำถัดไป" ซึ่งถูกในระดับกลไก — มันคำนวณความน่าจะเป็นของโทเค็นถัดไปจริง ๆ — แต่การหยุดอยู่ที่ความเข้าใจนั้นทำให้ใช้งานมันได้ห่วยมาก เพราะมันบอกไม่ได้ว่าทำไมบางคำสั่งได้ผลและบางคำสั่งไม่ได้ผล
มุมที่ใช้งานได้จริงกว่าคือมองมันเป็น คอมพิวเตอร์อเนกประสงค์ ตัวโมเดลคือฮาร์ดแวร์กับระบบปฏิบัติการที่ตายตัวแล้ว ส่วนข้อความที่เราพิมพ์เข้าไปคือซอร์สโค้ดที่ตั้งค่าการทำงานของมันใหม่ตอนรันจริง — เขียนคำสั่งใหม่ ก็ได้เครื่องที่ทำงานคนละอย่าง โดยที่น้ำหนักในตัวไม่ได้ขยับแม้แต่ตัวเดียว
💡 In-context learning — ความสามารถที่โมเดลปรับพฤติกรรมตามสิ่งที่อยู่ในข้อความตรงหน้า โดยไม่มีการเทรนใด ๆ เกิดขึ้น ยกตัวอย่างสามตัวอย่างให้ดูแล้วมันทำตามแบบทันที นี่คือสิ่งที่ทำให้ยุคที่สามเป็นไปได้ และบทที่ 12 จะเล่าว่าทำไมสถาปัตยกรรมแบบ Transformer จึงมีคุณสมบัตินี้ในตัว
4.2 ราคาที่จ่ายซ้ำรอยเดิม
ลองเทียบสามยุคด้วยเกณฑ์เดียวกัน แล้วจะเห็นแบบแผนที่ซ้ำ
| เขียนอะไร | ควบคุมได้แค่ไหน | แก้เมื่อผิดยังไง | |
|---|---|---|---|
| 1.0 | คำสั่งทีละขั้น | เต็มที่ | แก้บรรทัดที่ผิด |
| 2.0 | ชุดข้อมูล | ผ่านข้อมูล | เติมตัวอย่างที่ขาด |
| 3.0 | ข้อความสั่งงาน | ผ่านถ้อยคำ | เขียนคำสั่งใหม่ |
ทุกครั้งที่ขยับลงหนึ่งแถว เราได้ความสามารถกับความเร็วมากขึ้น และเสียความแน่นอนกับความสามารถในการตรวจสอบลงไปเท่า ๆ กัน นี่ไม่ใช่ข้อบกพร่องที่รอการแก้ในเวอร์ชันหน้า มันคือธรรมชาติของการยกงานตัดสินใจไปให้กระบวนการที่เราไม่ได้เขียนเอง
บังคับให้มันคิดออกมาดัง ๆ#
บทนี้เป็นบทที่ให้ผลตอบแทนต่อเวลาอ่านสูงที่สุดในเล่ม เพราะมันเปลี่ยนวิธีเขียนคำสั่งของคุณได้ตั้งแต่วันนี้ และเหตุผลเบื้องหลังมันสวยกว่าที่คนส่วนใหญ่รู้
5.1 ทำไมมันตอบเลขผิด ทั้งที่เขียนโปรแกรมเป็น
โมเดลทำงานโดยผลิตโทเค็นออกมาทีละชิ้น และการคำนวณที่มันทำได้ต่อหนึ่งโทเค็นนั้น มีปริมาณจำกัดและตายตัว ไม่ว่าคำถามจะง่ายหรือยาก
ผลที่ตามมาแรงกว่าที่เห็น: ถ้าเราถามโจทย์ที่ต้องคิดหลายขั้น แล้วบังคับให้มันตอบเป็นตัวเลขตัวเดียวทันที เราไม่ได้ขอให้มันคิดเร็ว — เรากำลังขอให้มันคิดทั้งโจทย์ให้เสร็จภายในการคำนวณของโทเค็นเดียว ซึ่งมันไม่มีที่ให้คิดพอ มันจึงเดา
วิธีแก้จึงเป็นการให้ที่ให้มันคิด: สั่งให้แสดงขั้นตอน โทเค็นแต่ละตัวที่มันพิมพ์ออกมากลายเป็นพื้นที่คำนวณเพิ่ม และผลลัพธ์กลางที่พิมพ์ไว้แล้วยังถูกอ่านซ้ำได้ในขั้นถัดไป
ขั้นตอนที่โมเดลพิมพ์ออกมา ไม่ใช่คำอธิบายให้เราอ่าน — มันคือกระดาษทดที่โมเดลใช้คิด
5.2 ตัวเลขจริง และบทเรียนที่ซ่อนอยู่ในตัวเลขนั้น
เรื่องนี้มีตัวเลขที่วัดได้ และมันเป็น สองขั้น ไม่ใช่ขั้นเดียวอย่างที่มักถูกเล่าต่อ
| คำสั่งที่ใช้ | ความแม่นบนชุดโจทย์ MultiArith |
|---|---|
| ถามตรง ๆ ไม่ให้แสดงวิธี | 17.7% |
เติม Let's think step by step | 78.7% |
| เติมประโยคที่เครื่องค้นเจอเอง | 82.0% |
ขั้นแรกคือของงานวิจัยปี 2022 ที่พบว่าการเติมประโยคสั้น ๆ ประโยคเดียวว่า Let's think step by step ดันความแม่นจาก 17.7% เป็น 78.7% โดยไม่ต้องเทรนอะไรใหม่เลย
ขั้นที่สองน่าคิดกว่า มีงานวิจัยที่ให้เครื่องไปค้นหาประโยคสั่งงานที่ดีที่สุดเอง แทนที่จะให้มนุษย์คิด แล้วประโยคที่มันหาเจอ (Let's work this out in a step by step way to be sure we have the right answer) ทำได้ 82.0% — ชนะประโยคที่มนุษย์คิดขึ้นมา
สังเกตให้ดีว่าขั้นที่สองคือเรื่องเดียวกับทั้งเล่มนี้อีกครั้ง เราลบ "มนุษย์เป็นคนคิดถ้อยคำ" ออก แล้วปล่อยให้กระบวนการค้นหาเติมแทน ผลก็ดีขึ้นตามแบบแผนเดิม
💡 กระดาษทดที่มีขอบเขตจริง — ถ้าคิดว่าโทเค็นที่โมเดลพิมพ์คือกระดาษทด ก็มีคนทำให้เป็นกระดาษทดจริง ๆ ด้วยการฝึกให้มันเปิด-ปิดโน้ตด้วยโทเค็นกำกับ (ทำนอง <scratchpad> … </scratchpad>) แล้วเขียนขั้นตอนกลางไว้ในนั้น ประโยชน์ไม่ได้อยู่ที่ความสวย แต่อยู่ที่ของในกระดาษทดถูกทิ้งได้เมื่อใช้เสร็จ — ที่ว่างในบริบทมีจำกัด การมีขอบเขตชัดว่าตรงไหนคือรอยคิดชั่วคราวจึงทำให้จัดการมันได้ แทนที่จะปล่อยให้รกไปเรื่อย ๆ
5.3 สองท่าที่ใช้ได้ทันที
หนึ่ง — ให้ที่ให้มันคิดก่อนตอบ อย่าถามแล้วบังคับให้ตอบสั้น ถ้าอยากได้คำตอบสั้น ให้มันคิดยาวก่อนแล้วค่อยสั่งให้สรุปท้ายสุด
สอง — กำหนดบทบาทให้ชัด เพราะโมเดลเรียนจากข้อความของคนทั้งอินเทอร์เน็ตซึ่งมีทั้งคำตอบที่ดีเยี่ยมและคำตอบที่มั่ว ถ้าไม่ระบุอะไรเลย มันจะเดินไปทางค่าเฉลี่ยของข้อความแบบนั้น การระบุว่าให้ตอบในฐานะผู้เชี่ยวชาญเฉพาะทางไม่ได้ทำให้มันฉลาดขึ้น แต่มันเลือกย่านของข้อความที่จะเลียนแบบ ให้แคบลงและตรงกับที่เราต้องการ
💡 เคล็ดลับที่ใช้ได้กับทุกคำสั่ง — ถ้ายังตอบไม่ได้ว่า "คำตอบที่ถูกต้องหน้าตาเป็นยังไง" แปลว่าคำสั่งยังไม่ชัดพอ ปัญหาอยู่ที่คำสั่ง ไม่ใช่ที่โมเดล
โมเดลในฐานะเครื่องจำลอง#
ถ้าแบบจำลองความคิดในบทที่ 4 ถูกต้องจริง — ว่าโมเดลเป็นคอมพิวเตอร์ที่ตั้งค่าใหม่ได้ด้วยข้อความ — ก็ควรมีข้อทำนายที่ตรวจสอบได้ตามมา นั่นคือ เราควรสั่งให้มันสวมรอยเป็นระบบอย่างอื่นได้ ไม่ใช่แค่ตอบคำถาม
ข้อทำนายนี้เป็นจริง และเป็นจุดที่แบบจำลอง "เครื่องเดาคำ" อธิบายอะไรไม่ได้เลย
6.1 สั่งให้เป็นเทอร์มินัล
เคสที่ดังที่สุดคือการสั่งให้โมเดลทำตัวเป็นเทอร์มินัลของ Linux แล้วพิมพ์คำสั่งใส่มันเหมือนเครื่องจริง สิ่งที่มันตอบกลับมาไม่ใช่คำอธิบายว่าคำสั่งนั้นทำอะไร แต่เป็นผลลัพธ์แบบที่เทอร์มินัลจะพิมพ์ออกมา และมันรักษาสถานะข้ามคำสั่งได้ด้วย — สร้างไฟล์ไว้ในคำสั่งก่อน แล้วสั่งดูรายการไฟล์ทีหลัง ไฟล์นั้นยังอยู่
เกิดอะไรขึ้น มันไม่ได้มีเครื่อง Linux อยู่ข้างใน มันกำลังจำลองพฤติกรรมของระบบจากความเข้าใจว่าระบบนั้นทำงานยังไง โดยเก็บสถานะไว้ในข้อความที่ผ่านมาทั้งหมด
6.2 จากของเล่นเป็นสถาปัตยกรรมจริง
พอเห็นกลไกนี้แล้วประตูจะเปิดกว้างกว่าที่คิด เพราะสิ่งที่จำลองได้ไม่จำกัดแค่เทอร์มินัล — Karpathy ยกตัวอย่างการสั่งให้มันเป็นสมองของบ้านอัจฉริยะที่รับสถานะเข้าแล้วตัดสินใจว่าจะสั่งอุปกรณ์อะไร และตัวอย่างที่ไปไกลกว่านั้น: ใช้มันเป็นส่วนหลังบ้านของแอปพลิเคชันโดยไม่เขียนโค้ดฝั่งเซิร์ฟเวอร์เลย รับข้อมูลเข้าเป็น JSON ปรับสถานะ แล้วส่ง JSON กลับ โดยตรรกะทั้งหมดถูกอธิบายไว้เป็นภาษาคน
นี่คือจุดที่ Software 3.0 เลิกเป็นลูกเล่นและกลายเป็นทางเลือกทางสถาปัตยกรรมจริง
💡 ข้อควรระวังที่ต้องพูดให้ครบ — ความสามารถนี้มีเสน่ห์มากจนหลายคนเอาไปใช้ผิดที่ ของที่จำลองด้วยโมเดลจะไม่แน่นอนโดยธรรมชาติ ตรรกะที่ต้องถูกทุกครั้งอย่างการคิดเงินหรือการตรวจสิทธิ์ ควรอยู่ในโค้ดแบบ 1.0 ที่ทดสอบได้ ส่วนที่เหมาะกับการจำลองคือส่วนที่กฎเยอะ เปลี่ยนบ่อย และยอมรับความคลาดเคลื่อนได้ — เกณฑ์ตัดสินคือ "ผิดหนึ่งครั้งในร้อยครั้งแล้วเกิดอะไรขึ้น" ถ้าคำตอบคือเสียเงินหรือข้อมูลรั่ว อย่าเอาไปจำลอง
6.3 ปริศนาที่ค้างไว้สำหรับครึ่งหลังของเล่ม
หกบทที่ผ่านมาเล่าว่ามนุษย์ลบอะไรออกไปบ้าง และผลที่ได้คืออะไร แต่เรายังไม่ได้เปิดดูข้างในเลยว่า เครื่องที่ทำสิ่งเหล่านี้ได้ มันประกอบขึ้นจากอะไร
ครึ่งหลังของเล่มจะเปิดฝาออกดู และลำดับจะเป็นแบบนี้: บทที่ 7 เล่าคอขวดที่ทำให้โลกต้องคิดกลไกใหม่ขึ้นมา · บทที่ 8 เล่าจังหวะที่ทุกอย่างถูกตัดออกเหลือกลไกเดียว · บทที่ 9 ผ่ากลไกนั้นด้วยโค้ดที่รันได้จริง · บทที่ 10 เล่าว่าการเปลี่ยนเงื่อนไขข้อเดียวทำให้ได้โมเดลสามตระกูลที่ต่างกันสิ้นเชิง · บทที่ 11 อ่านโค้ดจริงทั้งชั้น · บทที่ 12 ไขปริศนาจากบทที่ 1 ว่าทำไมลบแล้วดีขึ้น
LEVEL 2 · ระดับกลาง
คอขวดที่ทำให้โลกต้องคิดกลไกใหม่#
เปิดฝาดูข้างในแล้ว และเราจะไม่เริ่มจากคำตอบ เพราะการเห็นคำตอบก่อนเห็นปัญหาทำให้จำได้แต่ไม่เข้าใจ เราจะเริ่มจากปัญหาที่คนยุคนั้นเจอจริง ๆ แล้วคุณจะพบว่ากลไกที่ดูซับซ้อนในบทถัดไป เป็นสิ่งที่คุณคิดออกเองได้
7.1 ยุคที่ทุกสาขาแยกกันคนละโลก
ก่อนราวปี 2012 งานด้านภาพ เสียง และภาษา แยกออกจากกันโดยสิ้นเชิง แต่ละสาขามีเครื่องมือเฉพาะทางของตัวเองที่มนุษย์ออกแบบมาด้วยมือ — คนทำงานด้านภาพมีตัวอธิบายลักษณะของภาพที่คิดขึ้นมาเป็นสิบปี คนทำเสียงมีของอีกชุดที่ใช้ข้ามสาขาไม่ได้เลย ย้ายคนจากสาขาหนึ่งไปอีกสาขาแล้วความรู้แทบทั้งหมดใช้ไม่ได้
จำแถวที่สองในตารางบทที่ 1 ไหม — จังหวะที่ตัวอธิบายลักษณะทำมือถูกลบออก แล้วให้เครือข่ายหาลักษณะเอง นั่นคือจุดที่กำแพงระหว่างสาขาเริ่มบางลง แต่ยังไม่หายไป เพราะแต่ละสาขายังใช้โครงของโมเดลคนละแบบ
7.2 ปี 2014 — บีบทั้งประโยคลงถังใบเดียว
งานแปลภาษาในยุคนั้นใช้โครงที่ชื่อว่า encoder-decoder โดยมีหน่วยความจำแบบ LSTM เป็นแกน วิธีทำงานคือ อ่านประโยคต้นทางทีละคำ สะสมความเข้าใจไว้ แล้วเมื่ออ่านจบก็ได้ เวกเตอร์ตัวเดียวขนาดคงที่ ที่ควรบรรจุความหมายของทั้งประโยคไว้ จากนั้นฝ่ายถอดรหัสก็เอาเวกเตอร์นั้นไปคลี่ออกเป็นประโยคปลายทาง
ห้ามย้อนกลับไปดูต้นทางเลย — เห็นได้แค่สิ่งที่รอดผ่านคอขวดมาปัญหาปรากฏชัดทันทีเมื่อประโยคยาวขึ้น เพราะเวกเตอร์มีขนาดเท่าเดิมตลอด ไม่ว่าประโยคจะยาวห้าคำหรือห้าสิบคำ ข้อมูลจึงต้องหล่นหายไปไหนสักที่ นี่คือสิ่งที่เรียกว่า คอขวดของฝ่ายเข้ารหัส (encoder bottleneck)
💡 อุปมาที่ตรงกับกลไกจริง — เหมือนสั่งให้คนอ่านรายงานยาวยี่สิบหน้า แล้วห้ามจดอะไรเลยนอกจากกระดาษโพสต์อิตแผ่นเดียว จากนั้นให้เขียนสรุปเป็นภาษาอื่นจากโพสต์อิตแผ่นนั้นอย่างเดียว ห้ามเปิดกลับไปดูรายงานเลย — รายงานสั้นยังรอด รายงานยาวคือหายนะ และจุดสำคัญคือคำว่า "ห้ามเปิดกลับไปดู" นั่นคือข้อจำกัดตัวจริง ไม่ใช่ขนาดของโพสต์อิต
ถ้าอุปมานั้นชัด คุณก็คิดวิธีแก้ออกแล้ว: ก็ให้เปิดกลับไปดูได้สิ
7.3 ปี 2014–2015 — ให้ย้อนกลับไปมองได้
นั่นคือสิ่งที่ Dzmitry Bahdanau ทำร่วมกับ Kyunghyun Cho และ Yoshua Bengio ในงานที่ตีพิมพ์ปี 2014 แทนที่จะบังคับให้ฝ่ายถอดรหัสใช้เวกเตอร์สรุปตัวเดียว พวกเขาให้มันสามารถย้อนกลับไปมองสถานะของทุกตำแหน่งในประโยคต้นทางได้โดยตรง และเลือกน้ำหนักเองว่าตอนกำลังผลิตคำนี้ ควรให้ความสำคัญกับตำแหน่งไหนมากที่สุด
พวกเขาเรียกกลไกนี้ว่าการ ค้นแบบนุ่มนวล (soft search) และเรียกโมเดลว่า RNNsearch เพราะฝ่ายถอดรหัส "ค้น" ในประโยคต้นทางทุกครั้งที่ผลิตคำใหม่
ที่น่าสังเกตคือ คำว่า attention แทบไม่ปรากฏในงานต้นฉบับ — คำที่ใช้เป็นหลักทั้งฉบับคือ alignment หรือการจับคู่ตำแหน่ง ส่วนชื่อ attention ที่ทั้งโลกใช้กันวันนี้มาติดทีหลัง Karpathy เล่าไว้ในการบรรยายว่าเป็น Yoshua Bengio ที่เสนอคำนี้ขึ้นมา — จุดนี้เป็นคำบอกเล่าจากการบรรยาย เล่มนี้จึงบอกไว้ตามนั้น ไม่ยกเป็นข้อเท็จจริงที่ยืนยันแล้ว ส่วนที่ตรวจกับงานต้นฉบับได้แน่นอนคือ ชื่อที่งานนั้นใช้เองคือ alignment กับ RNNsearch
ประเด็นที่ต้องจับให้ได้จากบทนี้: ปี 2014 กลไกการมองหากันนี้เป็นเพียงของเสริม ที่ถูกแปะเข้ากับ LSTM เพื่ออุดคอขวด แกนหลักยังเป็นการไล่ลำดับทีละคำอยู่ อีกสามปีถัดมาจะมีคนถามคำถามที่ทำให้ทุกอย่างพลิก
ตัดทุกอย่างออก เหลือแค่การมองหากัน#
ปี 2017 มีงานวิจัยชื่อ Attention Is All You Need ออกมา และชื่อของมันคือใจความทั้งหมด — ไม่ใช่การถ่อมตัว ไม่ใช่การเล่นคำ มันเป็นคำประกาศถึงสิ่งที่ทีมนั้นทำจริง ๆ
คำถามที่พวกเขาถามคือคำถามที่ฟังดูบ้าในตอนนั้น: ถ้ากลไกการมองหากันที่แปะเสริมไว้มันดีนัก จะเกิดอะไรขึ้นถ้าเราเอาส่วนที่เป็นแกนหลักออกให้หมด แล้วเหลือแต่ของเสริม
ผลคือได้สถาปัตยกรรมที่ไม่มีหน่วยความจำแบบไล่ลำดับเลยแม้แต่ชิ้นเดียว มีแต่การมองหากันเป็นชั้น ๆ ซ้อนกัน และมันชนะทุกอย่างในยุคนั้น
ของเสริมกลายเป็นทั้งหมด และแกนเดิมถูกลบทิ้ง — นี่คือแถวที่สามในตารางบทที่ 1
8.1 ราคาที่ต้องจ่ายทันทีเมื่อลบลำดับออก
การลบการไล่ลำดับทิ้งไม่ได้มาฟรี และตรงนี้คือจุดที่คนอ่านผ่านกันเยอะที่สุด
LSTM รู้ลำดับของคำ โดยอัตโนมัติ เพราะมันอ่านทีละคำตามเวลาจริง คำที่มาก่อนก็ถูกประมวลผลก่อนโดยธรรมชาติของกลไก แต่เมื่อทุกตำแหน่งถูกมองพร้อมกันหมด ข้อมูลเรื่องลำดับหายไปทั้งก้อน โมเดลจะแยกไม่ออกเลยว่า "กรกินหมา" กับ "หมากินกร" ต่างกัน เพราะมันเห็นแค่กองคำที่ไม่มีลำดับ
ทางแก้คือใส่ข้อมูลตำแหน่งกลับเข้าไปเองในรูปตัวเลขที่ผสมเข้ากับข้อมูลของแต่ละโทเค็น เรียกว่า positional encoding สังเกตให้ดีว่านี่คือแบบแผนที่จะเจอซ้ำ: ลบสิ่งที่มนุษย์ใส่ไว้ออก แล้วถ้าจำเป็นก็เอากลับเข้ามาในรูปที่โมเดลเรียนรู้ต่อได้เอง ไม่ใช่ในรูปกฎที่ตายตัว
8.2 ชิ้นส่วนที่ต้องมาเป็นชุด ไม่ใช่แค่ attention
ความเข้าใจผิดที่พบบ่อยคือคิดว่างานปี 2017 มีแค่ attention ความจริงคือมันเป็นการประกอบเทคนิคที่พิสูจน์ตัวเองมาแล้วเข้าด้วยกันอย่างพอดี และถ้าขาดชิ้นใดชิ้นหนึ่งไป มันเทรนไม่ขึ้น
| ชิ้นส่วน | มีไว้ทำอะไร | ถ้าไม่มีจะเป็นยังไง |
|---|---|---|
| Residual connection | ให้สัญญาณวิ่งผ่านชั้นลึก ๆ ได้ | เทรนโมเดลลึกไม่ขึ้น |
| Layer normalization | คุมสเกลของตัวเลขในแต่ละชั้น | ค่าระเบิดหรือดับกลางทาง |
| Multi-head attention | มองหากันหลายแบบพร้อมกันในชั้นเดียว | จับความสัมพันธ์ได้แบบเดียวต่อชั้น |
| Positional encoding | บอกว่าโทเค็นไหนอยู่ตำแหน่งไหน | แยกลำดับคำไม่ออก |
| MLP ขยาย 4 เท่า | ที่ให้แต่ละโทเค็นคิดของตัวเอง | มีแต่การรับส่ง ไม่มีการคิด |
สองชิ้นแรกคือคำตอบข้อที่สองของปริศนาในบทที่ 1 (เรื่องความง่ายในการเทรน) และบทที่ 11 จะให้คุณพิสูจน์มันด้วยการรันโค้ดเอง ไม่ใช่เชื่อตามตาราง
💡 Multi-head แปลว่าอะไรจริง ๆ — แทนที่จะให้แต่ละชั้นมองหากันได้แบบเดียว เราแบ่งช่องข้อมูลออกเป็นหลายกลุ่ม แต่ละกลุ่มมองหากันเป็นเอกเทศ แล้วเอาผลมารวมกัน เหมือนอ่านเอกสารเดียวกันด้วยคนหลายคนที่ได้รับคำสั่งให้จับใจความคนละแบบ แล้วเอาบันทึกของทุกคนมารวม — คนหนึ่งดูว่าประธานอยู่ไหน อีกคนดูว่าคำไหนขยายคำไหน
LEVEL 3 · ระดับสูง
กราฟที่โน้ดคุยกัน#
บทนี้คือแก่นทางเทคนิคของทั้งเล่ม และเราจะเข้าถึงมันด้วยแบบจำลองความคิดหนึ่งอันที่ทำให้ทุกอย่างที่เหลือกลายเป็นเรื่องเดาได้
เลิกมอง Transformer เป็นลำดับของคำ ให้มองเป็นกราฟ โทเค็นทุกตัวคือโน้ดหนึ่งโน้ด และการทำงานของทั้งสถาปัตยกรรมคือการสลับสองเฟสไปเรื่อย ๆ
| เฟส | ชื่อทางเทคนิค | เกิดอะไรขึ้น |
|---|---|---|
| สื่อสาร | multi-head attention | โน้ดทุกตัวส่งข้อมูลถึงกันตามน้ำหนักที่คิดเอง |
| คิด | MLP / feed-forward | โน้ดแต่ละตัวแปรรูปข้อมูลของตัวเองอย่างเป็นเอกเทศ ไม่คุยกับใคร |
ชั้นหนึ่งชั้นคือสื่อสารหนึ่งครั้งแล้วคิดหนึ่งครั้ง ซ้อนกันหลายสิบชั้นก็คือสลับสื่อสาร-คิดหลายสิบรอบ เท่านั้นจริง ๆ
9.1 สามคำถามที่โน้ดทุกตัวต้องตอบ
ในเฟสสื่อสาร โน้ดแต่ละตัวสร้างเวกเตอร์สามตัวจากข้อมูลของตัวเอง และแต่ละตัวคือคำตอบของคำถามหนึ่งข้อ
- Query — "ฉันกำลังมองหาข้อมูลแบบไหน"
- Key — "ฉันมีข้อมูลลักษณะไหนอยู่กับตัว"
- Value — "ถ้ามีใครสนใจฉัน เนื้อหาที่ฉันจะส่งให้คืออะไร"
1 — หลังจากนั้น ผลลัพธ์เป็นเพียงผลรวมถ่วงน้ำหนักของ V ทุกตัว ไม่ใช่การเลือกมาตัวเดียวจากนั้นกลไกทำสี่ขั้นตรงไปตรงมา: เอา Query ของโน้ดที่ถาม ไปจับคู่กับ Key ของทุกโน้ด ด้วยการคูณแบบจุด (q @ k.T) ได้คะแนนความเข้ากัน → หารด้วยรากของขนาดช่องเพื่อคุมสเกล → ผ่าน softmax ให้กลายเป็นน้ำหนักที่รวมกันได้ 1 → เอาน้ำหนักไปถ่วง Value ของทุกโน้ดแล้วบวกกัน
💡 อุปมาฐานข้อมูล และรอยที่มันรั่ว — Q คือคำค้น K คือดรรชนี V คือเนื้อหา ดีตรงที่สื่อว่าเป็นการค้นหา แต่รั่วตรงที่ ฐานข้อมูลจริงเลือกมาหนึ่งแถวที่ตรง ส่วน attention เอาทุกแถวมาผสมกันตามน้ำหนัก ไม่เคยเลือกแค่อันเดียว คำว่า "นุ่มนวล" ใน soft search ของบทที่ 7 หมายถึงตรงนี้พอดี
9.2 ลองพิสูจน์ด้วยตาเอง
อย่าเชื่อคำอธิบายข้างบน รันเองแล้วดู โค้ดนี้ใช้ numpy ล้วน ไม่มีไลบรารีเรียนรู้ของเครื่องเลย และครบทั้งกลไก
import numpy as np
np.set_printoptions(precision=2, suppress=True)
T, C, head = 4, 6, 3 # 4 โทเค็น · 6 ช่องข้อมูล · หัวขนาด 3
x = np.arange(T * C, dtype=np.float64).reshape(T, C) / 10.0
rng = np.random.default_rng(1337)
Wq = rng.normal(size=(C, head)) * 0.5
Wk = rng.normal(size=(C, head)) * 0.5
Wv = rng.normal(size=(C, head)) * 0.5
q, k, v = x @ Wq, x @ Wk, x @ Wv # สามคำถามของทุกโน้ด
scores = q @ k.T / np.sqrt(head) # แถว i = โน้ด i ถามหาใคร
print("scores (raw) =\n", scores)
mask = np.tril(np.ones((T, T), dtype=bool))
masked = np.where(mask, scores, -np.inf) # ปิดอนาคตด้วยลบอนันต์
print("\nscores (after causal mask) =\n", masked)
e = np.exp(masked - masked.max(axis=-1, keepdims=True))
w = e / e.sum(axis=-1, keepdims=True) # softmax ทีละแถว
print("\nweights (after softmax) =\n", w)
print("row sums =", w.sum(axis=-1))
out = w @ v # ถ่วงน้ำหนักแล้วบวก
print("\nout[0] == v[0] ?", np.allclose(out[0], v[0]))ผลลัพธ์จริงที่ได้:
scores (raw) =
[[-0.14 -0.27 -0.39 -0.52]
[-0.1 -0.08 -0.06 -0.04]
[-0.06 0.11 0.28 0.44]
[-0.02 0.3 0.61 0.93]]
scores (after causal mask) =
[[-0.14 -inf -inf -inf]
[-0.1 -0.08 -inf -inf]
[-0.06 0.11 0.28 -inf]
[-0.02 0.3 0.61 0.93]]
weights (after softmax) =
[[1. 0. 0. 0. ]
[0.49 0.51 0. 0. ]
[0.28 0.33 0.39 0. ]
[0.15 0.2 0.28 0.38]]
row sums = [1. 1. 1. 1.]
out[0] == v[0] ? Trueมีสามอย่างในผลลัพธ์นี้ที่คุ้มกับการหยุดดูให้ดี
หนึ่ง — ตารางกลายเป็นสามเหลี่ยม ครึ่งบนขวาเป็น -inf ทั้งหมด เพราะเราปิดไม่ให้โน้ดมองอนาคต (บทที่ 10 จะเล่าว่าทำไม)
สอง — -inf หายไปกลายเป็น 0 พอดี นี่ไม่ใช่ความบังเอิญ softmax ต้องยกกำลัง e ของทุกค่า และ e ยกกำลังลบอนันต์เท่ากับศูนย์เป๊ะ นี่คือเหตุผลว่าทำไมต้องเป็นลบอนันต์ ไม่ใช่เลขติดลบมาก ๆ ถ้าใช้ค่าอย่างลบหนึ่งพัน มันจะเหลือน้ำหนักจิ๋วหนึ่งค้างอยู่ ซึ่งแปลว่ายังมีข้อมูลจากอนาคตรั่วเข้ามา
สาม — แถวแรกได้น้ำหนัก [1, 0, 0, 0] และ out[0] เท่ากับ v[0] เป๊ะ โน้ดตัวแรกไม่มีใครให้มองนอกจากตัวเอง น้ำหนักจึงเทไปที่ตัวเองทั้งหมด และผลลัพธ์ที่ได้คือ Value ของตัวเองแบบไม่ผสมอะไร — นี่คือหลักฐานว่ากลไกทั้งหมดเป็นเพียงการถ่วงน้ำหนักแล้วบวกกัน ไม่มีเวทมนตร์อะไรเกินกว่านั้น
9.3 แล้วเฟสคิดล่ะ
เฟสสื่อสารทำให้โน้ดได้ข้อมูลจากเพื่อน แต่ยังไม่มีใครคิดอะไรกับข้อมูลนั้น เฟสที่สองคือส่วนที่ทำงานนั้น: ข้อมูลของแต่ละโน้ดถูกส่งผ่านชั้นคำนวณเล็ก ๆ ที่ขยายออกสี่เท่าแล้วบีบกลับ โดยโน้ดแต่ละตัวทำของตัวเองอย่างเป็นเอกเทศ ไม่มีการคุยกันเลยในเฟสนี้
การแยกสองหน้าที่นี้ออกจากกันเด็ดขาดคือความงามทางการออกแบบของ Transformer — รับส่งข้อมูลเป็นเรื่องของเฟสหนึ่ง แปรรูปข้อมูลเป็นเรื่องของเฟสสอง ไม่ปนกัน
หน้ากากสามแบบ = โมเดลสามตระกูล#
บทนี้จะให้ผลตอบแทนที่ดีเกินคาด เพราะมันเฉลยว่าโมเดลที่คุณเคยได้ยินชื่อมาทั้งหมด — BERT, GPT, T5, Whisper — ไม่ได้ต่างกันที่สถาปัตยกรรม พวกมันใช้ของชิ้นเดียวกันกับที่คุณเพิ่งรันในบทที่แล้ว ต่างกันแค่เรื่องเดียว: ใครถูกอนุญาตให้มองเห็นใคร
-inf ก่อนเข้า softmax จึงเหลือน้ำหนักศูนย์พอดี| ตระกูล | ตัวอย่าง | เงื่อนไขการมองเห็น | เหมาะกับงาน |
|---|---|---|---|
| Encoder-only | BERT | ทุกโน้ดมองเห็นกันหมด ไม่มีหน้ากาก | จำแนกประเภท วิเคราะห์อารมณ์ ทำเวกเตอร์แทนความหมาย |
| Decoder-only | GPT | มองเห็นเฉพาะตัวเองกับอดีต | ผลิตข้อความต่อเนื่อง โมเดลภาษาขนาดใหญ่ |
| Encoder-decoder | T5, Whisper | ฝ่ายเข้ารหัสมองกันหมด ฝ่ายถอดรหัสเห็นแต่อดีต และมองข้ามไปหาฝ่ายเข้ารหัสได้ | แปลภาษา ถอดเสียงเป็นข้อความ สรุปความ |
10.1 ทำไม GPT ต้องปิดอนาคต
เหตุผลไม่ใช่เรื่องเทคนิค แต่เป็นเรื่องความซื่อสัตย์ของการฝึก
งานที่ GPT ฝึกคือทำนายโทเค็นถัดไปจากโทเค็นที่ผ่านมา ถ้าตอนเทรนเราปล่อยให้โน้ดตำแหน่งที่ห้ามองเห็นโน้ดตำแหน่งที่หกได้ มันก็แค่ลอกคำตอบ ค่าความผิดพลาดจะสวยงามมากระหว่างเทรน แล้วพอเอาไปใช้จริงที่ไม่มีอนาคตให้ลอก มันจะทำอะไรไม่ได้เลย
หน้ากากแบบสามเหลี่ยมจึงไม่ใช่ข้อจำกัดที่น่ารำคาญ มันคือสิ่งที่ทำให้การฝึกมีความหมาย และการที่มันเป็นแค่การเติม -inf ลงครึ่งหนึ่งของตารางก่อน softmax คือความประหยัดที่น่าทึ่ง — เปลี่ยนพฤติกรรมของโมเดลทั้งตระกูลด้วยการแก้ตัวเลขในตารางเดียว
10.2 Cross-attention — สะพานที่ปิดวงเรื่องทั้งหมด
ตระกูลที่สามมีของเพิ่มมาหนึ่งอย่างที่ควรสังเกต ฝ่ายถอดรหัสไม่ได้มองแต่ในกลุ่มตัวเอง มันสร้าง Query ของตัวเองแล้วไปจับกับ Key และ Value ของฝ่ายเข้ารหัส เรียกว่า cross-attention
ตรงนี้คือจุดที่เรื่องทั้งเล่มปิดวง เพราะสิ่งนี้คือกลไกเดียวกับที่ Bahdanau คิดขึ้นในปี 2014 เพื่ออุดคอขวดในบทที่ 7 — ให้ฝ่ายถอดรหัสย้อนกลับไปมองต้นทางได้ ต่างกันแค่ตอนนี้มันไม่ได้แปะอยู่บน LSTM อีกแล้ว มันคือกลไกเดียวกับที่ใช้ทำทุกอย่างในสถาปัตยกรรม
LEVEL 4 · ระดับเทพ
อ่านโค้ดจริงทั้งชั้น#
ถึงจุดที่เราประกอบทุกอย่างเข้าด้วยกัน โค้ดข้างล่างนี้คือ Transformer block หนึ่งชั้นเต็มแบบ decoder-only โครงเดียวกับที่ใช้ในโมเดลจริง และรันได้บนเครื่องที่ไม่มีการ์ดจอ
11.1 เฟสสื่อสาร — บรรทัดที่ต้องจับตา
import torch
import torch.nn as nn
import torch.nn.functional as F
torch.manual_seed(1337) # ตัวเลขทุกตัวในบทนี้มาจาก seed นี้
class CausalSelfAttention(nn.Module):
def __init__(self, n_embd, n_head, block_size):
super().__init__()
self.n_head, self.n_embd = n_head, n_embd
self.attn = nn.Linear(n_embd, 3 * n_embd, bias=False) # Q, K, V ในก้อนเดียว
self.proj = nn.Linear(n_embd, n_embd, bias=False)
self.register_buffer("mask", torch.tril(torch.ones(block_size, block_size)))
def forward(self, x):
B, T, C = x.shape
q, k, v = self.attn(x).split(C, dim=2) # แยกสามทางที่นี่
hs = C // self.n_head
q = q.view(B, T, self.n_head, hs).transpose(1, 2) # แตกเป็นหลายหัว
k = k.view(B, T, self.n_head, hs).transpose(1, 2)
v = v.view(B, T, self.n_head, hs).transpose(1, 2)
att = (q @ k.transpose(-2, -1)) * hs ** -0.5 # คะแนนความเข้ากัน
att = att.masked_fill(self.mask[:T, :T] == 0, float("-inf"))
att = F.softmax(att, dim=-1)
y = att @ v # ถ่วงน้ำหนักแล้วบวก
y = y.transpose(1, 2).contiguous().view(B, T, C)
return self.proj(y), attเทียบกับโค้ด numpy ในบทที่ 9 แล้วจะเห็นว่าแกนกลางเหมือนกันทุกบรรทัด สี่บรรทัดที่ขึ้นต้นด้วย att คือกลไกเดียวกับที่คุณรันไปแล้วเป๊ะ ๆ ส่วนที่เพิ่มมามีสามอย่างเท่านั้น: ทำหลายประโยคพร้อมกัน (B) แตกเป็นหลายหัว และรวมการสร้าง Q, K, V ไว้ในชั้นเดียวเพื่อความเร็ว
จุดที่ควรสังเกตเป็นพิเศษคือ masked_fill — นั่นคือหน้ากากจากบทที่ 10 ที่ปรากฏเป็นโค้ดหนึ่งบรรทัด และคือทั้งหมดที่แยก GPT ออกจาก BERT
11.2 ประกอบเป็นชั้นเต็ม — สังเกตเครื่องหมายบวก
class Block(nn.Module):
def __init__(self, n_embd, n_head, block_size):
super().__init__()
self.ln1 = nn.LayerNorm(n_embd)
self.sa = CausalSelfAttention(n_embd, n_head, block_size)
self.ln2 = nn.LayerNorm(n_embd)
self.mlp = nn.Sequential(
nn.Linear(n_embd, 4 * n_embd), # ขยาย 4 เท่า
nn.GELU(),
nn.Linear(4 * n_embd, n_embd), # บีบกลับ
)
def forward(self, x):
delta, att = self.sa(self.ln1(x))
x = x + delta # residual เส้นที่ 1 — สื่อสาร
x = x + self.mlp(self.ln2(x)) # residual เส้นที่ 2 — คิด
return x, attทั้งชั้นมีแค่นี้จริง ๆ สองเฟสจากบทที่ 9 อยู่ในสองบรรทัดสุดท้าย และแต่ละบรรทัดเป็น x = x + ... ไม่ใช่ x = ...
เครื่องหมายบวกนั้นคือหัวใจ และมันสำคัญกว่าที่หน้าตาบอก — ชั้นนี้ไม่ได้แทนที่ข้อมูลเดิม มันคำนวณส่วนแก้แล้วบวกทับลงไปบนของเดิม
11.3 พิสูจน์ว่า residual คือทางหลัก
นี่คือการทดลองที่ทำให้เชื่อได้ด้วยตาตัวเอง: ถ้าเราเซ็ตชั้นสุดท้ายของทั้งสองเฟสให้เป็นศูนย์ทั้งหมด ส่วนแก้ก็จะเป็นศูนย์ แล้ว x = x + 0 ต้องได้ x กลับมาเป๊ะ — ชั้นทั้งชั้นควรกลายเป็นทางผ่านที่ไม่ทำอะไรเลย
B, T, n_embd, n_head = 1, 5, 8, 2
block = Block(n_embd, n_head, block_size=T)
x = torch.randn(B, T, n_embd)
y, att = block(x)
print("params in one block =", sum(p.numel() for p in block.parameters()))
print("x.shape =", tuple(x.shape), " -> y.shape =", tuple(y.shape))
print("\nattention of head 0 (rows = who is asking):")
print(att[0, 0].detach().numpy().round(2))
with torch.no_grad(): # ปิดส่วนแก้ทั้งสองเส้น
for p in block.sa.proj.parameters():
p.zero_()
for p in block.mlp[-1].parameters():
p.zero_()
y_zero, _ = block(x)
print("\nblock becomes identity?", torch.allclose(y_zero, x, atol=1e-6))ผลลัพธ์จริง:
params in one block = 840
x.shape = (1, 5, 8) -> y.shape = (1, 5, 8)
attention of head 0 (rows = who is asking):
[[1. 0. 0. 0. 0. ]
[0.41 0.59 0. 0. 0. ]
[0.31 0.35 0.34 0. 0. ]
[0.22 0.28 0.22 0.28 0. ]
[0.34 0.19 0.21 0.15 0.11]]
block becomes identity? Trueคำว่า True บรรทัดสุดท้ายคือคำตอบข้อที่สองของปริศนาในบทที่ 1 ที่จับต้องได้ ค่าเริ่มต้นของชั้นคือ "ไม่ทำอะไร" ไม่ใช่ "ทำอะไรมั่ว ๆ" ดังนั้นการซ้อนชั้นเพิ่มเข้าไปจึงไม่เคยทำให้ของเดิมพัง อย่างแย่ที่สุดชั้นใหม่ก็เรียนรู้ที่จะเงียบ นี่คือเหตุผลที่โมเดลลึกเป็นร้อยชั้นเทรนขึ้นได้ และเป็นเหตุผลที่รูปทรงของกราฟการคำนวณมีทางตรงจากชั้นแรกถึงชั้นสุดท้ายให้สัญญาณวิ่งผ่านได้ตลอด
สังเกตตารางน้ำหนักด้วย: สามเหลี่ยมเหมือนบทที่ 9 และแถวแรกเป็น [1, 0, 0, 0, 0] — กลไกเดียวกัน ต่างแค่ตัวเลข
ทำไมสถาปัตยกรรมนี้กินรวบทุกสาขา#
ถึงเวลาไขปริศนาที่ปลูกไว้ในบทที่ 1: ถ้าการลบความรู้ของมนุษย์ออกควรทำให้แย่ลง ทำไมผลกลับดีขึ้น
คำตอบคือ Transformer เก่งสามด้านนี้พร้อมกัน และคำว่าพร้อมกันคือทั้งหมดของเรื่อง เพราะสถาปัตยกรรมก่อนหน้านี้เก่งได้สองในสามข้อ ไม่เคยครบสาม
12.1 ข้อหนึ่ง — แสดงออกได้กว้าง (expressive)
กราฟที่โน้ดทุกตัวส่งข้อมูลถึงกันได้อย่างอิสระ สามารถแสดงรูปแบบการคำนวณได้กว้างมาก และคุณสมบัติที่น่าทึ่งที่สุดคือ in-context learning จากบทที่ 4 — ความสามารถปรับพฤติกรรมตามตัวอย่างในข้อความโดยไม่มีการเทรน
มีงานวิจัยที่เสนอว่าสิ่งที่เกิดขึ้นภายในนั้นคล้ายกับการมีกระบวนการเรียนรู้ย่อย ๆ เกิดขึ้นในตัวการคำนวณเอง ระหว่างที่ข้อมูลไหลผ่านชั้นต่าง ๆ พูดอีกอย่างคือ ตอนออกแบบเราตั้งใจให้มันเรียนตอนเทรน แต่มันดันได้ความสามารถในการเรียนตอนใช้งานมาแถมด้วย
ที่ทำให้ข้อเสนอนี้น่าคิดคือรูปร่างของสมการมันพ้องกันพอดี ชั้นหนึ่งชั้นของ Transformer คือ x = x + ส่วนแก้ ซึ่งคุณพิสูจน์ด้วยมือไปแล้วในบทที่ 11 ส่วนการเรียนรู้ด้วยการไล่ลาดชันก็คือ น้ำหนักใหม่ = น้ำหนักเดิม + ส่วนแก้ เหมือนกัน — ต่างกันแค่ว่าอันหนึ่งแก้ที่ข้อมูลระหว่างไหลผ่านชั้น อีกอันแก้ที่น้ำหนักระหว่างเทรน
12.2 ข้อสอง — เทรนขึ้น (optimizable)
ข้อนี้คุณพิสูจน์ด้วยมือแล้วในบทที่ 11 คำว่า True บรรทัดนั้น: ค่าเริ่มต้นของทุกชั้นคือไม่ทำอะไร บวกกับ layer norm ที่คุมสเกลไม่ให้ตัวเลขระเบิดหรือดับ ผลคือสัญญาณย้อนกลับวิ่งผ่านโมเดลลึกได้โดยไม่หายไปกลางทาง
ประวัติศาสตร์ตรงนี้น่าคิด — ปัญหา "เทรนโมเดลลึกไม่ขึ้น" ถูกแก้ไปแล้วในงานด้านภาพก่อนหน้านั้นหลายปี ทีมปี 2017 ไม่ได้คิดใหม่ พวกเขาหยิบของที่พิสูจน์แล้วมาประกอบ และนั่นคือส่วนที่คนมักมองข้ามเวลาเล่าเรื่องนี้
12.3 ข้อสาม — ฮาร์ดแวร์ที่โลกมีอยู่ ชอบรูปทรงนี้พอดี
ข้อนี้คือข้อที่ไม่ค่อยมีใครพูด และมันอาจสำคัญที่สุด
LSTM ต้องประมวลผลทีละคำตามลำดับเวลา คำที่สิบต้องรอคำที่เก้าเสร็จก่อน กราฟการคำนวณของมันจึงเป็นเส้นยาวและลึก ซึ่งบังคับให้ทำงานแบบเรียงลำดับ เอาคอร์เป็นพันมาช่วยก็ไม่ได้ เพราะงานมันรอกันเอง
Transformer ตรงข้าม ทุกโทเค็นถูกคำนวณพร้อมกันหมดในหนึ่งชั้น กราฟของมันจึงเป็น ตื้นและกว้าง ซึ่งเป็นรูปทรงเดียวกับที่การ์ดจอถูกออกแบบมาให้ทำ — คำนวณเรื่องเดียวกันหลายพันชุดพร้อมกัน
ผลที่ตามมาคือสิ่งที่เปลี่ยนโลก: มันขยายขนาดได้ เพิ่มข้อมูล เพิ่มพารามิเตอร์ เพิ่มการ์ดจอ แล้วมันเก่งขึ้นตามอย่างที่คาดเดาได้ ในขณะที่สถาปัตยกรรมแบบเรียงลำดับตันอยู่ที่เพดานของเวลาที่ต้องรอกันเอง
Transformer ไม่ได้ชนะเพราะฉลาดที่สุดในทางทฤษฎี มันชนะเพราะเป็นสถาปัตยกรรมที่ใช้ฮาร์ดแวร์ที่เรามีอยู่ได้เต็มที่ที่สุด แล้วความฉลาดตามมาจากขนาด
12.4 กินรวบทุกสาขาด้วยท่าเดียว — หั่นเป็นชิ้นแล้วโยนใส่
ชื่อบทนี้บอกว่ามันกินรวบทุกสาขา แต่ยังไม่ได้บอกว่าทำยังไง คำตอบเรียบง่ายจนน่าตกใจ: ไม่ต้องออกแบบสถาปัตยกรรมใหม่เลย แค่หั่นข้อมูลของสาขานั้นให้เป็นชิ้น ๆ แล้วส่งเข้าไปเป็นโหนดในกราฟ
| สาขา | หั่นอะไรเป็นโหนด |
|---|---|
| ภาพ | ตัดภาพเป็นช่องสี่เหลี่ยมเล็ก ๆ แต่ละช่องคือหนึ่งโหนด |
| เสียง | ตัดสเปกโทรแกรมตามแกนเวลาเป็นชิ้น ๆ |
| การตัดสินใจเป็นลำดับ | มองสถานะ การกระทำ และรางวัล เป็นลำดับเหมือนคำในประโยค |
นี่คือเหตุผลว่าทำไมกำแพงระหว่างสาขาที่เล่าไว้ในบทที่ 7 ถึงพังลง — ไม่ใช่เพราะมีใครสร้างสะพานข้ามมัน แต่เพราะทุกสาขาถูกแปลให้พูดภาษาเดียวกันคือ "ลำดับของชิ้นข้อมูล" แล้วเครื่องมือตัวเดียวก็ใช้ได้หมด ความรู้เฉพาะทางที่แต่ละวงการสะสมมาหลายสิบปีจึงถูกลบออกอีกชั้นหนึ่ง ตรงกับแถวที่สองในตารางบทที่ 1 พอดี
12.5 กลับไปที่ตารางในบทที่ 1
ตอนนี้ตารางสี่แถวนั้นควรอ่านไม่เหมือนเดิมแล้ว การลบแต่ละครั้งไม่ใช่การทิ้งความรู้ทิ้งเปล่า ๆ มันคือการเปลี่ยนสิ่งที่มนุษย์กำหนดตายตัว ให้เป็นสิ่งที่ข้อมูลกับการคำนวณเติมเข้ามาได้ และสิ่งที่ทำให้การแลกนี้คุ้มคือข้อสาม — เพราะเรามีเครื่องที่คำนวณขนานได้มหาศาลอยู่ในมือ
นี่คือเหตุผลที่ประโยคว่า "ลบทุกอย่าง เหลือแค่กราฟ" ไม่ใช่คำเท่ ๆ มันคือคำอธิบายทางวิศวกรรมที่ตรงตัว: เหลือกราฟไว้ เพราะกราฟคือรูปทรงที่ขยายขนาดได้
💡 สิ่งที่คู่มือเล่มนี้ไม่ได้ตอบ — เล่มนี้อธิบายว่าสถาปัตยกรรมทำงานยังไงและทำไมมันชนะ แต่ไม่ได้ตอบว่าทำไมการขยายขนาดแล้วได้ความสามารถที่ไม่มีใครสั่งไว้ (เช่นการให้เหตุผลหลายขั้น) ซึ่งยังเป็นคำถามเปิดของวงการจริง ๆ ไม่ใช่เรื่องที่มีคำตอบแล้วแต่เล่มนี้ตัดออก
อ่านต่อ: เล่มนี้เล่ากลไกข้างในโมเดล ส่วนบันไดสาย AI เล่าวิธีใช้มัน เดินได้ทั้งบันไดโดยไม่ต้องกลับมาที่เล่มนี้ และกลับกันก็ได้ — เริ่มที่ Prompt 0 → Hero สำหรับการเขียนคำสั่งให้ได้ผลตามที่บทที่ 5 วางพื้นไว้ · ต่อด้วย Context Engineering ว่าอะไรควรอยู่ตรงหน้าโมเดล ณ วินาทีที่มันถูกเรียก · แล้วปิดที่ Harness Engineering ที่ผ่ากลไกรอบนอกของโมเดลทั้งตัว
คู่มือ Transformer — ลบทุกอย่าง เหลือแค่กราฟ — ทำไมการถอนข้อสมมติของมนุษย์ออกทีละชั้น กลับทำให้เครื่องเก่งขึ้น สำหรับคนที่ใช้ AI เป็นแล้วอยากรู้ว่าข้างในมันทำงานยังไง
ส่วนหนึ่งของ Handbooks — เขียนเพื่อเข้าใจ ไม่ใช่เพื่อท่องจำ · โดย @tayakorn221 · 2026
If this was useful —buy me a coffee