Bài 1. LLM bên trong: token, attention và lấy mẫu
Hiểu mô hình đoán chữ tiếp theo thế nào, đo được bằng tay.
Cấp độ: Nền tảng · Thời lượng: 3 đến 4 giờ · Đầu ra: notebook l01_probe.ipynb
Mục tiêu
- Giải thích một LLM sinh chữ như thế nào, từ chuỗi ký tự đến phân phối xác suất trên từ vựng.
- Đếm token chính xác và dự đoán chi phí của một đoạn văn tiếng Việt so với tiếng Anh.
- Điều khiển temperature, top-p và hiểu vì sao cùng một prompt cho ra kết quả khác nhau.
- Nhận ra ba giới hạn cấu trúc: cửa sổ ngữ cảnh, kiến thức đóng băng theo thời điểm huấn luyện, và ảo giác.
Cơ chế cốt lõi
Token. Mô hình không đọc chữ cái mà đọc các mảnh (token) do bộ tách từ như BPE tạo ra. Từ tiếng Anh phổ biến thường là một token; tiếng Việt có dấu thường bị tách vụn hơn, nên cùng một ý có thể tốn gấp 1,5 đến 3 lần số token. Hệ quả thực tế: giá, độ trễ và giới hạn ngữ cảnh đều tính theo token, không theo số từ.
Dự đoán token tiếp theo. Mỗi bước, mạng Transformer nhận toàn bộ token đã có, cho ra một vector điểm (logit) cho mọi token trong từ vựng, đổi thành xác suất bằng softmax, chọn một token, nối vào chuỗi rồi lặp lại. Toàn bộ "trí thông minh" nằm ở chỗ mô hình học được phân phối này từ lượng văn bản khổng lồ.
Attention. Ở mỗi lớp, mỗi token tạo ba vector: query, key, value. Token hiện tại so query của nó với key của mọi token trước đó để quyết định "nhìn" vào đâu, rồi trộn các value theo trọng số đó. Chi phí tính attention tăng theo bình phương độ dài chuỗi, đó là lý do ngữ cảnh dài vừa đắt vừa chậm. KV cache lưu lại key và value của phần đã xử lý để khỏi tính lại khi sinh token mới.
Lấy mẫu. Temperature chia logit trước softmax: nhỏ hơn 1 làm phân phối nhọn (ổn định, lặp), lớn hơn 1 làm phân phối phẳng (đa dạng, dễ lạc đề). Top-p giữ tập token nhỏ nhất có tổng xác suất đạt p rồi bỏ phần đuôi. Temperature bằng 0 gần như chọn token xác suất cao nhất, nhưng vẫn có thể không tất định tuyệt đối do tính toán song song trên GPU.
Ba giai đoạn huấn luyện. Tiền huấn luyện (pre-training) trên văn bản thô tạo ra mô hình "hoàn thành văn bản". Tinh chỉnh theo chỉ dẫn (instruction tuning) dạy nó trả lời theo dạng hội thoại. Học từ phản hồi (RLHF, hoặc các biến thể như huấn luyện theo bộ nguyên tắc) định hình sự hữu ích và an toàn.
Đánh đổi và lỗi thường gặp
| Hiện tượng | Nguyên nhân thật | Cách xử lý |
|---|---|---|
| Đếm sai số chữ cái trong một từ | Mô hình thấy token, không thấy chữ cái | Bắt mô hình viết từng chữ ra trước, hoặc dùng code |
| Bịa tên sách, số liệu | Mô hình tối ưu "câu nghe hợp lý", không tối ưu "câu đúng" | Cấp tài liệu (Bài 4), yêu cầu trích dẫn, cho phép trả lời "không biết" |
| Quên chỉ dẫn ở đầu prompt dài | Thông tin ở giữa ngữ cảnh dài dễ bị bỏ sót | Đặt chỉ dẫn quan trọng ở đầu và nhắc lại ở cuối, cắt bớt ngữ cảnh thừa |
| Kết quả mỗi lần một khác | Lấy mẫu ngẫu nhiên | Hạ temperature, cố định đầu ra bằng schema, chạy nhiều lần rồi đo |
Lab: soi bên trong một mô hình nhỏ
Dùng một mô hình mở nhỏ (ví dụ Qwen/Qwen2.5-0.5B hoặc gpt2) trên Colab để thấy trực tiếp xác suất.
- Cài đặt:
pip install transformers torch. - Đếm token cho ba câu cùng nghĩa bằng tiếng Việt, tiếng Anh và tiếng Việt không dấu. Ghi tỉ lệ token trên số từ.
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
name = "Qwen/Qwen2.5-0.5B"
tok = AutoTokenizer.from_pretrained(name)
model = AutoModelForCausalLM.from_pretrained(name)
for s in ["Hôm nay trời Hà Nội se lạnh.", "Hanoi feels chilly today.", "Hom nay troi Ha Noi se lanh."]:
ids = tok(s)["input_ids"]
print(len(ids), [tok.decode([i]) for i in ids])
- In 10 token có xác suất cao nhất cho câu mở "Thủ đô của Việt Nam là":
ids = tok("Thủ đô của Việt Nam là", return_tensors="pt")
with torch.no_grad():
logits = model(**ids).logits[0, -1]
for T in (0.5, 1.0, 1.5):
p = torch.softmax(logits / T, dim=-1)
top = torch.topk(p, 10)
print(T, [(tok.decode([i]), round(v.item(), 3)) for v, i in zip(top.values, top.indices)])
- Sinh 20 lần với mỗi mức temperature 0,2 / 0,8 / 1,4 cho cùng prompt "Viết tên một món ăn Việt Nam:" và đếm số đáp án khác nhau.
- Ghi nhận xét vào cuối notebook: khi nào bạn muốn temperature thấp, khi nào cao.
Thử thách
Dễ (10 điểm): Máy tính tiền token. Viết hàm estimate_cost(text, price_in, price_out, out_ratio) dùng tokenizer thật để ước tính chi phí. Nghiệm thu: chạy trên 5 đoạn văn bạn chọn, in bảng token và chi phí, sai số so với số token đếm trực tiếp bằng 0.
Vừa (20 điểm): Bản đồ độ chắc chắn. Với 20 câu hỏi kiến thức (10 câu có đáp án chắc chắn, 10 câu về sự kiện mơ hồ hoặc bịa ra), tính entropy của phân phối token đầu tiên trong câu trả lời. Nghiệm thu: biểu đồ so sánh hai nhóm và một câu kết luận có số liệu; nêu rõ trường hợp entropy thấp nhưng mô hình vẫn sai.
Boss (40 điểm): Thuế token tiếng Việt. Lấy 200 cặp câu song ngữ Việt và Anh (tự soạn hoặc từ bộ dữ liệu mở có giấy phép rõ). So sánh số token trên ít nhất ba tokenizer khác nhau. Nghiệm thu: bảng tỉ lệ trung bình và phân vị 90, giải thích vì sao tokenizer nào "rẻ" hơn với tiếng Việt, và đề xuất một quy tắc viết prompt giúp giảm ít nhất 15% token mà không đổi nghĩa, kèm số đo trước sau.
Quiz tự kiểm tra
- Vì sao giá API tính theo token mà không theo từ?
- Temperature bằng 0 có đảm bảo kết quả giống hệt nhau mọi lần không?
- KV cache tiết kiệm cái gì?
- Một mô hình chỉ qua tiền huấn luyện sẽ phản ứng thế nào với câu "Hãy liệt kê 3 loại trái cây"?
- Tại sao đặt chỉ dẫn quan trọng ở cuối một prompt rất dài thường hiệu quả hơn ở giữa?
Đáp án
- Vì mô hình xử lý và sinh từng token; khối lượng tính toán tỉ lệ với số token, còn "từ" không có định nghĩa chung giữa các ngôn ngữ.
- Không hoàn toàn. Nó gần như chọn token cao nhất, nhưng sai số dấu phẩy động và cách gộp lô trên GPU có thể khiến kết quả lệch nhẹ.
- Tiết kiệm việc tính lại key và value cho các token đã xử lý, đổi lại tốn bộ nhớ GPU tăng theo độ dài ngữ cảnh.
- Nó có thể viết tiếp văn bản thay vì trả lời, ví dụ thêm một câu lệnh tương tự, vì nó chỉ học hoàn thành văn bản.
- Thông tin ở gần cuối nằm sát vị trí sinh câu trả lời; nhiều nghiên cứu cho thấy mô hình dễ bỏ sót thông tin nằm giữa ngữ cảnh dài.
Đọc thêm
- Vaswani et al., 2017, "Attention Is All You Need": https://arxiv.org/abs/1706.03762
- Hugging Face, "Tokenizers" và "Generation strategies": https://huggingface.co/docs/transformers/main/en/generation_strategies
- Liu et al., 2023, "Lost in the Middle: How Language Models Use Long Contexts": https://arxiv.org/abs/2307.03172
- Anthropic, "Token counting": https://docs.anthropic.com/en/docs/build-with-claude/token-counting
- Ouyang et al., 2022, "Training language models to follow instructions with human feedback": https://arxiv.org/abs/2203.02155