Tech Analysis · 2026-06-02

Speculative Decoding:投机解码的真实收益、校正采样与生产边界

Mohit 的长文适合入门:用“小模型先猜、大模型验收”解释了为什么 LLM decode 可以被加速。但真正决定这项技术是否严谨、是否能上生产的,不是“猜中 top-1”这个故事,而是 acceptance / correction sampling 是否保持目标分布、draft 成本是否低于节省下来的 target 步数,以及调度、KV cache、batch size 和采样温度是否允许收益落到 wall-clock。

2-3x原始 Google 论文在 T5-XXL 翻译/摘要任务上的加速区间。
2-2.5xDeepMind speculative sampling 在 70B Chinchilla 分布式设置中的报告加速。
Lossless理论目标是保持 target model 输出分布,而不是换一个更快但有偏的近似解码器。
条件收益低 batch、memory-bound、draft 高接受率、长 decode 更容易受益。

核心判断

投机解码的本质不是“让小模型替大模型生成”,而是把 autoregressive decode 中最难并行的串行 token 依赖,改写成“便宜 proposal + 昂贵 verifier 的批量验收”。它只有在不改变目标分布的前提下才是 inference acceleration;一旦接受规则变成简单 top-1 match、typical acceptance 或启发式阈值,就要重新说明质量和分布偏差。

关键 insight:投机解码真正要优化的不是单 token FLOPs,而是每个可交付 token 需要读多少次 target model 权重。现代 GPU/TPU 在 decode 阶段常常受 HBM 读权重和 KV cache 访问限制;如果一次 target forward 能并行验证多个 draft token,就可能用相近的权重读取成本推进多个 token。

这也解释了为什么 Mohit 文中“验证比生成便宜”的说法需要改成更精确的系统表述:验证不是数学上免费,也不只是“一次 matmul”。target model 仍然要对 prefix + draft positions 做 forward,draft tree 还会增加 attention、activation 和 KV 管理成本。它便宜的地方在于把多个候选位置合并进一次 target 调用,利用硬件并行度摊薄原本逐 token 的串行读权重成本。

问题背景:decode 为什么慢

LLM 推理通常分为 prefill 和 decode。Prefill 处理完整 prompt,天然能并行;decode 每一步都依赖上一步生成的 token,天然串行。投机解码只主要解决 decode 阶段的串行瓶颈,不会神奇降低长 prompt 的首 token 延迟。

Prefill

输入 prompt 已知,Transformer 可以一次处理多个位置。瓶颈通常是长上下文 attention、prompt 长度、batch packing 和首 token SLO。

Decode

输出 token 未知,第 \(t+1\) 个 token 取决于第 \(t\) 个 token。传统解码每生成一个 token 就要重新调用 target model。

投机解码的可乘收益来自两个观察:第一,很多 token 是容易预测的,例如格式化文本、代码模板、重复片段、常见短语;第二,大模型 decode 在很多硬件上不是算力完全饱和,而是 memory-bound。于是可以用小模型或轻量 head 预先提出几个 token,再让 target model 批量检查。

机制拆解:draft / verify / accept

最朴素的流程可以看成四步。这个框架足够解释 Mohit 原文,也足够承载 EAGLE、Medusa、MTP、NGRAM 等变体。

1 Draft

便宜 proposer 基于当前 prefix 生成 \(K\) 个候选 token,可能是小模型、EAGLE head、Medusa heads、MTP head 或 n-gram cache。

2 Verify

target model 接收 prefix 加 draft tokens,一次 forward 得到每个候选位置下的目标分布。

3 Accept

根据 greedy 或 sampling 接受规则保留若干 draft token。sampling 场景下通常不是简单 top-1 match。

4 Correct

若某处拒绝,从拒绝点用 target 分布或 residual 分布补一个 token,保证每轮至少推进。

如果是 greedy decoding,检查 draft token 是否等于 target argmax 可以作为直观近似。但现实服务经常用 temperature、top-p、top-k、repetition penalty 等采样策略,这时“匹配 target top-1 才接受”既过于保守,也不能代表无偏采样。

采样校正:评论区指出的关键缺口

SPThole 在回复里说 Mohit 漏了 correction 和 sampling-based speculative decoding,这个提醒是实质性的。因为投机解码最重要的理论卖点是“保持 target model 分布”,而不是“多数时候猜对”。

设 draft proposer 的分布为 \(q(x)\),target model 的分布为 \(p(x)\)。若 draft 采样出 token \(x\),标准 modified rejection sampling 的核心接受概率可以写成:

\[ a(x)=\min\left(1,\frac{p(x)}{q(x)}\right) \]

直觉是:如果 draft 对某个 token 的概率低于 target,说明它没有过度提出,可以接受;如果 draft 对某个 token 的概率高于 target,就只能按比例接受,避免输出分布偏向 draft。若拒绝,则从 residual 分布中补采样:

\[ r(x)=\frac{\max(p(x)-q(x),0)}{\sum_y \max(p(y)-q(y),0)} \]

这一步就是“correction”。没有 correction,拒绝后的 token 很容易变成启发式 fallback;没有 sampling-based acceptance,温度采样下的投机解码就会退化为“看起来更快,但输出分布可能变了”的近似系统。

对 Mohit 原文的校正:“如果 draft token 在 target top-1 中就接受”只适合解释 greedy 或近似实现,不是完整 speculative sampling。严谨版本需要用 target/draft 概率比来做接受/拒绝,并在拒绝时从 residual 分布补 token。

方法谱系:从小模型到 self-speculation

所有变体都在回答同一个工程问题:怎样以最低额外成本提出更容易被 target 接受的候选 token。

方法 Draft 来源 优势 代价与边界
Standalone draft model 同家族小模型,例如 7B target 配 1.5B/2B draft。 概念简单,兼容性强,便于直接试验。 需要额外模型权重和 KV cache;draft 太弱接受率低,draft 太强又吞掉收益。
EAGLE / EAGLE-2 / EAGLE-3 围绕 target hidden states 或多层特征训练的 draft head / draft model。 更贴近 target 表征,接受率通常更高;动态 draft tree 能把不确定性分配给更有希望的分支。 需要为特定 target 训练和部署 draft;特征抽取、draft tree、CUDA graph 和验证路径都增加系统复杂度。
Medusa 在 target backbone 上加多个未来 token prediction heads。 避免独立 draft 模型,部署形态更集中;tree attention 可并行验证多候选。 Medusa heads 需要训练;多步预测基于同一表示,越往后越难准确。
MTP 模型原生 multi-token prediction heads。 如果 checkpoint 已带 MTP,额外部署成本低;适合被 serving engine 直接接入 speculative workflow。 依赖目标模型训练时是否支持;不同模型的 head 语义和配置差异较大。
NGRAM / suffix / prompt lookup 从当前 prompt、历史输出或全局 suffix cache 中取重复片段。 无额外 draft model,内存和部署成本较低;代码、模板化输出、重复上下文场景有效。 依赖文本重复性;创意写作、开放问答和高温采样中收益有限。

SGLang 文档把 EAGLE-3、EAGLE-2、MTP、DFLASH、standalone draft 和 NGRAM 都归入 speculative decoding 配置面;vLLM 文档也把 EAGLE、MTP、draft model、PARD、MLP、N-Gram、Suffix 等列为选择项。这说明“投机解码”已经从单一论文算法扩展成 serving engine 的一类 proposer/verifier 插件接口。

生产边界:什么时候真能快

投机解码不是无条件加速。正确评估要看每个 accepted token 的总成本,而不是只看理论 \(K\) 个 draft token。

低 batch 更容易赢

单用户、低 QPS、memory-bound decode 场景下,target model 原本并行度不足,投机验证更容易填满硬件。

高 batch 可能稀释收益

连续批处理已经把 GPU 填满时,再加入 draft/verify 子流程可能增加调度和 cache 压力。

长输出更有空间

短回答只有少量 decode token,draft warmup、验证、调度、同步开销可能覆盖收益。

采样越随机越难猜

温度高、top-p 宽、创意任务多样性强时,draft 接受率下降,校正采样更频繁。

KV cache 是硬约束

独立 draft model 需要额外 KV;tree-based verification 还会保存多分支状态,直接影响最大 batch 和上下文长度。

监控要按 token 归因

上线时至少记录 acceptance rate、draft latency、verify latency、rejected depth、OOM、batch size 和 per-token latency。

落地判断:如果业务目标是降低单次对话的可感知延迟,投机解码值得优先试;如果目标是高 QPS 批量吞吐,先确认 continuous batching、prefix caching、quantization、kernel fusion 和模型路由是否已经做满,再评估投机解码的边际收益。

术语解释

Target model

最终要保持输出分布的大模型。投机解码的正确性目标是输出等价于直接从 target model 解码。

Draft model / proposer

提出候选 token 的便宜机制。它可以是小模型、轻量 head、n-gram cache 或自定义 proposer。

Acceptance rate

draft token 被 target 接受的比例。它越高,target 调用摊薄到每个输出 token 的成本越低。

Correction sampling

拒绝 draft token 后,从 residual 分布补采样 token 的过程,用来保持 target 输出分布。

Tree verification

一次不只验证线性 token 序列,而是验证多个候选分支。它提高覆盖率,但增加显存和调度复杂度。

Lossless acceleration

指算法在理论上不改变 target model 输出分布。硬件数值误差、batch 非确定性和启发式接受规则仍可能带来差异。

边界与风险

Mohit 的文章把核心直觉讲得清楚,但对 sampling correctness、target/draft 概率比、拒绝后 residual correction、production scheduler 的复杂度讲得不够。这并不削弱文章作为入门材料的价值,但如果把它直接当生产设计说明,会漏掉最重要的正确性门槛。

  • 理论边界:lossless guarantee 依赖正确的 rejection/correction sampler;typical acceptance 或阈值接受可能是高质量近似,但不等价于严格无偏。
  • 系统边界:draft model、draft tree、CUDA graph、batch expansion 和 KV cache 都会占显存,OOM 不只是模型大小问题。
  • 评测边界:不要只报告 tokens/s。应该同时报告 TTFT、TPOT、p95 latency、接受率、输出长度分布、batch size、采样参数和质量回归。
  • 业务边界:对短输出、高 batch、强随机采样、低重复文本,投机解码可能只有小收益甚至负收益。

证据边界与资料索引

本文基于 Mohit 的 X Article、X 回复区补充、作者资料、Google Research 回顾、arXiv 论文元数据,以及 SGLang / vLLM 当前文档交叉梳理。X 原帖只有短链,完整内容来自 X Article;评论区只有一条实质技术补充。本文没有复现实测 benchmark,所有速度数字都作为来源报告值使用。

Speculative Decoding LLM Inference Serving EAGLE Medusa vLLM SGLang