Speculative Decoding: Cách LLM Sinh Văn Bản Nhanh Gấp 2–3 Lần
Posted on: 6/15/2026 1:14:48 AM
Table of contents
- Speculative Decoding là gì, trong một câu
- Nút thắt thật sự: LLM không thiếu sức tính, mà thiếu băng thông
- Ý tưởng cốt lõi: đoán thì rẻ, kiểm thì song song
- Toán học của sự "miễn phí": vì sao chất lượng không đổi
- Bốn họ kỹ thuật đang thống trị 2026
- Token tree: kiểm nhiều nhánh đoán cùng lúc
- Khi nào tăng tốc, khi nào phản tác dụng
- Hành trình từ ý tưởng đến chuẩn production
- Bật trong production: cấu hình thực tế
- Tác động vận hành: vì sao đây là bài toán tối ưu chi phí
- Kết luận
Khi bạn gõ một câu hỏi cho Claude hay ChatGPT, chữ hiện ra gần như tức thì rồi tuôn đều đặn từng dòng. Cảm giác mượt mà đó che giấu một sự thật khó chịu: ở dưới capô, mô hình ngôn ngữ lớn (LLM) sinh chữ từng token một, và mỗi token là một lượt nạp toàn bộ hàng chục tỉ tham số từ bộ nhớ GPU. Đây là điểm nghẽn căn bản của giải mã tự hồi quy (autoregressive). Vậy làm sao các nhà cung cấp vẫn trả lời nhanh đến thế ở quy mô hàng triệu người dùng?
Câu trả lời, phần lớn, là một mẹo phản trực giác tên là Speculative Decoding (giải mã suy đoán): để một mô hình nhỏ, nhanh đoán trước vài token kế tiếp, rồi để mô hình lớn kiểm tra cả chùm cùng lúc trong đúng một lượt tính. Điều đẹp đẽ nhất: kết quả cuối cùng giống hệt từng bit như khi chỉ dùng mô hình lớn — không đánh đổi một chút chất lượng nào. Bài viết này mổ xẻ vì sao thủ thuật này hoạt động, toán học khiến nó "miễn phí", bốn họ kỹ thuật đang thống trị 2026, và cách bật nó trong production.
Speculative Decoding là gì, trong một câu
Là kỹ thuật tăng tốc suy luận LLM bằng cách dùng một bộ nháp (draft) rẻ tiền để đề xuất nhiều token kế tiếp, rồi để mô hình đích (target) kiểm tra cả chùm trong một lượt forward duy nhất — chấp nhận phần đoán đúng và sửa ngay tại token sai đầu tiên, sao cho phân phối đầu ra không đổi so với việc chạy mô hình đích đơn lẻ.
Nút thắt thật sự: LLM không thiếu sức tính, mà thiếu băng thông
Trực giác thường thấy là "muốn nhanh hơn thì cần nhiều FLOPs hơn". Với giải mã LLM ở chế độ tương tác (batch nhỏ), điều này sai. Mỗi bước sinh một token, GPU phải kéo toàn bộ trọng số của mô hình từ bộ nhớ băng thông cao (HBM) vào các nhân tính toán — nhưng chỉ để nhân với một vector trạng thái duy nhất. Tỉ lệ "phép tính trên mỗi byte nạp về" (arithmetic intensity) cực thấp, nên GPU dành phần lớn thời gian chờ bộ nhớ, còn các nhân ma trận thì ngồi không. Đây gọi là chế độ memory-bandwidth bound.
Hệ quả nghịch lý: nạp trọng số để dự đoán 1 token, hay để dự đoán đồng thời 5 token, tốn gần như cùng một thời gian, vì chi phí bị thống trị bởi việc chuyển trọng số chứ không phải bởi số phép nhân. Nói cách khác, một lượt forward của mô hình lớn có thừa "ngân sách tính toán ẩn" mà chế độ sinh từng-token-một bỏ phí. Speculative Decoding ra đời chính để thu hồi phần ngân sách bỏ phí đó.
Mấu chốt để nhớ
Sinh chữ là tuần tự (token sau phụ thuộc token trước) nên không song song hóa được. Nhưng kiểm tra một chuỗi token cho sẵn lại song song hóa được hoàn toàn: một lượt forward có thể chấm điểm xác suất cho mọi vị trí cùng lúc. Toàn bộ Speculative Decoding xoay quanh việc khai thác sự bất đối xứng này.
Ý tưởng cốt lõi: đoán thì rẻ, kiểm thì song song
Quy trình một vòng (cycle) của Speculative Decoding gồm ba bước:
- Nháp (draft). Một mô hình phụ nhỏ và nhanh sinh tự hồi quy
Ktoken ứng viên (ví dụ K = 4–8). Vì nó nhỏ, K bước này rất rẻ. - Kiểm (verify). Mô hình đích chạy một lượt forward duy nhất trên (prompt + K token nháp), thu về phân phối xác suất ở từng vị trí — tức "ý kiến" của mô hình lớn về mỗi token mà bản nháp đề xuất.
- Chấp nhận / sửa. Một bước lấy mẫu thông minh quyết định tiền tố dài nhất của bản nháp được giữ lại, và sửa ngay tại token sai đầu tiên. Phần còn lại của bản nháp bị bỏ. Lặp lại.
Nếu trung bình mỗi vòng chấp nhận được γ token, thì mỗi lượt forward của mô hình lớn cho ra γ+1 token thay vì 1. Vì lượt forward của mô hình lớn mới là chi phí thống trị, tốc độ sinh tăng xấp xỉ γ+1 lần (trừ đi chi phí chạy bản nháp).
flowchart TB
S["Ngữ cảnh hiện tại"] --> D["Mô hình NHAP nho
sinh K token ung vien
(tu hoi quy, re)"]
D --> V["Mo hinh DICH lon
1 luot forward kiem ca K token
(song song)"]
V --> A{"Lay mau chap nhan
token nao dung?"}
A -- "chap nhan tien to + 1 token bonus" --> G["Phat ra gamma+1 token
trong 1 luot forward lon"]
A -- "token sai dau tien" --> F["Sua bang phan phoi du
bo phan nhap con lai"]
F --> G
G --> C{"Da xong?"}
C -- "chua" --> S
C -- "roi" --> E["Tra ket qua"]
style S fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style D fill:#16213e,stroke:#fff,color:#fff
style V fill:#e94560,stroke:#fff,color:#fff
style A fill:#ff9800,stroke:#fff,color:#fff
style G fill:#2c3e50,stroke:#fff,color:#fff
Toán học của sự "miễn phí": vì sao chất lượng không đổi
Điểm khiến Speculative Decoding khác hẳn các thủ thuật tăng tốc khác (như lượng tử hóa hay cắt tỉa) là nó không xấp xỉ. Đầu ra được chứng minh là tuân theo đúng phân phối của mô hình đích. Bí mật nằm ở một biến thể của lấy mẫu loại bỏ (rejection sampling), được Leviathan và cộng sự (Google) cùng Chen và cộng sự (DeepMind) công bố độc lập năm 2023.
Gọi q(x) là xác suất mô hình nháp gán cho token x, và p(x) là xác suất mô hình đích gán cho token đó. Với mỗi token nháp, lần lượt theo thứ tự:
- Chấp nhận token với xác suất
min(1, p(x) / q(x)). Nếu mô hình lớn "tin" vào token này ít nhất bằng mô hình nhỏ, luôn giữ. - Nếu bị loại ở vị trí nào đó, lấy một token thay thế từ phân phối dư đã chuẩn hóa
norm(max(0, p(x) − q(x))), rồi dừng — bỏ toàn bộ token nháp phía sau. - Nếu chấp nhận hết cả K token nháp, lấy thêm một token "bonus" từ phân phối của mô hình đích ở vị trí K+1 — token này gần như miễn phí vì lượt forward lớn đã tính sẵn nó.
Có thể chứng minh quy trình này tạo ra các token phân phối chính xác như khi lấy mẫu trực tiếp từ mô hình đích. Đó là lý do người ta gọi Speculative Decoding là kỹ thuật "lossless" (không mất mát): nó chỉ thay đổi thứ tự tính toán, không thay đổi phân phối kết quả.
Trường hợp tham lam (greedy / nhiệt độ thấp)
Khi giải mã tham lam, quy tắc rút gọn rất trực quan: chấp nhận tiền tố dài nhất mà token argmax của bản nháp trùng với token argmax của mô hình đích; tại điểm lệch đầu tiên, lấy token của mô hình đích. Đây là lý do nhiệt độ thấp (đầu ra xác định hơn) cho tỉ lệ chấp nhận cao hơn — bản nháp dễ "đoán trúng" hơn.
sequenceDiagram
participant U as Vong lap
participant Dr as Mo hinh nhap (nho)
participant Tg as Mo hinh dich (lon)
U->>Dr: Ngu canh hien tai
Dr-->>U: K token nhap: [t1 t2 t3 t4]
U->>Tg: prompt + [t1 t2 t3 t4] (1 luot forward)
Tg-->>U: phan phoi p tai moi vi tri
Note over U: Chap nhan t1,t2,t3 (p>=q)
t4 bi loai -> lay mau lai tu (p-q)+
U-->>U: Phat ra t1 t2 t3 + t4' = 4 token / 1 luot lon
Note over U,Tg: Lap lai voi ngu canh moi
Bốn họ kỹ thuật đang thống trị 2026
"Bản nháp" có thể đến từ nhiều nguồn khác nhau, và đây là nơi các phương pháp phân hóa. Đánh đổi cốt lõi luôn là: bản nháp càng giống mô hình đích thì tỉ lệ chấp nhận càng cao, nhưng tạo bản nháp càng tốn thì lợi ích càng bị bào mòn.
| Họ kỹ thuật | Nguồn bản nháp | Cần train thêm? | Điểm mạnh | Hợp khi |
|---|---|---|---|---|
| Hai mô hình (draft model) | Một LLM nhỏ cùng họ (vd 1B nháp cho 70B) | Không, nếu đã có sẵn model nhỏ | Đơn giản, dễ hiểu, hiệu quả tốt | Đã có cặp model nhỏ–lớn cùng tokenizer |
| Medusa | Gắn thêm vài "đầu" dự đoán vào chính mô hình đích | Có — train các đầu phụ | Không cần model phụ riêng, ít tốn bộ nhớ | Muốn tự suy đoán, ngại quản lý hai model |
| EAGLE / EAGLE-2 / EAGLE-3 | Tự hồi quy ở tầng đặc trưng + cây ứng viên | Có — train một lớp nháp nhẹ | Tỉ lệ chấp nhận SOTA, tăng tốc cao nhất 2026 | Cần tốc độ tối đa, chấp nhận train một lần |
| N-gram / Prompt Lookup | Sao chép cụm từ ngay trong prompt/ngữ cảnh | Không — zero-cost, không cần model | Bản nháp miễn phí hoàn toàn | Tải lặp nhiều: RAG, sửa code, tóm tắt |
Hai chi tiết đáng nhớ. Thứ nhất, EAGLE không đoán token thô mà đoán ở tầng đặc trưng ẩn (hidden features) rồi mới chiếu ra token — nhờ đó bản nháp "đồng pha" hơn với mô hình lớn, đẩy tỉ lệ chấp nhận lên cao. EAGLE-3 (2025) bỏ hồi quy đặc trưng để dự đoán trực tiếp ở tầng token và hợp nhất đa tầng, nhờ vậy đạt 2–6× và số token chấp nhận trung bình quanh 4–5 mỗi vòng. Thứ hai, Prompt Lookup đẹp ở chỗ với các tác vụ mà đầu ra lặp lại nhiều phần của đầu vào (trích dẫn nguồn trong RAG, sửa một file code, viết lại đoạn văn), bản nháp tốt nhất đơn giản là chính các cụm từ có sẵn trong ngữ cảnh — không tốn một FLOP nào để tạo.
Token tree: kiểm nhiều nhánh đoán cùng lúc
Các phương pháp hiện đại (EAGLE, Medusa, SpecInfer) không chỉ đoán một chuỗi token mà đoán cả một cây các khả năng. Thay vì cược tất cả vào một dự đoán tuyến tính, bản nháp đề xuất nhiều nhánh, và mô hình đích kiểm toàn bộ cây trong một lượt forward nhờ tree attention — một mặt nạ chú ý đặc biệt cho phép mỗi nhánh chỉ "nhìn" tổ tiên của nó. Nhánh được chấp nhận sâu nhất chính là đầu ra của vòng đó.
flowchart TB
R(("token goc")) --> A1["the"]
R --> A2["a"]
A1 --> B1["cat"]
A1 --> B2["dog"]
A2 --> B3["big"]
B1 --> C1["sat"]
B2 --> C2["ran"]
style R fill:#e94560,stroke:#fff,color:#fff
style A1 fill:#2c3e50,stroke:#fff,color:#fff
style A2 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style B1 fill:#2c3e50,stroke:#fff,color:#fff
style B2 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style B3 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style C1 fill:#2c3e50,stroke:#fff,color:#fff
style C2 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
Lợi ích của cây là tăng số token kỳ vọng được chấp nhận mỗi vòng: nếu nhánh thẳng đầu tiên sai sớm, một nhánh khác trong cây vẫn có thể đúng dài hơn. Cái giá là thêm chút tính toán cho các nhánh sẽ bị bỏ — nhưng vì đang ở chế độ memory-bound, phần tính thêm này phần lớn "miễn phí".
Khi nào tăng tốc, khi nào phản tác dụng
Speculative Decoding không phải nút bấm thần kỳ luôn-thắng. Có ba yếu tố quyết định nó giúp được bao nhiêu — hay có khi làm chậm đi.
| Yếu tố | Có lợi cho Spec Decoding | Bất lợi / cần cân nhắc |
|---|---|---|
| Nhiệt độ (temperature) | Thấp / greedy → bản nháp dễ trúng, chấp nhận cao | Cao → đầu ra ngẫu nhiên hơn, tỉ lệ chấp nhận giảm |
| Kích thước batch | Batch nhỏ, tương tác → đang memory-bound, lợi lớn | Batch lớn → đã compute-bound, FLOPs kiểm dư có thể bào mòn throughput |
| Chất lượng bản nháp | Nháp giống đích → γ cao | Nháp quá tốn (model phụ to) → lợi ích bị ăn ngược |
| Độ dài suy đoán K | K vừa phải, hợp với độ "dễ đoán" của tải | K quá lớn → lãng phí khi token sai xuất hiện sớm |
Cạm bẫy thường gặp
Ở chế độ phục vụ throughput cao, batch lớn, GPU đã chuyển sang compute-bound. Khi đó các token nháp bị loại trở thành FLOPs phí, và Speculative Decoding có thể giảm tổng throughput dù vẫn cải thiện độ trễ từng-token cho một số request. Hãy đo trên chính tải của bạn: tối ưu cho độ trễ tương tác (TPOT) khác hẳn tối ưu cho throughput hàng loạt. Đồng thời lưu ý: kỹ thuật này tăng tốc thời gian giữa các token (TPOT), chứ không rút ngắn thời gian tới token đầu tiên (TTFT) vốn do bước prefill quyết định.
Hành trình từ ý tưởng đến chuẩn production
Bật trong production: cấu hình thực tế
Tin tốt cho kỹ sư: bạn gần như không cần tự cài đặt thuật toán. Các engine phục vụ phổ biến đã hỗ trợ sẵn. Trên vLLM (2026), Speculative Decoding khai báo qua trường speculative_config, hỗ trợ nhiều phương pháp: ngram, eagle, eagle3, medusa, draft_model và các biến thể MTP.
# vLLM -- n-gram (zero-cost draft), hop cho RAG / sua code / tom tat
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-3.1-70B-Instruct",
speculative_config={
"method": "ngram",
"num_speculative_tokens": 5, # K
"prompt_lookup_max": 4, # cua so n-gram toi da
},
)
# vLLM -- EAGLE-3 (tang toc cao nhat, can lop nhap da train)
llm = LLM(
model="meta-llama/Llama-3.1-8B-Instruct",
speculative_config={
"method": "eagle3",
"model": "yuhuili/EAGLE3-LLaMA3.1-Instruct-8B",
"num_speculative_tokens": 6,
},
)
Mẹo chọn phương pháp nhanh
- Không muốn train gì, tải nhiều phần lặp đầu vào (RAG, code edit) → bắt đầu với
ngram/ prompt-lookup. Lợi ích tức thì, rủi ro bằng không. - Muốn tăng tốc tối đa, chấp nhận train một lần → EAGLE-3, hiện cho tỉ lệ chấp nhận tốt nhất.
- Đã có sẵn cặp model nhỏ–lớn cùng tokenizer → draft model hai-mô-hình là lựa chọn đơn giản, dễ suy luận.
- Luôn benchmark trên tải thật với phân bố nhiệt độ và batch giống production trước khi chốt K và phương pháp.
Tác động vận hành: vì sao đây là bài toán tối ưu chi phí
Nhìn ở góc vận hành, Speculative Decoding là một trong những đòn bẩy hiếm hoi cho phép cải thiện đồng thời cả độ trễ lẫn chi phí mà không hi sinh chất lượng. Với cùng một GPU, bạn phát ra nhiều token hơn mỗi giây cho mỗi request tương tác → trải nghiệm streaming mượt hơn, người dùng chờ ít hơn. Với cùng một mức trải nghiệm mục tiêu, bạn cần ít GPU-giờ hơn để phục vụ cùng lượng tải → hóa đơn suy luận giảm.
Đây chính là mảnh ghép thường bị bỏ qua trong câu chuyện "ứng dụng AI tối ưu vận hành": phần lớn chi phí của một sản phẩm LLM nằm ở suy luận lúc phục vụ, không phải lúc huấn luyện. Một thay đổi cấu hình ở tầng serving — bật Speculative Decoding và tinh chỉnh K theo tải — có thể đem lại mức tiết kiệm mà nếu đi đường "đổi sang model nhỏ hơn" thì phải trả giá bằng chất lượng. Ở đây bạn không đánh đổi gì cả: phân phối đầu ra giữ nguyên.
Việc nên làm
- Mặc định bật thử Speculative Decoding cho mọi endpoint tương tác, đo trước khi kết luận.
- Khởi đầu với
ngramnếu tải có nhiều phần lặp đầu vào — lợi ích miễn phí, không cần train. - Tinh chỉnh
Ktheo "độ dễ đoán" của tải; theo dõi số token chấp nhận trung bình như chỉ số sức khỏe. - Tách bạch mục tiêu: tối ưu độ trễ (batch nhỏ) hay throughput (batch lớn) — cấu hình tối ưu khác nhau.
- Giữ greedy/nhiệt độ thấp ở những endpoint cần độ chính xác cao — vừa lợi chất lượng vừa tăng tỉ lệ chấp nhận.
Việc nên tránh
- Bật mù quáng ở chế độ batch rất lớn rồi ngạc nhiên khi throughput tụt — lúc đó GPU đã compute-bound.
- Chọn model nháp quá lớn: chi phí nháp ăn hết phần tăng tốc.
- Kỳ vọng cải thiện TTFT — kỹ thuật này tăng tốc giữa các token, không phải bước prefill.
- Tin rằng có đánh đổi chất lượng nên "ngại bật" — với lấy mẫu loại bỏ đúng chuẩn, đầu ra là lossless.
- Đặt một giá trị
Kcố định cho mọi loại tải mà không đo lại.
Kết luận
Speculative Decoding là một trong những ý tưởng đẹp nhất của hạ tầng AI hiện đại: nó không làm mô hình thông minh hơn, không đổi một tham số nào, mà chỉ sắp xếp lại trật tự tính toán để thu hồi phần băng thông GPU vốn bị giải mã từng-token-một bỏ phí. Đoán thì rẻ và tuần tự; kiểm thì song song và gần như miễn phí ở chế độ memory-bound — và nhờ một mẹo lấy mẫu loại bỏ, kết quả cuối cùng giống hệt mô hình gốc tới từng bit. Từ hai mô hình cổ điển tới EAGLE-3 và token tree năm 2026, hướng tiến hóa vẫn không đổi: làm bản nháp ngày càng "đồng pha" với mô hình đích để chấp nhận được nhiều token hơn mỗi vòng. Với người xây sản phẩm LLM, đây là đòn bẩy hiếm hoi vừa giảm độ trễ vừa cắt chi phí mà không phải hi sinh chất lượng — một cấu hình đáng bật mặc định và đáng đo cho đúng tải của bạn.
Nguồn tham khảo
- Leviathan, Kalman, Matias (Google) — Fast Inference from Transformers via Speculative Decoding (ICML 2023)
- Chen et al. (DeepMind) — Accelerating Large Language Model Decoding with Speculative Sampling
- Cai et al. — Medusa: Simple LLM Inference Acceleration with Multiple Decoding Heads
- Li et al. — EAGLE-3: Scaling Inference Acceleration via Training-Time Test
- vLLM — Tài liệu Speculative Decoding (ngram / EAGLE / Medusa)
- AWS ML Blog — P-EAGLE: Parallel Speculative Decoding trong vLLM
- Hugging Face — Speculative Decoding in Practice: How EAGLE-3 Makes LLMs Faster
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.