โจทย์
โมเดลภาษาเลือก token ถัดไปจากการแจกแจงความน่าจะเป็น โดยมีการตั้งค่าสองอย่างที่กำหนดรูปร่างของมัน:
- 'Top-k: เก็บเฉพาะ k token ที่มี logit สูงที่สุด (ถ้า logit เท่ากัน index ที่น้อยกว่าอยู่อันดับสูงกว่า)'
- 'Temperature T: หาร logit ที่เก็บไว้ด้วย T ก่อน softmax ค่า T ต่ำทำให้การเลือกคาดเดาได้มากขึ้น ค่า T สูงทำให้สุ่มมากขึ้น'
เพื่อให้ทดสอบการสุ่มได้ จึงกำหนดตัวเลขสุ่มมาให้:
- เก็บ token ใน top-k และเรียงตาม index เดิม (จากน้อยไปมาก)
- คำนวณ softmax(logit / T) บน token ที่เก็บไว้ (ลบค่าที่มากที่สุดก่อนคำนวณ e^x)
- ไล่ตามรายการพร้อมบวกความน่าจะเป็นสะสม คืนค่า index ของ token แรกที่ผลรวมสะสมมากกว่า
random_valueถ้าไม่เกิดขึ้นเลย (จากการปัดเศษ) ให้คืน token สุดท้ายที่เก็บไว้
เมื่อ k = 1 จะเป็น greedy decoding: เลือก token ที่น่าจะเป็นมากที่สุดเสมอ
จง implement sample_token(logits, temperature, k, random_value)
อินพุต
logits: คะแนนหนึ่งค่าต่อ token ในคลังคำศัพท์
temperature: T ซึ่งมากกว่า 0
k: จำนวน token อันดับต้นที่จะเก็บไว้
random_value: ตัวเลขสุ่มใน [0, 1)
เอาต์พุต
คืนค่า index ของ token ที่ถูกเลือก
เงื่อนไข
1 ≤ k ≤ จำนวน logit ≤ 1,000
0 < temperature ≤ 100, 0 ≤ random_value < 1
-100 ≤ แต่ละ logit ≤ 100
ตัวอย่าง
อินพุต:
k = 1
logits = [1.0, 3.0, 2.0, 0.5]
temperature = 1.0
random_value = 0.99
ผลลัพธ์ที่คาดหวัง:
expected = 1
อินพุต:
long long k = 1;
std::vector<double> logits = {1.0, 3.0, 2.0, 0.5};
double temperature = 1.0;
double random_value = 0.99;
ผลลัพธ์ที่คาดหวัง:
long long expected = 1;
อินพุต:
long k = 1;
double[] logits = new double[] {1.0, 3.0, 2.0, 0.5};
double temperature = 1.0;
double random_value = 0.99;
ผลลัพธ์ที่คาดหวัง:
long expected = 1;
คำอธิบาย
k = 1 เก็บเฉพาะ logit สูงสุด คือ 3.0 ที่ index 1 ความน่าจะเป็นของมันคือ 1 จึงถูกเลือกไม่ว่าตัวเลขสุ่มจะเป็นเท่าใด: greedy decoding
อินพุต:
k = 2
logits = [2.0, 1.0, 0.0]
temperature = 1.0
random_value = 0.8
ผลลัพธ์ที่คาดหวัง:
expected = 1
อินพุต:
long long k = 2;
std::vector<double> logits = {2.0, 1.0, 0.0};
double temperature = 1.0;
double random_value = 0.8;
ผลลัพธ์ที่คาดหวัง:
long long expected = 1;
อินพุต:
long k = 2;
double[] logits = new double[] {2.0, 1.0, 0.0};
double temperature = 1.0;
double random_value = 0.8;
ผลลัพธ์ที่คาดหวัง:
long expected = 1;
คำอธิบาย
Top-2 เก็บ index 0 และ 1 (logit 2 และ 1) softmax ได้ประมาณ 0.731 และ 0.269 ผลรวมสะสมเป็น 0.731 หลัง index 0 (ไม่เกิน 0.8) และเป็น 1 หลัง index 1 ดังนั้นจึงเลือก index 1
แหล่งอ้างอิง
โจทย์นี้ปรับให้เหมาะกับ CodeUtility กรุณาทำตามคำชี้แจงและข้อจำกัดด้านบน