
Top P, Top K, và Stop Sequences — giải thích chi tiết
1. Top P (Nucleus Sampling)
Nó chọn một tập hợp các từ có xác suất cao nhất sao cho tổng xác suất của tập hợp đó đạt đến hoặc vượt qua một ngưỡng P nhất định.
Cơ chế: Model sắp xếp các từ ứng viên theo xác suất giảm dần, rồi cộng dồn xác suất cho đến khi tổng đạt ngưỡng P. Tất cả từ trong "tập nucleus" đó được giữ lại để sampling; phần đuôi xác suất thấp bị cắt bỏ hoàn toàn.
Bản chất của Top P là kích thước tập từ được xét thay đổi linh hoạt tùy theo hình dạng phân phối xác suất, chứ không cố định số lượng từ như Top K.
Ví dụ:
Trường hợp phân phối "nhọn" (model rất chắc chắn):
"bò": 0.85, "gà": 0.08, "cuốn": 0.04, ...
Với P = 0.9: chỉ cần "bò" + "gà" (0.93) đã vượt ngưỡng → tập nucleus chỉ có 2 từ. Model gần như chắc chắn sẽ ra "phở bò".
Trường hợp phân phối "phẳng" (model phân vân):
"bò": 0.25, "gà": 0.20, "cuốn": 0.18, "xào": 0.15, "áp chảo": 0.12, ...
Với cùng P = 0.9: phải cộng đến 5-6 từ mới đạt ngưỡng → tập nucleus rộng hơn nhiều, output đa dạng hơn.
→ Đây chính là ưu điểm cốt lõi của Top P so với Top K: nó tự thích nghi. Khi model tự tin, tập từ nhỏ lại (ít rác); khi model phân vân, tập từ mở rộng ra (giữ được sự đa dạng hợp lý) thay vì cắt cứng theo số lượng.
2. Top K
Top K là tham số giới hạn số lượng từ có xác suất cao nhất được mô hình xem xét khi chọn từ tiếp theo.
Ví dụ: Prompt: "Món ăn yêu thích của tôi là phở, đặc biệt là phở..."
Mô hình dự đoán các từ tiếp theo với xác suất: bò: 0.6 gà: 0.2 cuốn: 0.1 xào: 0.05 nước: 0.03 ... (và nhiều từ khác với xác suất rất nhỏ)
- Nếu K = 2: Mô hình chỉ xem xét "bò" (0.6) và "gà" (0.2). Các từ khác bị loại bỏ. Sau đó, nó sẽ chọn ngẫu nhiên giữa "bò" và "gà" (khả năng cao chọn "bò"). - Nếu K = 3: Mô hình xem xét "bò" (0.6), "gà" (0.2), và "cuốn" (0.1). Từ tiếp theo sẽ được chọn ngẫu nhiên từ 3 từ này.
3. Stop Sequences
Trong thực tế, stop sequences mạnh nhất khi dùng cho cấu trúc output có định dạng rõ ràng, ví dụ:
a) Ép dừng ở ranh giới lượt hội thoại (chatbot):
stop_sequences: ["\n\nHuman:", "\n\nUser:"]
Ngăn model tự "diễn" luôn cả câu hỏi tiếp theo của người dùng — rất hay gặp khi build custom prompt template thay vì dùng chat template chuẩn.
b) Ép dừng khi sinh code/JSON để tránh model viết lan man sau khi đã xong:
Prompt: "Trả lời dạng JSON, kết thúc bằng ###"
stop_sequences: ["###"]
→ Bạn parse JSON xong là dừng ngay, không sợ model viết thêm giải thích thừa phía sau làm hỏng JSON.parse().
c) Ép dừng theo cấu trúc markdown/code block:
stop_sequences: ["```"]
Dùng khi chỉ muốn lấy đúng 1 code block, không muốn model viết thêm đoạn giải thích sau đó.
Một điểm quan trọng: stop sequence phải khớp chính xác chuỗi ký tự, không phải theo nghĩa. Nếu bạn set "." làm stop sequence, model dừng ở dấu chấm đầu tiên xuất hiện — kể cả dấu chấm trong số thập phân ("giá 1.5 triệu") cũng sẽ bị cắt ngang, đây là nhược điểm cần lưu ý khi chọn stop sequence quá "phổ biến".
4. Áp dụng thực tế — ví dụ với Bedrock/Anthropic API
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=500,
temperature=0.7,
top_p=0.9,
top_k=40,
stop_sequences=["\n\n---", "###"],
messages=[{"role": "user", "content": "Viết mô tả ngắn cho món phở bò"}]
)