Speculative Decoding: Performance or Illusion?
速读卡片 (TL;DR)
一句话:把过去三年所有 SD 论文的"惊艳数字"放进 vLLM v0.10.1.1 + H100 + 真实 batch 重新跑一遍,系统性地发现:verification 占 42%–95% 的执行时间、acceptance length 在 token 位置 / request / dataset 三个维度都剧烈漂移,因此 paper-reported speedup 在生产部署里大幅缩水。
立场:这是一篇审计 / 测量论文,不是方法论文。它给 EAGLE-3 / DFlash / MARS 这类报 "2.x×" 的工作泼冷水——并指出真正没人攻克的问题是"避免 verify 注定要被拒的 token"。
1 · 动机:为什么"生产级 benchmarking"比新 SD 方法更重要
1.1 历史脉络:从 Leviathan-2023 到今天的论文通胀
SD 自 2023 年 Leviathan 提出后,论文呈指数增长。EAGLE / EAGLE-2 / EAGLE-3 / Medusa / Lookahead / Sequoia / DistillSpec / SpecInfer / DFlash / MARS……每一篇都报一组漂亮的 "2.x× speedup",且常常基于同一套不真实的实验条件:
- batch size = 1,因为这是 SD 收益最大、最容易出好看数字的工况;
- research prototype(自己写的小推理框架),没有 CUDA Graph、没有 continuous batching、没有 chunked prefill,baseline 自己就跑得很慢——SD 的相对收益就被放大;
- 报 average latency 或 dataset-level acceptance rate,把变量平均掉,看不见 per-position / per-request 的剧烈方差。
结果就是:论文里 "2.5× over baseline" 的 EAGLE-3,真到 vLLM serving 集群上跑 batch=128,可能只剩 1.2×;某些 batch / dataset 组合下甚至比不上 no-SD。这正是这篇论文要揭穿的"幻觉"。
1.2 别人为什么没干这事——做生产级 benchmark 的工程门槛
把 SD 集成进 vLLM / SGLang / TensorRT-LLM 这类生产引擎,工程量非常大:要适配 PagedAttention 的 KV 调度、要让 draft 模型 / draft head 走 CUDA Graph、要处理 chunked prefill 中途加入的请求、要在 continuous batching 调度器里区分 verify token vs prefill token。绝大多数学术组没有这个工程储备,只能在 prototype 上跑数字。
对比表(为什么"prototype 数字"不能信):
| 评测设置 | 典型问题 | 对 SD 收益的偏置方向 |
|---|---|---|
| Prototype + bs=1 | 无 CUDA Graph / 无 cont batching | 乐观偏 30–80% |
| vLLM + bs=1 | 系统已优化但 batch 不真实 | 乐观偏 20–40% |
| vLLM + bs=128 + 真实 prompt | 本文做的 | 基本可信 |
| 仅报 dataset 平均 | 掩盖 per-position 方差 | 掩盖 robustness 问题 |
| 仅报 acceptance rate | 不等于 wall-time speedup | 掩盖 c (drafting cost) 项 |
1.3 为什么这事不平凡
"生产级 SD benchmark" 听起来像是脏活,但有三个非平凡之处:
- 同一组 prompt + greedy 都得不到一致输出——因为 vLLM 在不同 batch size 下走不同 kernel,FP16 累加顺序不同,生成长度都会变(论文 Tab.1 给出 mean±std,差异在 ±5% 量级)。这意味着 "lossless SD" 这个假设在生产里不严格成立,baseline 也漂移。论文用 token throughput 而不是 wall-time per request 作为指标,就是为了消解这点。
- compute-bound 拐点:bs 小时系统 memory-bound,SD 有大量空闲 FLOPS 给 verification,几乎免费;bs 一大、target 模型一大,verification 的多 token forward 跟 baseline 的 1 token forward 时间不再相等(公式假设崩),SD 反而拖慢。这个拐点在哪、跟模型规模/TP 大小怎么扩展,以前没人系统测过。
- 三层方差(within request / across requests / across datasets)是策略意义的关键:它说明 "用一种 SD 通吃" 是次优的——存在一个理论上界 4.9×,而当前最强方法只到 ~2×。
2 · 背景速查
2.1 术语与缩写
| 术语 | 含义 | 本文里的具体值/约定 |
|---|---|---|
| target model | 大模型 / verifier | Llama3.1-8B / Llama3-70B / Qwen3-8B / GLM-4.5-Air-106B |
| draft method | 提议 token 的方式 | n-gram / EAGLE / EAGLE-3 / Draft-Model / MTP |
| k | 每步提议 token 数 | 默认 3,n-gram 也测 5;tree 测 6/21 |
| α | token acceptance rate | 0.30–0.92 视方法/dataset |
| c | drafting/target 单 forward 时间比 | n-gram ≈ 0;EAGLE ≈ 0.05–0.20;Draft-Model 8B 配 0.6B ≈ 0.375 |
| acceptance length | 每步实际通过 verify 的 token 数 (含 bonus token) | 2–8,reasoning 长尾可到 15+ |
| MTP | Multi-Token Prediction (DeepSeek-V3 / GLM-4.5) | co-trained 副 head,不需 post-hoc fine-tune |
| chain vs tree verify | k 个串成链 vs 多分支树 | tree 仅在 bs=1 略胜,bs≥64 全面崩盘 |
2.2 SD 速度公式回顾
这是 Leviathan et al. 2023 给的封闭式。两个核心变量:
- α (acceptance rate):越高越好,但提高 α 一般需要更聪明的 draft → c 上升;
- c (drafting cost ratio):相对成本,n-gram 接近 0,Draft-Model 取决于配对。
2.3 vLLM 生产配置
本文所有实验启用 vLLM 默认优化:KV cache 管理 (PagedAttention)、continuous batching、chunked prefill、CUDA Graph;硬件 H100 80GB(8B 单卡 / 70B 与 106B TP=4)。temperature=0,top_p=1,top_k=-1。max gen length 8K(reasoning 32K)。
3 · 实验方法学:测了什么、怎么测
3.1 矩阵规模
| 维度 | 取值 |
|---|---|
| target 模型 | Llama3.1-8B / Llama3-70B / Qwen3-8B / Qwen3-8B-Thinking / GLM-4.5-Air-106B |
| SD 变体 | n-gram(k=3,5) / EAGLE / EAGLE-3 / Draft-Model / MTP / tree (k=6,21) |
| 数据集 | CNN/DailyMail · ShareGPT · InstructCoder · GSM8K · AIME22-24 · GPQA-Main |
| batch size | 1, 8, 16, 32, 64, 128, 512(部分) |
| 引擎 | vLLM v0.10.1.1(tree 用 SGLang v0.5.9) |
3.2 一个棘手细节:同 prompt 不一定生成同输出
论文 Tab.1 给出一个尴尬事实:即便 temperature=0、greedy 解码,把同一组 ShareGPT prompt 在 bs=1 / 8 / 32 / 128 下用 Llama3.1-8B 跑(no SD),平均生成长度分别是 737 / 722 / 674 / 714 (±约 1000)。这不是 SD 引入的,而是 GPU kernel 并行度 + FP16 累加顺序在不同 batch 下不同导致的。引用 He 2025 "Defeating Nondeterminism in LLM Inference"。
3.3 评测指标定义
不用 latency / 不用 acceptance rate / 不用 dataset 平均生成长度。这选择本身就是审计型论文的态度:用一个不易被搞坏的指标。
4 · 主结果:batch size 一动,speedup 立刻塌
4.1 batch size 是 SD 收益的最大杀手
论文 Fig.1 把所有 (model × dataset × method × bs) 摆出来,核心 trend:
- Llama3.1-8B / GSM8K / EAGLE:1.73× → 1.21× 当 bs 从 1 到 128;
- Llama3.1-8B / ShareGPT / EAGLE:1.68× → 1.61× (bs 1→32),损失 4.3%;
- Llama3-70B / ShareGPT / EAGLE:1.96× → 1.72× (bs 1→32),损失 14.0%。
规模效应:模型越大,SD 收益越早地随 bs 衰减。原因:70B 用 TP=4,单 H100 上的有效 batch 已经更接近 compute-bound,verifying rejected token 的浪费立刻显形。
4.2 哪个方法在哪种条件下赢
| 条件 | 胜者 | 关键 caveat |
|---|---|---|
| 大模型 (70B) + 任意 batch | Draft-Model (Llama-3.2-1B 配 70B,c≈0.125) | 需要现成同词表小模型,KV cache +1.77× (8B 场景) |
| 中模型 (8B) + 任意 batch | EAGLE-3 | Draft-Model 在 8B 时 c=0.375 太贵,反而被 EAGLE-3 / 甚至 n-gram 压 |
| code editing (InstructCoder) | n-gram (k=5) | BLEU-4 > 0.6 时 n-gram 赢 EAGLE 53%–100% |
| reasoning (AIME / GPQA) | EAGLE-3 主导,n-gram 紧随 | n-gram 在长 CoT 末段(写最终答案)崩 |
| bs=1 学术评测 | tree 看起来最好 | bs≥64 全面失效,真实部署不要用 |
| 106B + reasoning | MTP 唯一可行 | 仅前一个 MTP head,position-wise α: 0.92→0.68→0.38 急速衰减 |
5 · 时间分解:verification 才是真正的成本中心
5.1 四阶段拆分
SD 一步分四件事:
- Drafting:n-gram 是 CPU lookup,EAGLE 是 head autoregress k 次,Draft-Model 是 1B 模型 autoregress k 次;
- Verification:target 模型一次 forward k+1 个 token;
- Rejection sampling:从 verify 输出 logits 里采样;
- Other (vLLM overhead):scheduling、KV 管理。
5.2 关键数字
- verification 占比:42%–95%(随 model size, batch size 单调上升);
- drafting 占比:n-gram <2% / EAGLE 12–20% (bs=1) → 3–7% (bs=512) / Draft-Model 8B 配 0.6B 时 47% (bs=1) → 16% (bs=512);
- sampling < 1.7%(可忽略,这是过去几年大家一直忽略 KL-correction overhead 的合理性确认);
- vLLM overhead:3–12%(scheduling,被 batch 摊薄)。
5.3 推论:为什么 verify 是真正的优化空间
如果 acceptance length 是 m(≤k+1),那 verify 跑了 k+1 个 token,其中 k+1−m 是注定要被丢的,这部分 GPU compute 是纯浪费。在 compute-bound 阶段(大 batch),这浪费直接换算成 throughput 损失。论文据此提出:真正的研究方向不是把 acceptance rate 从 80% 提到 85%,而是只 verify "本来就会被接受的 token"。这是 Section 8 的理论上界推演。
5.4 内存开销(顺带)
| 方法 | 静态内存增量 | per-token KV 增量 |
|---|---|---|
| n-gram | 0 | 0(CPU 历史) |
| EAGLE / EAGLE-3 (8B) | +3.1% / +5.3% | +3.1% (+4 KiB) |
| Draft-Model 70B+1B | +1.8% | +10% (320→352 KiB) |
| Draft-Model 8B+0.6B | +7.3% | +77% (144→256 KiB) |
结论:小模型配小 draft 在内存上反而最贵——因为 draft 全模型的多层 KV 都得留着。
6 · acceptance length 的三层方差
SD 论文里通常只报 dataset-level α 或 mean acceptance length。这篇说:那是把所有方差平均掉了。它从三个层级揭露 α 的分布。
6.1 Within a request: token 位置维度
对 reasoning 任务(Qwen3-8B-Thinking on GPQA),把生成位置分成 10 个 bin,看每个 bin 的平均 acceptance length。结果:
- n-gram:短输出(<4K)1.6 → 3.7;长输出(>13K)2.7 → 5.0,越往后越好(局部重复积累),但最末段往往掉——因为模型从 step-by-step CoT 切到写最终答案,无重复可挖。
- EAGLE-3:从 ~2.1 → 5.7,增长更平缓但更稳定。
6.2 Across requests: 同 dataset 内方差
InstructCoder + Llama3-70B 的 per-request 平均 acceptance length(box plot 5–95 percentile):
- EAGLE: 2.7–7.4(窄,std 小)
- n-gram: 1.1–15.0(重尾,std 是 EAGLE 的 2–5×)
- Draft-Model: 5.6–18.3(最长但波动大)
这意味着对 SLA 敏感的服务(比如 chat 场景必须 P99 ≤ 2× P50),n-gram 那个长尾"看起来好"但不可靠。EAGLE 的稳定性可能比 mean 高 10% 更值钱。
6.3 Across datasets: 方法 × 任务的强相互作用
| dataset | EAGLE | n-gram | Draft-Model |
|---|---|---|---|
| InstructCoder | 4.2 | 7.3 | ~10 |
| CNN/DailyMail | 3.1 | 2.5 | ~3.5 |
| ShareGPT | 3.5 | 2.0 | ~5 |
| GSM8K | 4.5 | 2.0 | ~5 |
| AIME / GPQA(reasoning) | 4–6 | 3–5 | — |
这表是论文级 cheat sheet:任务变了,谁赢就变。没有 universal winner。
7 · n-gram 在 InstructCoder 上的"神迹"与 BLEU 解释
令人惊讶的事实:n-gram(零训练、CPU lookup、几乎没 drafting cost)在 InstructCoder 上对 Llama3.1-8B / Qwen3-8B 的 speedup 比 EAGLE / EAGLE-3 还高;对 Llama3.1-8B + bs=1 + n-gram k=5 时,相对 EAGLE 提升 +100%。
7.1 假设与验证
作者假设:code editing 的 prompt-output 局部重复率高,n-gram lookup 命中率高。用 BLEU-4(prompt vs no-SD output)作 overlap 代理量,把 request 按 BLEU 分到 5 个 bin,对每个 bin 算 n-gram-vs-EAGLE 的相对 speedup。
7.2 操作型推论(本文未明说但可推)
routing rule:code editing / refactor / patch generation 走 n-gram(k=5);其它 chat / reasoning 默认 EAGLE-3;reasoning 长 CoT 走 EAGLE-3 + n-gram 联用(下一节)。如果你的服务能根据 task type 路由,可以直接吃这个 free lunch。
8 · 理论上界:Oracle Proposal & Oracle Combine
8.1 Oracle Proposal:消除"verify 注定被拒的 token"
构造:每步用 oracle 知道实际能接受的 m,然后只 propose m 个 token,verify 时全部通过。这等价于消除 wasted verification。
结果(Llama3.1-8B / InstructCoder / n-gram / bs=1):oracle = 2.75×,固定 k=5 = 2.1×,gap 约 30%。bs ↑ 时 gap 拉大——固定-k 曲线下降快,oracle 下降慢。
8.2 Oracle Combine:跨方法择优
把 EAGLE 和 n-gram 并行跑,逐 token 位置选谁的 acceptance length 更长。这是图 11 的红蓝交错图(每个 position 总有一个赢家)的体现。结果:
- InstructCoder:Oracle Combine 在 bs=1 飙到 ~5×(论文 abstract 报的 4.9×);
- ShareGPT / CNN/DailyMail:相对 best fixed 多 ~30–50%;
- GSM8K:几乎没增益(因为 n-gram 在数学步骤里很少长 burst,combine ≈ Eagle)。
8.3 反向论证:为什么不能直接"propose 越多越好"
有人会问:既然 verify 不好预判 accept,那固定 k 大点不好吗?反向看:k 大 → 期望 reject 的 token 多 → verify 浪费的 compute 多 → bs 大时直接拖慢(tree k=21 在 bs=64 跌穿 1× 就是 case)。Oracle 之所以是上界,是因为它同时选对方法 + 选对 k + 全部 accept,三个理想化叠在一起。
9 · 生产场景化算账:一个 H100 集群的具体决策
把上面所有发现塞进一个具体场景。
9.1 场景设定
- 服务类型:多租户 chat assistant,流量混合 = 50% ShareGPT-like + 30% reasoning + 20% code editing;
- 硬件:8× H100 80GB,单节点 TP=4 跑 Llama3-70B-Instruct;
- SLA:P50 TTFT ≤ 200ms,P50 ITL(inter-token-latency)≤ 30ms;
- 负载:稳态 batch 在 32–64 之间。
9.2 套用论文数据 + 公式
| 方案 | 预期 throughput speedup | P99 风险 | 额外成本 |
|---|---|---|---|
| no SD | 1.0×(基线) | 稳 | 0 |
| EAGLE-Llama-70B + chain k=3 | ~1.7×(bs=32 ShareGPT) | 低(per-req std 小) | +1.4% 静态 GPU mem,+1.3% per-token KV;需要 EAGLE checkpoint |
| Draft-Model (Llama3.2-1B) | ~1.85×(bs=32 ShareGPT,胜 EAGLE) | 中(α 重尾) | +1.8% 静态,+10% per-token KV |
| Tree EAGLE k=21 | bs=1 看 2.0×,bs=32 跌至 ~1.3×,bs=64 <1.0× | 高 | 大量额外 verify compute |
| code 路由 → n-gram k=5,其余 → EAGLE | code 段额外 +30%~+75%,整体 ~1.9× | 低(分段) | 需路由层判断 task type |
9.3 一笔每 token 钱
假设 H100 节点 $32/小时,no-SD 70B/TP4 throughput 在 bs=64 大约是 ~1.5K tok/s(论文数量级)。EAGLE 加速 1.7× → ~2.55K tok/s。
EAGLE: $32 / (2550 × 3600) ≈ $3.49 / 1M tok(省 41%)
但若忽略 acceptance 三层方差,直接信论文报的 2.5× 上线,你的 capacity 规划会按 $2.37/1M 算 → 实际跑出来流量打满 → P99 爆 SLA。
9.4 决策口诀(本文蒸馏)
10 · 与同类工作对比:谁的论断挺得住?
| 论文 | 核心论断 | 本文裁决 |
|---|---|---|
| NeMo-RL × EAGLE-3 (NVIDIA) | EAGLE-3 在 RL rollout 给 1.4–1.8× 加速 | 基本可信:RL rollout 通常 bs 中等且场景 ≈ ShareGPT,本文同条件下 EAGLE-3 给 1.5–1.8× 一致 |
| EAGLE-1/2/3 / DFlash 演化 | EAGLE-3 报 2.5×、DFlash 报 2.4× | 乐观偏:这些数字是 bs=1 / prototype 上的。本文 vLLM bs=1 还能见到 1.7–2.0×;bs=64 后腰斩到 1.2–1.4× |
| ReSpec(RL 中的自适应 SD) | 动态调 k 比固定 k 好 | 方向支持:本文 Oracle Proposal 也证明动态 k 才是上界来源;ReSpec 是该 idea 的实例化 |
| Medusa / Lookahead / Sequoia (tree) | tree verification 加速更高 | 仅 bs=1 成立:本文显示 bs ≥ 64 时 tree(k=21) 跌穿 1× |
| Liu 2024 "Optimizing SD for Serving via Goodput" | SD 在大 batch 下可能负收益 | 高度一致:本文给了更系统的实证,bs 与 model size 双轴扫 |
| MTP (DeepSeek-V3 / GLM-4.5) | co-trained head 加速更高 | 部分:106B 上 MTP 给 1.3–1.8×,确实超过 n-gram。但 position-wise α 衰减(0.92→0.68→0.38)说明 single-head 复用是瓶颈 |
11 · 局限 / 个人 take / 待验证问题
局限
- 只测了 Llama-3 / Qwen-3 / GLM-4.5 三个家族;Mistral / DeepSeek-R1 / Gemma 等没覆盖,跨架构 SD 行为可能不同。
- vLLM v0.10.1.1 一个固定版本;tree-verify 用 SGLang 是因为 vLLM 此版 tree path 没优化好——结论"tree 在大 batch 必输"可能对其他引擎不严格成立。
- α 与 acceptance length 的测量定义微妙:作者"每步最多 propose 20 tokens 看实际能 accept 几个",和真正部署里固定 k=3/5 的语义略不同——是 oracle-style 上界估计。
- Oracle Combine 的 4.9× 没扣 EAGLE KV 重建开销(若 method 切换会需要 prefill EAGLE 的 KV)。所以"4.9×" 这个数本身也是上界中的上界。
- 没有 long-context (128K+) prefill-heavy 工况;real chat 的 system prompt 越长,prefix-cache 主导,SD 收益形态可能再变。
个人 take
- 这是 2026 年我读到最有用的一篇 SD 论文,虽然它没提任何新方法。它把整个 SD 学术界的"叙事溢价"打掉一个量级,以后 EAGLE-N+1 必须在 vLLM bs=64 报数才有可信度。
- "verification dominates" 是审计型核心结论,但其推论"propose only what will be accepted"是个开放且具体的研究题目——可以做出一个 lightweight predictor,小规模(几十 M 参数)预测下一段 acceptance length 即可。
- Oracle Combine 给出的 routing 思路,我相信工程上 1–2 季度内会有论文跟进,做"per-position SD selector"。这是接下来值得投注的方向。
- 对一线工程师:这论文的核心价值是给你一份 cheat sheet,能在 review SD 方案时立刻识别哪些数字水分大。
待验证问题
- 本文用 H100 + TP=4。换到 H200 / B200 / GH200 (NVLink-NVSwitch) 后,memory-bound→compute-bound 的拐点 batch size 应该右移多少?是否能让 SD 在更大 batch 也保持高 speedup?
- FP8 / INT4 量化 baseline 下 SD 的相对收益怎么变?直觉上 verify 时间被压缩,SD 优势进一步缩水。
- 如果用 disaggregated prefill/decode (Mooncake / DistServe),decode 阶段 batch 通常远小于 unified——SD 是不是天然在 disagg 框架下更好?
- EAGLE-3 + n-gram 在 reasoning 长 CoT 上的实际 production combine 实现(不依赖 oracle),能否捞回多少?
- 开源 GLM-4.5-Air MTP 只有第一个 head,是否能事后蒸馏出 head 2 / 3 / 4 来恢复 position-wise α 衰减?
- BLEU-4 作为 task-type router 信号是否稳定?有没有 cheap proxy 能在 prefill 阶段就预测?
12 · 应该读什么、应该信什么 (Memory Points)
精读笔记 · 2026-05 · 配套 spec-rl 系列 · 与 01 NeMo-RL · 02 EAGLE evolution · 04 ReSpec 互参