Sampling — temperature và top-p
Temperature không phải nút chỉnh độ thông minh. Nó điều chỉnh cách chọn token từ phân phối xác suất — và đoán được output đổi thế nào khi vặn nó.
TL;DR: Temperature không phải "nút chỉnh độ thông minh" — nó chỉnh độ nhọn của phân phối xác suất token kế tiếp (bài 01), trước khi một token được chọn. T thấp bóp phân phối nhọn về token khả dĩ nhất → gần-greedy: nhất quán nhưng dễ lặp. T cao san phẳng phân phối → token hiếm cũng có cửa: đa dạng hơn nhưng dễ rời rạc. top-p (nucleus sampling) là núm khác hẳn — không đổi hình dạng, mà cắt tập ứng viên: chỉ giữ nhóm token nhỏ nhất có tổng xác suất từ p trở lên. Hai núm độc lập nhau.
Đội dev nội bộ ngân hàng chạy UAT hai bot cùng lúc. Bot FAQ tra chính sách set T bằng 0 — "cho an toàn, khỏi bịa". Nhưng tester hỏi cùng một ý bằng năm cách diễn đạt khác nhau, cả năm lần bot trả gần như nguyên văn một câu — đọc như kịch bản dựng sẵn. Cùng lúc, bot soạn thông báo nội bộ set T gần 2 "cho sinh động" — sinh câu đứt mạch, có đoạn lặp một cụm từ vô nghĩa liên tục.
Hai đội đều nghĩ mình đang vặn "độ thông minh của AI". Cả hai sai ngay câu hỏi: temperature không đổi model biết gì — nó chỉ đổi cách model chọn giữa các khả năng đã tính sẵn.
Bài 01: mỗi bước, model tính ra một phân phối xác suất trên toàn vocabulary (bài 02) cho token kế tiếp — chưa phải chọn thẳng một token. Bài này mổ đúng bước chọn đó: quy tắc chọn nào, và bạn vặn được gì.
1. Analogy — vòng quay may mắn ở hội chợ
Một gian hàng hội chợ có vòng quay trúng thưởng: phần thưởng "hot" vẽ miếng to, phần thưởng ít ai màng vẽ miếng bé tí. Quay một lần, kim dừng ở đâu ăn giải đó — miếng càng to, cơ hội trúng càng cao.
Ban tổ chức có hai cách can thiệp trước khi bạn quay:
| Hội chợ | Sampling |
|---|---|
| Vẽ lại tỉ lệ các miếng: thu nhỏ hết mọi miếng trừ miếng to nhất, hoặc san đều các miếng | Temperature scale logits trước softmax — đổi độ nhọn của phân phối |
| Gỡ bỏ hẳn những miếng bé tí ra khỏi mặt vòng trước khi quay | top-p giữ tập nhỏ nhất có tổng xác suất đạt ngưỡng p, loại đuôi dài |
| Quay đúng một lần, ra đúng một kết quả | Sample ra đúng một token |
| Vòng gốc chưa chỉnh gì vẫn có sẵn tỉ lệ miếng | Phân phối xác suất gốc do model tính ra (bài 01) |
Temperature vẽ lại tỉ lệ miếng trên cùng một vòng quay. top-p gỡ bớt miếng trước khi quay. Hai việc khác nhau, làm cùng lúc được.
2. Hai núm vặn, một phân phối
Trước khi mổ cơ chế, đoán trước.
Cùng một prompt, cùng model. Hạ temperature xuống gần 0 rồi chạy lại nhiều lần — output có giống nhau không? Vặn temperature lên rất cao — token hiếm có cơ hội xuất hiện nhiều hơn hay ít hơn? top-p bằng 1.0 so với 0.5 — tập token có thể chọn thay đổi thế nào? Viết dự đoán trước khi đọc tiếp.
Toàn cảnh một bước sinh token, tính từ chỗ bài 01 dừng lại:

Hai hộp giữa — chia cho T và lọc top-p — là hai núm độc lập, tác động lên cùng một phân phối nhưng theo hai cách khác hẳn nhau. Mục 3 và 4 mổ từng hộp.
3. Cơ chế temperature — scale logits trước softmax
Model không tính thẳng ra xác suất. Nó tính ra logits — điểm số thô cho từng token trong vocabulary, số nào cũng được, chưa cộng lại bằng 1. Softmax biến logits thành xác suất: token điểm cao hơn thì xác suất cao hơn, tổng toàn bộ luôn bằng 1.
T (temperature) chia vào logits trước khi đưa qua softmax:
-- z la logits tho model tinh ra, T la temperature
function chon_token_tiep_theo(z[], T):
for i in z:
z_scaled[i] <- z[i] / T -- T nho hon 1: khoang cach gian ra, T lon hon 1: khoang cach thu hep
xac_suat <- softmax(z_scaled) -- chuan hoa, tong = 1
return sample(xac_suat) -- boc tham theo trong so xac suat
Chia cho một số nhỏ hơn 1 làm khoảng cách giữa các logits giãn ra — token vốn đã cao điểm càng bỏ xa phần còn lại, phân phối nhọn hơn. Chia cho một số lớn hơn 1 làm khoảng cách co lại — mọi token gần bằng nhau hơn, phân phối phẳng hơn.
Ví dụ minh hoạ (logits giả định cho bốn token tiếp theo của "Hôm nay trời...", tính bằng đúng công thức trên, không phải số đo từ model thật):
| Token | Logits gốc | Xác suất, T = 1 | Xác suất, T = 0.5 | Xác suất, T = 2 |
|---|---|---|---|---|
| đẹp | 2.0 | 0.505 | 0.694 | 0.379 |
| nắng | 1.5 | 0.306 | 0.255 | 0.295 |
| mưa | 0.5 | 0.113 | 0.035 | 0.179 |
| lạnh | 0.1 | 0.076 | 0.016 | 0.147 |
Đọc bảng: ở T = 0.5, "đẹp" chiếm gần 70% — phần lớn các lần chạy ra "đẹp", nhưng khoảng ba trong mười lần vẫn ra token khác. Ở T = 2, bốn token gần đều nhau hơn hẳn — "lạnh" nhảy từ 7.6% lên gần 15%, dù vẫn là token ít hợp lý nhất. Bot FAQ đầu bài (T gần 0) rơi vào vùng nhất quán tới cứng nhắc; bot thông báo (T gần 2) rơi vào vùng token hiếm áp đảo nhiều lần liên tiếp, output đứt mạch.
4. Cơ chế top-p — cắt tập ứng viên, không đổi hình dạng
top-p (nucleus sampling) giải quyết một vấn đề khác: vocabulary có hàng chục nghìn token, nên dù mỗi token trong "đuôi dài" xác suất thấp chỉ chiếm một mẩu bé, cộng dồn cả đuôi vẫn chiếm phần đáng kể tổng xác suất — T cao chỉ làm đuôi đó phẳng hơn, không loại bỏ nó. Holtzman et al. chỉ ra: sample trúng một token lạc quẻ trong đuôi này đủ kéo cả câu sau trôi rời rạc — họ gọi là text degeneration (The Curious Case of Neural Text Degeneration, arXiv:1904.09751).
Cách chữa: đừng cho đuôi dài cơ hội được rút thăm ngay từ đầu.
-- xac_suat[] da sap xep giam dan, p la nguong top-p
function loc_nucleus(xac_suat[], p):
tong <- 0
nucleus <- {}
for token, xs in xac_suat:
if tong dat nguong p: break -- du nguong, dung lai, khong nhan them
nucleus.add(token)
tong <- tong + xs
return chuan_hoa_lai(nucleus) -- re-normalize de tong = 1 trong tap con
Áp vào đúng phân phối gốc (T = 1) ở mục 3:
| Ngưỡng p | Token còn trong nucleus | Token bị loại |
|---|---|---|
| p = 0.9 | đẹp, nắng, mưa (cộng dồn 0.924) | lạnh (0.076) |
| p = 0.5 | đẹp (một mình đã 0.505) | nắng, mưa, lạnh |
| p = 1.0 | cả bốn — không loại gì | — |
Điểm mấu chốt: top-p không đổi tỉ lệ giữa các token còn lại như temperature — nó chỉ quyết định token nào còn được đứng trong vòng quay. Ở p = 0.5, dù T = 1 (chưa chỉnh nhọn/phẳng gì), kết quả luôn ra "đẹp" — vì riêng "đẹp" đã đủ chạm ngưỡng 0.5, cả ba token còn lại bị gạch tên trước khi quay, chỉ còn đúng một ứng viên.
5. Vặn cả hai cùng lúc, output đổi thế nào?
Nhớ lại dự đoán ở mục 2. Ghép temperature và top-p vào một bảng quyết định:
| Cấu hình | Hình dạng phân phối sau xử lý | Hành vi kỳ vọng | Ca ở đầu bài |
|---|---|---|---|
| T thấp (gần 0), top-p mặc định cao | Rất nhọn | Nhất quán, gần-greedy, an toàn nhưng dễ lặp | Bot FAQ — đúng nguyên nhân đọc như kịch bản dựng sẵn |
| T vừa (khoảng 0.7–1), top-p vừa (khoảng 0.9) | Cân bằng | Đa dạng vừa phải, vẫn mạch lạc | Cấu hình khởi điểm hợp lý cho hầu hết use case |
| T cao (trên 1.5), top-p cao (gần 1) | Rất phẳng, đuôi dài còn nguyên | Đa dạng cao, dễ chọn nhầm token lạc quẻ, đứt mạch | Bot thông báo nội bộ — đúng nguyên nhân lặp cụm vô nghĩa |
| T bất kỳ, top-p thấp (khoảng 0.1–0.3) | Tập ứng viên bị siết chặt | Gần-greedy trong dải T thực dụng (0–2) | Set T cao mà top-p quá thấp thì temperature gần như mất tác dụng |
Hai đội ở đầu bài không cần đổi model hay viết lại prompt — họ cần đúng chỗ vặn: bot FAQ muốn bớt cứng nhắc thì nới T lên một chút thay vì giữ 0 tuyệt đối; bot thông báo muốn bớt đứt mạch thì hạ cả T lẫn top-p, không chỉ một trong hai.
6. Pitfall tổng hợp
❌ Nhầm 1 — temperature là "độ thông minh" của model:
✅ Temperature không đổi model biết gì hay tính gì — nó chỉ đổi cách chọn từ phân phối đã có sẵn. Model "cứng nhắc" ở T thấp không phải vì kém đi; "sáng tạo" ở T cao không phải vì giỏi hơn.
❌ Nhầm 2 — set T về 0 để loại bỏ hoàn toàn ngẫu nhiên:
✅ T tiến gần 0 chỉ làm phân phối nhọn tới mức gần-greedy — "gần" không phải "tuyệt đối", tie-break khi vài token cùng điểm vẫn để lại kẽ hở tuỳ hệ thống. Muốn chắc output giống hệt mọi lần, phải chạy lại kiểm chứng, không suy diễn từ con số T.
❌ Nhầm 3 — top-p càng cao càng "an toàn", càng thấp càng "rủi ro":
✅ Ngược lại. p = 1.0 là không lọc gì — giữ nguyên đuôi dài xác suất thấp. p càng thấp mới càng siết chặt, càng gần-greedy. Đọc nhầm chiều tham số này dẫn tới vặn sai hướng khi debug output rời rạc.
7. 📚 Deep Dive
Paper chính chủ:
- Holtzman, Buys, Du, Forbes & Choi — The Curious Case of Neural Text Degeneration — paper đề xuất nucleus (top-p) sampling; đọc phần motivation để thấy tại sao đuôi dài xác suất thấp nguy hiểm hơn trực giác, kể cả khi mỗi token trong đuôi chỉ chiếm một mẩu bé.
Ghi chú: bảng số ở mục 3–4 tính trực tiếp bằng công thức softmax/nucleus trong bài, không phải số đo từ một model thật — mục đích là đúng hướng thay đổi, không phải con số tuyệt đối.
8. Liên hệ các bài khác
- Bài 01 — Dự đoán token kế tiếp — vòng lặp mà bước chọn token trong bài này nằm bên trong.
- Bài 03 — Context window — cấu hình sampling khác cách context bị cắt, nhưng cả hai cùng góp phần model "trôi" xa chủ đề.
- Bài 05 — Từ base model đến chat — SFT/RLHF định hình phân phối, sampling quyết định chọn gì từ phân phối đó.
- Bài 06 — Hallucination — output rời rạc vì sai cấu hình sampling khác với hallucination do model tự tin bịa nội dung.
- Mini-challenge — đọc log ba sự cố — một trong ba sự cố cần đúng bài này để chẩn đoán.
9. Tóm tắt
- Temperature làm phân phối nhọn/phẳng (T thấp → nhất quán; T cao → đa dạng hơn, dễ rời rạc); top-p loại đuôi dài xác suất thấp mà không đổi hình dạng phân phối.
- p = 1.0 nghĩa là không lọc gì; p thấp mới là siết chặt tập ứng viên — hiểu ngược chiều tham số này là pitfall phổ biến.
- Hai núm độc lập: chỉnh temperature không sửa vấn đề của top-p; debug output bất thường cần kiểm cả hai.
- Temperature không phải "độ thông minh" — nó chỉ đổi cách chọn giữa các khả năng model đã tính sẵn.
10. Tự kiểm tra
Q1Từ phân phối xác suất ở bài 01, giải thích temperature làm gì với phân phối đó — và vì sao nó không phải nút chỉnh độ thông minh của model.▸
Temperature chia vào logits trước softmax, đổi độ nhọn/phẳng của phân phối xác suất token kế tiếp — token nào từng có mặt trong phân phối gốc vẫn có mặt, chỉ tỉ lệ được chọn thay đổi. Model không tính lại hay biết thêm gì; cái đổi chỉ là quy tắc rút thăm, nên gọi đây là nút chỉnh độ thông minh là sai gốc.
Q2Cho hai cấu hình: T gần 0 với top-p mặc định cao, và T gần 2 với top-p mặc định cao. Dự đoán khác biệt hành vi output và giải thích cơ chế đằng sau.▸
T gần 0 bóp phân phối nhọn về phía token khả dĩ nhất — output gần-greedy, nhiều lần chạy ra câu gần giống nhau, đúng ca bot FAQ đầu bài. T gần 2 san phẳng phân phối — token vốn hiếm có cơ hội được chọn cao hơn hẳn, dễ chọn liên tiếp vài token lạc quẻ, câu đứt mạch hoặc lặp cụm vô nghĩa, đúng ca bot thông báo nội bộ.
Q3top-p = 1.0 và top-p = 0.1 khác nhau thế nào về tập token có thể được chọn? Vì sao nói p càng cao càng an toàn là hiểu sai chiều tham số?▸
p = 1.0 giữ nguyên toàn bộ phân phối, kể cả đuôi dài xác suất thấp — không lọc gì. p = 0.1 chỉ giữ vài token xác suất cao nhất, đủ để tổng đạt 10%, còn lại bị loại hẳn. Vậy p thấp mới là siết chặt, gần-greedy; p cao mới là nới lỏng, giữ nhiều rủi ro hơn — ngược hoàn toàn với trực giác "số cao nghĩa là chặt hơn".
Q4Nucleus sampling (top-p) giải quyết vấn đề gì mà chỉ chỉnh temperature không giải quyết được?▸
Vocabulary có hàng chục nghìn token, nên dù mỗi token trong đuôi dài xác suất thấp chỉ chiếm một mẩu bé, cộng dồn cả đuôi vẫn chiếm phần đáng kể tổng xác suất — temperature cao chỉ làm đuôi đó phẳng hơn chứ không loại bỏ nó. Holtzman et al. chỉ ra sample trúng một token lạc quẻ trong đuôi đó đủ kéo câu sau trôi rời rạc; top-p cắt hẳn đuôi dài trước khi sample, chạm đúng lỗ hổng mà temperature bỏ qua.
Q5Team đang debug một bot trả lời rời rạc, thỉnh thoảng lặp một cụm từ vô nghĩa liên tục. Từ bài này, hai giả thuyết cấu hình đầu tiên bạn kiểm tra là gì, và cách sửa mỗi giả thuyết?▸
Giả thuyết một: temperature quá cao, phân phối bị san phẳng quá mức — hạ temperature dần tới khi output mạch lạc trở lại. Giả thuyết hai: top-p đang gần 1.0 (gần như không lọc), giữ nguyên đuôi dài xác suất thấp — hạ top-p để cắt bớt tập ứng viên. Vì hai núm độc lập, cần kiểm và chỉnh cả hai, không chỉ một.
Bài tiếp theo: Từ base model đến chat
Bài này đáng gửi cho bạn học cùng?
Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.
Bài này có giúp bạn hiểu bản chất không?
Hỏi đáp về bài này
Chưa có câu hỏi
Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).
Đặt câu hỏi đầu tiên