状态:草案(2026-10-27),已实测 n-gram,未实测 EAGLE、MTP、suffix。 测试环境为一张 8GB 级笔记本 GPU(Ada 架构)、vLLM 0.31.0、Qwen3-Reranker-0.6B,测试时间为 2026-10-27。基于模型的方法(EAGLE、MTP、草案模型)需要下载草案权重,suffix 方法需要下载额外的软件包,因此这次未进行测试。 2026-10-27 补充。 第 3.1 节中加入了使用对话型 Qwen3-0.6B 和 vLLM 0.32.0 重新测试的结果。0.31.0 和重排序模型的数值保持不变。 写作规则:以实测数据为基础,未能测出的标记为“未实测”,无法确认的标记为“未确认”。
目录
1. 原理:猜测与一次性验证
解码的一步大部分时间都花在从内存中读取权重上(第二篇)。然而,无论是检查一个 Token 还是五个 Token,读取权重的量都是一样的。因此,只要低成本地预测 几个接下来的 Token,并让大模型 一步验证整个草案即可。
초안(싼 방법): " keeps a queue of" ← 4토큰 제안
검증(큰 모델 한 걸음): " keeps" ✓ " a" ✓ " queue" ✓ " of" ✓ + 다음 토큰 하나
→ 한 걸음에 5토큰 확정
在第一个错误的 Token 处停止,该位置会被替换为大模型选定的 Token。因此,每一步至少能增加一个 Token。在采样(温度 > 0)中,通过拒绝采样(rejection sampling)来保持与大模型单独生成相同的分布,而在贪婪解码中,输出必须相同。Leviathan 等人(ICML 2023)报告称,在 T5-XXL 上输出保持不变且速度提升了 2 到 3 倍;Chen 等人(DeepMind, 2023)报告称,在 Chinchilla 70B 的分布式环境中速度提升了 2 到 2.5 倍(基于摘要)。
收益由两个数字决定:
- 接受长度:平均每步确定多少个 Token。草案越准,长度越长。
- 验证步的成本:同时检查 k 个草案的步骤比常规步骤贵多少。当 GPU 有剩余计算能力(批次较小时)时,两者几乎相同;但当批次较大且 GPU 已经很忙时,检查额外的 k 个 Token 会使步骤变长。
因此,官方文档也将推测解码介绍为“在中低请求率、受内存限制的负载下缩短 Token 间隔的功能”。
2. vLLM 的草案方法
| 方法 | 生成草案的方式 | 准备工作 | 文档评估(定性) | 论文报告的值(基于摘要) |
|---|---|---|---|---|
n-gram(ngram, ngram_gpu) |
从提示词和当前的输出中找到相同的 Token 序列并复制其后方 | 无 | 低请求率下低至中等 | 提示词查找解码:单张 A100,Mistral-7B,摘要和上下文问答中平均 2.4 倍 |
suffix(suffix) |
使用提示词和先前请求的输出构建后缀树,根据频率改变长度进行建议 | arctic-inference 包 |
低至中等,对多重复的任务有效 | SuffixDecoding:在智能体任务(SWE-Bench, Text-to-SQL)中最高达 5.3 倍 |
EAGLE·EAGLE-3(eagle, eagle3) |
接收大模型的隐藏状态并输出下一个 Token 的小模型头 | 已训练的草案模型头 | 高 | EAGLE:在 LLaMA2-Chat 70B 上为 2.7~3.5 倍。EAGLE-3:最高 6.5 倍 |
MTP(mtp 等 |
模型原本自带的多 Token 预测头 | 拥有 MTP 的模型(DeepSeek-V3、Qwen3.5 等) | 高 | |
草案模型(draft_model) |
相同词表的小模型 | 小模型 | 高 |
通过单个 JSON 提供设置。
vllm serve <모델> --speculative-config '{"method":"ngram","num_speculative_tokens":4,"prompt_lookup_min":2,"prompt_lookup_max":5}'
n-gram 的 prompt_lookup_max·min 是要查找的 Token 序列长度范围,如果都省略则为 5。在 0.32.0 中,Model Runner V2 引入了一个可变长度的 GPU n-gram 建议生成器。在 0.31.0 中, ngram_gpu 已经是一个选项,但在实测中,这两种方法都发出了警告:“Model Runner V2 尚不支持此方法,因此使用 V1 执行器”。CPU 版的 ngram 还发出了“关闭异步调度”的警告。
有些功能无法同时使用。在 0.32.0 文档的兼容性表中,推测解码不能与 LoRA、池化模型、提示词嵌入输入一起使用,并且日志中打印了警告,提示 min_p 和 logit_bias 将被忽略。
3. 直接实测
方法
- 环境:一张 8GB 级笔记本 GPU(Ada 架构)、vLLM 0.31.0、Qwen3-Reranker-0.6B(bf16)。
- 任务集。全部输出 256 个 Token,
ignore_eos.- 复制:提供一段手写的英文段落和一个 Python 函数(约 300 个 Token),要求“原样复制两遍”。贪婪解码。输出与输入几乎相同,是 n-gram 最匹配的情况。
- 连词:提供由 30 个随机连接的单词组成的 200 个单词,并要求继续编写。贪婪解码。该模型倾向于重复相同的话,输出经常重写输入中的单词。
- 随机输出:从整个词表中随机抽取 200 个 Token,以温度 1.0 进行生成。预计重叠度最低的情况。使用相同的随机种子,以便即使服务器不同也能收到相同的提示词。
- 服务器:默认(无推测)、n-gram 建议 2、4、8 个,GPU n-gram 建议 4 个。查找长度 2~5。
- 重复:每个条件四批(第一批预热),高并发为三批。接受率通过批次前后的
vllm:spec_decode_num_accepted_tokens_total和..._draft_tokens_total的差值来计算。
结果 1. 单独使用:复制时达到四到六倍
| 任务(并发 1) | 默认 | n-gram k=2 | n-gram k=4 | n-gram k=8 | GPU n-gram k=4 |
|---|---|---|---|---|---|
| 复制,tok/s | 176.4 | 427.5(2.4倍) | 704.1(4.0倍) | 1,117.0(6.3倍) | 669.5(3.8倍) |
| 复制,接受率 | 97.7% | 99.0% | 95.8% | 95.3% | |
| 连词,tok/s | 175.6 | 524.7(3.0倍) | 515.8(2.9倍) | ||
| 连词,接受率 | 90.8% | 67.9% |
k=4 分别两次独立启动服务器进行测量(692.6、704.1 tok/s),给出了几乎相同的值。在复制中将建议增加到 8 个时,8 个草案中有平均 7.7 个是正确的,大模型附加的 1 个 Token 使得一步确定了约 8.7 个 Token。然而,吞吐量不是 8.7 倍,而是 6.3 倍。这意味着同时验证 9 个 Token 的步骤比常规步骤(5.7ms)长约 1.4 倍(7.8ms)。即使读取权重只有一次,如果要验证的 Token 增加,计算和注意力机制也会增加。
“连词”之所以也快了三倍,是因为该模型会重复相同的单词(例如: signal river meadow signal river meadow …)。在一般的对话模型中,可能不会有这样的匹配度。
结果 2. N-gram 随机输出:因提示词而异
温度为 1.0 的随机输出在不同提示词之间的结果差异很大,按批次列出(并发 1,tok/s)。
| 提示词 | 默认 | k=2 | k=4(接受) | k=8 |
|---|---|---|---|---|
| 1 | 171.4 | 242.4 | 237.6(113/430) | 397.6 |
| 2 | 171.3 | 384.0 | 596.5(202/208) | 914.2 |
| 3 | 171.4 | 149.2 | 153.6(22/175) | 139.9 |
- 提示词 2 尽管是随机提示词,但模型很快开始重复相同的话,接受率为 97%。
- 提示词 3 在所有 k 下都比默认慢(-13%、-10%、-18%)。 在 k=4 时,175 个建议中只有 22 个正确。不正确的草案也会使验证步骤变重,查找 n-gram 也需要时间。建议越多(k=8),损失越大。
结果 3. 提高并发会减少收益,随机输出则会导致损失
| 任务 | 并发 | 默认 tok/s | n-gram k=4 tok/s | 比例 | 接受率 |
|---|---|---|---|---|---|
| 复制 | 8 | 1,124.6 | 2,860.6 | 2.54 | 97.1% |
| 复制 | 32 | 2,868.7 | 4,042.9 | 1.41 | 83.4% |
| 连词 | 8 | 1,089.7 | 2,478.3 | 2.27 | 92.1% |
| 随机单词输入,负载测试(与第二篇条件相同) | 16 | 1,683.1 | 2,436.5 | 1.45 | |
| 随机单词输入,负载测试 | 64 | 2,899.3 | 3,267.8 | 1.13 | |
| 随机输出 | 8 | 1,072.0 | 950.4 | 0.89 | 58.2% |
| 随机输出 | 32 | 2,590.8 | 2,239.8 | 0.86 | 51.4% |
当批次变大时,GPU 已经很忙,验证的 Token 增加多少,步骤就会变长多少。即使是接受率高的复制,在并发 32 时收益也降至 1.41 倍,而接受率约为一半的随机输出在并发 8 和 32 时损失了 11~14%。文档中“高请求率下收益会减少”的说明在数字中得到了体现。
结果 4. 输出与成本
- 贪婪输出的一致性:通过贪婪解码使用 12 个固定提示词(复制 6 个,连词 6 个)分别生成 128 个 Token,n-gram k=4 服务器的输出与默认服务器有 10 个在字面上完全相同,2 个连词不同。文档指出,推测解码在算法上没有损失,但由于验证步骤同时计算多个 Token 而产生的浮点数差异,输出可能会有所不同。实测结果与该警告相符。
- KV 缓存槽:推测解码服务器的 KV 缓存槽从 40,208 个 Token 减少了 23% 至 30,832 个 Token。伴随着相同的警告(回退到 V1 执行器),内存测量结果似乎发生了变化,原因未确认。如果服务器的 KV 内存紧缺,则必须在启用前检查这一行。
- 启动时间:推测解码服务器准备就绪花费了 78 秒和 96 秒,比匹配了编译缓存的默认服务器(约 32 秒)要慢。
- 各位置的接受情况:
vllm:spec_decode_num_accepted_tokens_per_pos_total单独计算了草案中第几个 Token 是正确的。在 k=4 服务器的总体记录中,从第一到第四分别为 84.2%、79.4%、77.0%、74.7%,平均每步确定 4.15 个 Token。这种越往后越下降的曲线成了选择 k 的依据。
3-1. 2026-10-27 重新测定:对话模型与 0.32.0
先前的测量使用的是会重复相同话语的重排序模型,这对 n-gram 有利。使用对话型 Qwen3-0.6B (bf16) 和 vLLM 0.32.0 进行了重新测量。任务有四个。
- 复制:与前面相同(原始提示词、贪婪、固定 256 个 Token)。
- 返回代码: 聊天形式:「在这个 Python 函数中,将变量 budget 替换为 token_budget,仅以代码块返回整个函数」。贪婪,自然停止。
- 解释: 「为什么长提示词会拖慢共享语言模型服务器的其他用户,分为简短的三段」。贪婪,自然停止。这是一个很少需要重复输入的任务。
- 随机输出: 与前同(200 个随机 token,温度 1.0)。
| 任务 | 并发 | 基础 tok/s | n-gram k=4 tok/s | 比例 | 接受率 |
|---|---|---|---|---|---|
| 复制 | 1 | 176.3 | 656.0 | 3.72 | 87.3% |
| 返回代码 | 1 | 177.7 | 544.2 | 3.06 | 69.7% |
| 返回代码 | 8 | 1,288.6 | 3,252.8 | 2.52 | 69.7% |
| 解释 | 1 | 178.6 | 173.9 | 0.97 | 3.0% |
| 解释 | 8 | 1,163.5 | 1,141.5 | 0.98 | 3.6% |
| 随机输出 | 1 | 171.9 | 197.3 | 1.15 | 13.0% |
| 随机输出 | 8 | 1,074.7 | 961.9 | 0.90 | 18.0% |
- 在自由发挥的回答中,n-gram 几乎没有匹配上。 解释任务的接受率为 3%,吞吐量下降了 3%。损失较小是因为如果没有找到匹配的 n-gram,许多步骤不会生成草稿(1,188 个建议,远少于重排模型的随机输出)。
- 返回代码任务的速度快了三倍。 不过这个 0.6B 模型没有听从更改名称的指令,而是直接原封不动地返回了函数。因此该数值属于「几乎完全复制的输出」的情况。如果是实际修改了几行的输出,由于每次修改的地方草稿都会出错,收益会比这更小(未实测)。
- 贪婪输出的全部 12 个结果与基础服务器完全逐字相同。 在 0.31.0 和重排模型中,12 个里面有 10 个相同。
- 在 0.32.0 中,KV 显存几乎没有减少。 在 0.31.0 中,投机解码服务器的 KV 减少了 23%,并出现了「正在退回 V1 执行器 (V1 runner)」的警告。0.32.0 的日志中打印了「Using V2 Model Runner」,KV 仅从 38,224 个 token 减少到 37,456 个 token,降幅仅为 2%。推测前面未确认的 23% 下降与退回到 V1 执行器有关。「关闭异步调度」的警告在 0.32.0 中依然存在。
4. 何时开启
- 输出会重复输入的任务(代码修改、文档校对、摘要中的引用原文、Agent 的重复调用)仅靠 n-gram 就能获得巨大收益。无需准备工作,可直接开启。
- 若要在通用对话中降低响应延迟 则适合基于模型的方法,如 EAGLE 和 MTP。必须拥有针对该模型训练好的草稿头(未实测)。
- 在以吞吐量为目标的的高并发服务器上,收益会减少,如果接受率低甚至会造成损失。开启前后必须在实际负载下测量吞吐量。0.32.0 的动态投机解码等根据负载调整建议长度的功能正是针对此问题(未实测)。
- 如果已经开启,请将
vllm:spec_decode_num_accepted_tokens_total ÷ vllm:spec_decode_num_draft_tokens_total放在仪表盘上,并通过按位置接受来调整 k。
5. 未能确认的事项
- EAGLE、EAGLE-3、MTP、草稿模型和 suffix 需要重新获取草稿权重或
arctic-inference软件包,因此未进行实测。 - 通用对话模型的 n-gram 接受率仅在 3.1 节中通过一个 0.6B 模型进行了测量。实际修改几行的代码编辑输出未进行实测。
- 0.31.0 中投机解码服务器的 KV 显存减少 23% 的原因,仅推测与退回到 V1 执行器有关,未能最终确认(0.32.0 中降幅为 2%)。
参考资料
- vLLM 文档,Speculative Decoding、N-Gram、Suffix Decoding、EAGLE(0.31.0 与 0.32.0 相同):https://docs.vllm.ai/en/latest/features/speculative_decoding/
- Leviathan 等,「Fast Inference from Transformers via Speculative Decoding」,ICML 2023. https://arxiv.org/abs/2211.17192
- Chen 等,「Accelerating Large Language Model Decoding with Speculative Sampling」,2023. https://arxiv.org/abs/2302.01318
- Li 等,「EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty」,ICML 2024. https://arxiv.org/abs/2401.15077
- Li 等,「EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test」,2025. https://arxiv.org/abs/2503.01840
- Oliaro 等,「SuffixDecoding: Extreme Speculative Decoding for Emerging AI Applications」,2024. https://arxiv.org/abs/2411.04975
- Saxena,「Prompt Lookup Decoding」,2023. https://github.com/apoorvumang/prompt-lookup-decoding