[LLM 6/10] Context Distillation: ย้าย system prompt เข้าไปเก็บในน้ำหนักโมเดล
ทุกครั้งที่ผู้ใช้ส่งข้อความหาแชตบอตของคุณ คุณแนบ system prompt ก้อนเดิมยาวหลายร้อย token ไปด้วยเสมอ — ทุก request ตลอดอายุของระบบ จ่ายซ้ำไม่มีวันจบ บทนี้เราจะย้ายความรู้ก้อนนั้นจาก prompt เข้าไปอยู่ในน้ำหนักโมเดลด้วยเทคนิคชื่อ Context Distillation ในเวอร์ชัน on-policy (OPCD) จุดที่สวยที่สุดคือ ครูกับนักเรียนเป็นโมเดลตัวเดียวกันเป๊ะ ๆ — สิ่งเดียวที่ต่างกันคือใครได้เห็น prompt
Open in Colab06_context_distillation.ipynb
1. ปัญหา (Problem statement)
ระบบผู้ช่วยลูกค้าภาษาไทยทั่วไปมี system prompt หน้าตาประมาณนี้: กำหนด persona, บังคับให้ตอบภาษาไทยเสมอ, ต้องสุภาพลงท้ายครับ/ค่ะ, ห้ามให้คำแนะนำทางการแพทย์และกฎหมาย เขียนออกมาดี ๆ ก็ราว 400 token — และมันถูกส่งไปกับทุก request
ลองคิดเลขดูครับ ระบบที่รับ 100,000 request ต่อวัน จ่ายค่า token ให้ข้อความก้อนเดิมซ้ำ ๆ วันละ 40 ล้าน token เดือนละ 1,200 ล้าน token — ทั้งที่เนื้อหาไม่เคยเปลี่ยนเลยสักตัวอักษร และนี่ยังไม่นับราคาอีกสองอย่างที่มองไม่เห็นในบิล:
- Latency — โมเดลต้อง prefill 400 token ก่อนจะเริ่มคิดคำตอบแรกทุกครั้ง
- Context budget — ทุก token ของ persona คือที่ที่หายไปจากประวัติการสนทนาและเอกสารแนบ
มองในกรอบของซีรีส์นี้ ความรู้มีที่เก็บได้สามที่ และแต่ละที่มี "กำหนดจ่าย" ต่างกัน:
| ที่เก็บความรู้ | จ่ายเมื่อไหร่ | เหมาะกับ |
|---|---|---|
| System prompt | ทุก request ตลอดไป | พฤติกรรม/นโยบายที่ยังเปลี่ยนบ่อย |
| RAG | ทุก request (ค้น + prompt ยาว) | ข้อเท็จจริงจำนวนมาก เปลี่ยนบ่อย ต้องอ้างอิงแหล่งที่มา |
| น้ำหนักโมเดล | ครั้งเดียวตอนเทรน | พฤติกรรม/นโยบายที่นิ่งแล้ว |
system prompt ที่นิ่งแล้วแต่ยังแนบไปทุกครั้ง คือความรู้ที่เก็บผิดที่ — มันควรย้ายจากแถวแรกลงไปอยู่แถวสุดท้ายของตารางนี้ บทนี้คือวิธีย้าย
2. เราจะทำอะไร (Solution)
Context distillation คือการเทรนนักเรียนที่ไม่เห็น context ให้ทำตัวเหมือนครูที่เห็น — พูดอีกแบบคือย้ายผลของ จาก prompt เข้าไปในน้ำหนัก แนวคิด offline ดั้งเดิมมีมาตั้งแต่งานของ Askell และคณะ (2021) ส่วนเวอร์ชันที่เราใช้ในบทนี้คือ OPCD (On-Policy Context Distillation) ของ Ye, Dong, Wu, Huang และ Wei (2026, arXiv:2602.12275) ซึ่งเพิ่มส่วนผสมสำคัญสองอย่างที่หัวข้อ 3 จะแกะทีละตัว:
- นักเรียนสุ่มคำตอบของตัวเอง (on-policy) โดยไม่เห็น
- บนคำตอบเหล่านั้น minimize reverse KL เทียบกับครูที่เห็น
system prompt คือความรู้ที่เก็บผิดที่ — เก็บใน prompt คุณจ่ายทุก request ตลอดไป OPCD ย้ายมันเข้าไปในน้ำหนัก แล้วคุณจ่ายครั้งเดียวตอนเทรน
และในบทนี้ ครูกับนักเรียนคือน้ำหนักชุดเดียวกัน — ครูคือโมเดลตอนที่มี อยู่ตรงหน้า นักเรียนคือโมเดลตัวเดิมที่ไม่มี สิ่งที่ระยะห่างระหว่างสองตัวนี้วัด คือ "อิทธิพลของ " ล้วน ๆ
ขอปักหมุดประโยคหนึ่งไว้ตั้งแต่ตอนนี้ เพราะบทที่ 7 จะพูดถึง "distillation" อีกตัวที่คนสับสนกันบ่อย:
Context distillation เปลี่ยน "สิ่งที่โมเดลรู้โดยไม่ต้องบอก" — model distillation เปลี่ยน "ขนาดของโมเดล"
ในบทนี้โมเดลไม่ได้เล็กลงแม้แต่พารามิเตอร์เดียว มันแค่เลิกต้องการ prompt ส่วนบทที่ 7 คือเรื่องของการย่อโมเดลใหญ่ลงเป็นโมเดลเล็ก — คนละแกนกันโดยสิ้นเชิง
3. สมการ (Equation)
3.1 Objective ของ OPCD
โดย KL ในแต่ละตำแหน่ง token คือผลรวมข้ามทั้ง vocabulary :
- = context ที่อยากย้ายเข้า weights (persona + นโยบายความปลอดภัย ~400 token)
- = คำถามของผู้ใช้, = คำตอบที่นักเรียนสุ่มเองโดยไม่เห็น
- = นักเรียน (ทำนายโดยเห็นแค่ ), = ครู (น้ำหนักเดิม แต่เห็น ด้วย)
- = เฉลี่ยต่อ token กันคำตอบยาวได้น้ำหนักเกิน (คุ้น ๆ ไหมครับ — length bias จากบทที่ 4)
สังเกตว่านี่ไม่ใช่ cross-entropy กับ "เฉลย" ใด ๆ — เป้าหมายคือการกระจายความน่าจะเป็นทั้งแถวของครู ในทุกตำแหน่ง token นักเรียนไม่ได้เรียนว่า "คำถัดไปคืออะไร" แต่เรียนว่า "ถ้ามี อยู่ตรงหน้า ความน่าจะเป็นของทุกคำใน vocab จะหน้าตาเป็นอย่างไร"
สมการนี้มีจุดตัดสินใจสองจุดที่แบกน้ำหนักทั้งวิธีเอาไว้ แยกดูทีละจุด
3.2 จุดที่หนึ่ง — KL ต้องเป็น reverse ( อยู่หน้า)
KL ไม่สมมาตร และลำดับของมันคือการเลือกพฤติกรรม:
- Forward KL ระเบิดเมื่อครูมีมวลแต่นักเรียนไม่มี → นักเรียนถูกบังคับให้ "ครอบคลุม" ทุก mode ของครู (mode-covering) ถ้าความจุไม่พอ มันจะถัวเฉลี่ยแผ่มวลไปคลุมทุกอย่าง รวมถึงหุบเขาระหว่าง mode ที่ครูไม่เคยไป — ในภาษาของ LLM นั่นคือคำตอบประเภท "ผสมสองสไตล์จนเพี้ยน" หรือ hallucination
- Reverse KL ระเบิดเมื่อนักเรียนมีมวลตรงที่ครูไม่มี → นักเรียนถูกบังคับให้ไม่ทำสิ่งที่ครูไม่ทำ แล้วเลือกยึด mode ใด mode หนึ่งของครูให้มั่น (mode-seeking)
สำหรับงานของบทนี้ — persona และนโยบายความปลอดภัย — เราต้องการอย่างหลังแบบไม่ต้องคิดเลย: นักเรียนที่ "ทำเหมือนครูได้สักทางหนึ่ง อย่างมั่นคง" มีค่ากว่านักเรียนที่ "เผื่อความน่าจะเป็นให้ทุกทางของครู แถมทางที่ครูห้ามด้วย"
ถ้าคุ้น ๆ ว่าเคยเห็นที่ไหน — ใช่ครับ KL ในสมการ RLHF ของบทที่ 3–4 ก็เอา ไว้หน้าเหมือนกัน ด้วยเหตุผลเดียวกัน: เราคุมพฤติกรรมของตัวที่กำลังเทรน ไม่ใช่ของตัวอ้างอิง
3.3 จุดที่สอง — rollout ต้องเป็นของนักเรียนเอง (on-policy)
สังเกต ในสมการ 3.1: คำตอบที่ใช้เทรนสุ่มมาจากนักเรียน ไม่ใช่จากครู
ทางเลือกที่ง่ายกว่าคือให้ครู (ที่เห็น ) เขียนคำตอบมาชุดหนึ่ง แล้วให้นักเรียนทำ SFT ตาม — วิธีนั้นมีปัญหาเชิงโครงสร้างชื่อ exposure bias: นักเรียนถูกสอนเฉพาะบนเส้นทางข้อความที่ครูเขียน แต่ตอนใช้งานจริง มันต้องเดินต่อจาก prefix ที่ตัวเองเขียน พลาดหนึ่ง token ก็หลุดไปอยู่ในสถานะที่ไม่เคยถูกสอน แล้วความผิดพลาดจะทบต้นไปเรื่อย ๆ
การสุ่มแบบ on-policy ลบปัญหานี้โดยโครงสร้าง: สถานะที่นักเรียนเจอระหว่างเทรน คือสถานะแบบเดียวกับที่มันจะเจอตอน inference เพราะมันเป็นคนสร้างเองทั้งคู่ ครูมีหน้าที่เดียวคือ "ยืนตรวจ" อยู่บนเส้นทางของนักเรียน — บอกว่า ณ จุดที่เธอเพิ่งเดินมาถึงนี้ ถ้ามี ควรจะไปทางไหนต่อ (นี่คือเหตุผลเดียวกับที่บทที่ 5 ต้องสุ่มคำตอบตัวเองแทนที่จะใช้ DPO ต่อ)
หมายเหตุความซื่อตรงหนึ่งบรรทัด: ตอนคำนวณ gradient เรา treat ที่สุ่มมาเป็นค่าคงที่ ไม่ส่ง gradient ย้อนผ่านการสุ่ม — เป็นแนวปฏิบัติมาตรฐานของ on-policy distillation
3.4 Baseline ที่ต้องสู้ให้ชนะ: offline context distillation
สิ่งที่บล็อกส่วนใหญ่เรียกว่า "context distillation" คือเวอร์ชัน offline:
อ่านออกมาตรง ๆ: ให้ครูที่เห็น เขียนคำตอบ แล้วเอาคำตอบนั้นมา SFT นักเรียนที่ไม่เห็น — เป็น cross-entropy บนข้อความของครูธรรมดา ๆ ไม่มี KL ทั้งแถว ไม่มี on-policy
นี่ไม่ใช่หุ่นฟางนะครับ มันคือ baseline ที่แข็งจริงและถูกกว่า (เทรนเหมือนบทที่ 2 เป๊ะ) หัวข้อ 9 จะให้ OPCD สู้กับมันแบบแฟร์ ๆ บนข้อมูลเดียวกัน ถ้าสองส่วนผสมของ OPCD (reverse KL + on-policy) มีค่าจริง มันต้องชนะตรงที่ทฤษฎีบอกว่าจะชนะ: การ generalize ไปยัง prompt แบบที่ไม่เคยเห็น
บทความนี้คือประมาณ 30% แรกของบทเรียน — ส่วนที่เหลือ (การเตรียมสภาพแวดล้อม, การเตรียมข้อมูล, โค้ดหลัก, ผลลัพธ์จริง และบทสรุป) อยู่ในคอร์ส LLM Finetuning ซึ่งเรียนฟรี เพียงเข้าสู่ระบบด้วย Google
อ่านเนื้อหาเต็มในคอร์ส →