Skip to content
Tayakorn
← All handbooks
aiUpdated 2026-08-17Free

คู่มือ Transformer — ลบทุกอย่าง เหลือแค่กราฟ

เข้าใจ Transformer ถึงแก่นจากคำถามเดียว — ทำไมการลบสิ่งที่มนุษย์ออกแบบด้วยมือทิ้ง กลับทำให้เครื่องเก่งขึ้น ตั้งแต่ Software 1.0 จนอ่านโค้ด attention ออกทีละบรรทัด

#transformer#attention#llm#software-3.0#neural-networks

ลบสิ่งที่มนุษย์ออกแบบด้วยมือทิ้ง แล้วเครื่องกลับเก่งขึ้น — ทำไม (เล่มข้างทางของบันไดสาย 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รอบการเทรนโมเดลข้อความที่พิมพ์เข้าไปตอนใช้งาน
สิ่งที่มนุษย์ลงมือทำเองSoftware 1.0เขียนคำสั่งทีละขั้นSoftware 2.0สะสมชุดข้อมูลSoftware 3.0พิมพ์ข้อความสั่งงานลบอัลกอริทึมที่มนุษย์เขียนลบรอบการเทรน
FIG 1.1 ทุกจังหวะที่ก้าวไปข้างหน้า มีของที่มนุษย์ทำด้วยมือถูกลบออกหนึ่งชั้น — และสิ่งที่มนุษย์ยังต้องเขียน (บรรทัดล่างในกล่อง) สั้นลงเรื่อย ๆ

สังเกตว่าทุกแถวเป็นเรื่องเดียวกัน: มนุษย์ยอมถอนสมมติฐานที่ตัวเองใส่เข้าไป แล้วปล่อยที่ว่างนั้นให้ข้อมูลกับการคำนวณเติมแทน ชื่อของการบรรยายที่เล่มนี้เรียบเรียงมาคือ "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

รวบรวมข้อมูลเทรนโมเดลปล่อยใช้งานจริงดักจับเคสที่พลาดติดป้ายกำกับเพิ่มป้อนกลับเข้าชุดข้อมูล แล้ววนอีกรอบ
FIG 3.1 ขั้นที่สร้างมูลค่าคือขั้นที่ถูกเน้น ไม่ใช่ขั้นเทรน — ข้อมูลที่มีค่าที่สุด คือข้อมูลในจุดที่โมเดลยังพลาด ไม่ใช่ข้อมูลที่เยอะที่สุด

วงจรเดินอย่างนี้: รวบรวมข้อมูล → เทรนโมเดล → ปล่อยใช้งานจริง → ดักจับเคสที่โมเดลพลาด → ติดป้ายกำกับเคสเหล่านั้นเพิ่ม → ป้อนกลับเข้าชุดข้อมูล → เทรนใหม่ แล้ววนอีกรอบ

หัวใจอยู่ที่ขั้นที่สี่ ไม่ใช่ขั้นที่สอง คนมักคิดว่างานหลักคือการเทรน ความจริงคืองานหลักคือการหาว่าโมเดลพลาดตรงไหน เพราะข้อมูลที่มีค่าที่สุดไม่ใช่ข้อมูลที่เยอะที่สุด แต่คือข้อมูลในจุดที่โมเดลยังไม่รู้เรื่อง ถ่ายรูปถนนโล่งเพิ่มอีกล้านรูปแล้วโมเดลไม่เก่งขึ้น แต่รูปถนนตอนฝนตกกลางคืนที่มีเงาสะท้อนไฟหน้ารถอีกพันรูปเปลี่ยนผลลัพธ์ได้จริง

💡 อุปมาที่ใช้ได้และจุดที่มันพัง — 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 step78.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 เป็นแกน วิธีทำงานคือ อ่านประโยคต้นทางทีละคำ สะสมความเข้าใจไว้ แล้วเมื่ออ่านจบก็ได้ เวกเตอร์ตัวเดียวขนาดคงที่ ที่ควรบรรจุความหมายของทั้งประโยคไว้ จากนั้นฝ่ายถอดรหัสก็เอาเวกเตอร์นั้นไปคลี่ออกเป็นประโยคปลายทาง

ประโยคต้นทางคำที่ 1คำที่ 2คำที่ 3คำที่ 4คำที่ 5เวกเตอร์เดียวขนาดคงที่ตลอดฝ่ายถอดรหัสเห็นแค่กล่องกลางนี้ประโยคยาวขึ้น แต่กล่องกลางไม่โตตามส่วนที่ล้น คือส่วนที่หายไป
FIG 7.1 ข้อจำกัดตัวจริงไม่ใช่ขนาดของกล่องกลาง แต่คือการที่ฝ่ายถอดรหัสห้ามย้อนกลับไปดูต้นทางเลย — เห็นได้แค่สิ่งที่รอดผ่านคอขวดมา

ปัญหาปรากฏชัดทันทีเมื่อประโยคยาวขึ้น เพราะเวกเตอร์มีขนาดเท่าเดิมตลอด ไม่ว่าประโยคจะยาวห้าคำหรือห้าสิบคำ ข้อมูลจึงต้องหล่นหายไปไหนสักที่ นี่คือสิ่งที่เรียกว่า คอขวดของฝ่ายเข้ารหัส (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 — "ถ้ามีใครสนใจฉัน เนื้อหาที่ฉันจะส่งให้คืออะไร"
เฟสสื่อสาร — โน้ดส่งข้อมูลถึงกันQโน้ดที่ถามหาอะไรอยู่Kทุกโน้ดมีอะไรอยู่กับตัวsoftmaxคะแนนกลายเป็นน้ำหนักรวมได้ 1Vถ่วงน้ำหนักแล้วบวกกันq @ k.T / sqrt(head)เฟสคิด — แต่ละโน้ดแปรรูปข้อมูลของตัวเองMLPMLPMLPMLPสังเกตว่าไม่มีเส้นเชื่อมสักเส้น — เฟสนี้ไม่มีการคุยกันเลย
FIG 9.1 จุดที่เน้นคือขั้นที่คะแนนกลายเป็นน้ำหนักรวมได้ 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 — ไม่ได้ต่างกันที่สถาปัตยกรรม พวกมันใช้ของชิ้นเดียวกันกับที่คุณเพิ่งรันในบทที่แล้ว ต่างกันแค่เรื่องเดียว: ใครถูกอนุญาตให้มองเห็นใคร

แถว = โน้ดที่ถาม · คอลัมน์ = โน้ดที่ถูกมอง · ช่องทึบ = มองเห็นได้BERTมองเห็นกันหมดจำแนก · ทำเวกเตอร์GPTเห็นแต่ตัวเองกับอดีตผลิตข้อความต่อเนื่องเข้ารหัสถอดรหัสT5 · Whisperบนมองกันหมดล่างเห็นแต่อดีต
FIG 10.1 โมเดลทั้งสามตระกูลใช้กลไกชิ้นเดียวกัน ต่างกันแค่ตารางนี้ — ช่องจางคือช่องที่ถูกเติม -inf ก่อนเข้า softmax จึงเหลือน้ำหนักศูนย์พอดี
ตระกูลตัวอย่างเงื่อนไขการมองเห็นเหมาะกับงาน
Encoder-onlyBERTทุกโน้ดมองเห็นกันหมด ไม่มีหน้ากากจำแนกประเภท วิเคราะห์อารมณ์ ทำเวกเตอร์แทนความหมาย
Decoder-onlyGPTมองเห็นเฉพาะตัวเองกับอดีตผลิตข้อความต่อเนื่อง โมเดลภาษาขนาดใหญ่
Encoder-decoderT5, 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)ลึกและยาว — ต้องรอกันเองt1t2t3t2 เริ่มไม่ได้จนกว่า t1 จะเสร็จเพิ่มคอร์ก็ไม่ช่วยมองหากันพร้อมกัน (Transformer)ตื้นและกว้าง — คำนวณขนานได้t1t2t3t4t5หนึ่งชั้น จบพร้อมกันทุกตำแหน่งเพิ่มการ์ดจอแล้วเร็วขึ้นตามจริงจึงขยายขนาดได้ และความฉลาดตามมาจากขนาด
FIG 12.1 รูปทรงฝั่งขวาคือรูปทรงเดียวกับที่การ์ดจอทำได้เร็วที่สุด — นี่คือเหตุผลข้อที่สาม และเป็นข้อที่ทำให้การขยายขนาดเป็นไปได้จริง

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