โมเดลภาษาสร้างข้อความอย่างไร: temperature และ top-k ใน Python
โมเดลภาษาให้คะแนน (logit) กับ token ทุกตัวที่อาจมาเป็นตัวถัดไป การตั้งค่าการสุ่มจะกำหนดว่าคะแนนเหล่านั้นกลายเป็นตัวเลือกอย่างไร temperature ควบคุมความสุ่ม และ top-k เก็บไว้เฉพาะตัวเลือกที่ดีที่สุด
แนวคิดแบบเข้าใจง่าย
โมเดลภาษาให้คะแนน (logit) กับ token ทุกตัวที่อาจมาเป็นตัวถัดไป การตั้งค่าการสุ่มจะกำหนดว่าคะแนนเหล่านั้นกลายเป็นตัวเลือกอย่างไร temperature ควบคุมความสุ่ม และ top-k เก็บไว้เฉพาะตัวเลือกที่ดีที่สุด
ดูว่าโมเดลภาษาเลือก token ถัดไปอย่างไร: layer normalization, temperature และการสุ่มแบบ top-k ด้วย Python ล้วน
ประเด็นสำคัญ
- temperature ต่ำกว่า 1 ทำให้ผลลัพธ์คาดเดาได้มากขึ้น สูงกว่า 1 ทำให้สร้างสรรค์มากขึ้น
- การสุ่มแบบ top-k ตัด token ที่ไม่น่าจะเกิดออก ข้อความจึงไม่หลุดประเด็น
- ข้อความถูกสร้างทีละ token และ token ใหม่แต่ละตัวจะถูกป้อนกลับเป็นอินพุต
- layer normalization รักษาค่าให้อยู่ในช่วงที่เสถียรขณะผ่านหลายชั้น
ควรใช้เมื่อใด?
- เข้าใจสิ่งที่เกิดขึ้นภายในโครงข่ายประสาทเทียมและไลบรารี AI
- เข้าใจแนวคิดก่อนลงมือเขียนเองในโจทย์ที่เกี่ยวข้อง
- เตรียมตัวสำหรับคอร์สแมชชีนเลิร์นนิง การสัมภาษณ์งาน และโปรเจกต์
ลองดูการทำงานจริง
กดปุ่มลูกเต๋าเพื่อสุ่มคำถัดไป ลด temperature หรือ top-k เพื่อให้การเลือกคาดเดาได้มากขึ้น
โค้ดตัวอย่าง
import math
import random
# Layer normalization rescales a vector to mean 0 and variance 1.
def layer_norm(x, eps=1e-5):
mean = sum(x) / len(x)
var = sum((v - mean) ** 2 for v in x) / len(x)
return [(v - mean) / math.sqrt(var + eps) for v in x]
print("layer norm:", [round(v, 3) for v in layer_norm([2.0, 4.0, 6.0, 8.0])])
# Next-token scores from a model; temperature and top-k shape the choice.
words = ["cat", "dog", "car", "sky"]
logits = [2.0, 1.5, 0.3, -1.0]
def probabilities(temperature=1.0, top_k=None):
scores = [l / temperature for l in logits]
if top_k: # keep only the k best scores
cutoff = sorted(scores, reverse=True)[top_k - 1]
scores = [s if s >= cutoff else -1e9 for s in scores]
exps = [math.exp(s - max(scores)) for s in scores]
return [e / sum(exps) for e in exps]
for t, k in [(1.0, None), (0.5, None), (1.0, 2)]:
print(f"temperature={t} top_k={k}:", [round(p, 2) for p in probabilities(t, k)])
random.seed(7)
print("sampled:", random.choices(words, weights=probabilities(0.8, 3), k=5))
ผลลัพธ์ที่คาดหวัง
layer norm: [-1.342, -0.447, 0.447, 1.342]
temperature=1.0 top_k=None: [0.54, 0.33, 0.1, 0.03]
temperature=0.5 top_k=None: [0.71, 0.26, 0.02, 0.0]
temperature=1.0 top_k=2: [0.62, 0.38, 0.0, 0.0]
sampled: ['cat', 'cat', 'dog', 'cat', 'cat']
หลักการทำงาน
layer_norm() ปรับเวกเตอร์ให้มีค่าเฉลี่ย 0 และความแปรปรวน 1 ซึ่ง Transformer ทำในทุกบล็อก probabilities() หาร logit ด้วย temperature แล้วใช้ softmax ดังนั้น temperature ต่ำจะทำให้คำอันดับหนึ่งมีโอกาสถูกเลือกมากขึ้น ส่วน top-k ตั้งคะแนนที่อยู่นอก k อันดับแรกให้เกือบเป็น −∞ ก่อน softmax
เปลี่ยนค่าและรันโปรแกรมด้วย คอมไพเลอร์ Python ออนไลน์ของ CodeUtility โดยไม่ต้องติดตั้ง Python
แบบฝึกหัด
ลองเปลี่ยน input และทดสอบกรณีขอบก่อนใช้ชุดข้อมูลที่ใหญ่ขึ้น
- เปลี่ยนอินพุตหรือน้ำหนัก แล้วลองทายผลลัพธ์ก่อนรัน
- พิมพ์ค่าระหว่างทางออกมาเพื่อดูการคำนวณทีละขั้น
- แก้โจทย์ที่ลิงก์ไว้ด้านล่างเพื่อเขียนแนวคิดนี้ด้วยตัวเอง
ฝึกด้วยโจทย์
ใช้สิ่งที่เรียนในบทนี้แก้ปัญหาจริง ทุกโจทย์รันในเบราว์เซอร์ พร้อมการทดสอบทันทีและรีวิวจาก AI
- Layer normalization ปรับแต่ละแถวให้มีค่าเฉลี่ย 0 และความแปรปรวน 1 จากนั้นปรับสเกลและเลื่อน แบบเดียวกับที่ทุกบล็อก Transformer ทำ ปานกลาง
- การสุ่มด้วย temperature และ top-k เลือก token ถัดไปแบบโมเดลภาษา: เก็บ logit สูงสุด k ตัว ใช้ temperature แล้วสุ่ม ปานกลาง