一篇读懂投机解码:大模型推理的「先猜后验」

大模型生成慢,根因不是算力不够,而是自回归解码的串行性:token 只能一个一个往外蹦。投机解码(Speculative Decoding)用一个反直觉的思路打破这条铁律——让小模型先「猜」好几个 token,大模型一次前向并行「阅卷」,再靠一种修正过的拒绝采样保证:输出分布与原模型完全一致,一个字都不用改。这项 2022 年底发表、ICML 2023 口头报告的技术,如今已是 vLLM、SGLang 等推理引擎的生产标配,最高能把解码加速 6 倍以上。本文把它的工作原理、背后的数学、三代草稿方案和工程边界一次讲透。

慢的根源:解码是内存带宽问题

先算一笔账。一个 70 亿参数的模型以 BF16 存放,权重大约占 14 GB;解码阶段每生成一个 token,都要把这份权重从头到尾过一遍。GPU 每秒能执行上百亿次浮点运算,但 HBM 显存的读取带宽只有每秒几 TB——一次前向的计算量对算力来说是小菜一碟,瓶颈在「把权重从显存搬进计算单元」这件事上。

Google Research 在回顾博客里把这一点讲得很直白:硬件每秒可执行数百亿次操作,但每个字节读取只对应少量运算,存在大量闲置算力。也就是说,验证 1 个 token 和验证 8 个 token,前向耗时几乎一样——因为注意力与 MLP 的并行维度本来就能覆盖序列位置,多个 token 的 logits 是「顺手」一起算出来的。这套被闲置的并行度,就是投机解码要白捡的便宜。

顺带解释一个高频疑问:为什么不能让大模型直接一次输出多个 token?因为 softmax 采样是逐位置的联合分布,模型本身没有任何机制保证「跳着」生成仍然合法。想并行,就得有人先把候选猜出来——这就引出了草稿模型。

核心思想:小模型起草,大模型阅卷

投机解码的循环只有四步:

flowchart TD
    A[草稿模型快速串行生成 K 个候选 token] --> B[目标模型一次前向并行验证 K+1 个位置]
    B --> C[逐个位置接受或拒绝]
    C --> D[全部接受:产出 K+1 个 token 进入下一轮]
    C --> E[某个位置被拒:丢弃它之后的候选]
    E --> F[从修正分布重采样一个 token 补位]
    F --> G[带上已接受的前缀进入下一轮]
    G --> A
    D --> A

直觉基础是一条朴素的经验:生成文本时,大部分 token 是「容易的」。代码里的语法结构、模板化的搭配、成语的后半截,小模型也猜得八九不离十;真正需要大模型能力的只是少数「难 token」。Leviathan 等人在原始论文里的表述是:难的语言建模任务中常含有可被更高效模型近似处理的简单子任务。草稿模型只负责把「容易的部分」先写出来,大模型把验证多个 token 压缩进一次前向,串行链条被大幅缩短。

用贪心解码(greedy)时这套思路早就有人做过——2018 年就有先猜后验的先行工作(arXiv:1811.03115):草稿猜出候选,大模型验一遍,不对就回退。麻烦出在采样温度大于 0 的场景:朴素地「猜对就收」会改变输出分布。Google 的博客举过一个极端例子:若两个模型都输出 1 到 100 的均匀分布,朴素投机执行平均每 100 次才接受 1 次——小模型的每次猜测几乎都是大模型「没想说的」。要让采样解码也能加速,数学上必须先解决分布不变的问题。

修正拒绝采样:把分布「拉回来」的数学

这是整件事最优雅的部分,核心只有两行公式。设目标模型(大模型)在某位置的分布为 p,草稿模型(小模型)的分布为 q,草稿给出候选 token x:

  • 以概率 min(1, p(x)/q(x)) 接受该 token;
  • 若拒绝,则从残差分布 max(0, p - q) 归一化后重采样一个 token 补位。

直觉上,q 高估(比 p 更偏爱)的 token 更容易被拒绝,拒绝后补采样的正是大模型比小模型更想要的那部分概率质量。两支合起来,最终分布恰好还原成 p:

def verify(p, q, x):
    """对一个草稿 token 做投机采样。p、q 是该位置的概率分布,x 是草稿 token。"""
    if random.random() < min(1.0, p[x] / q[x]):
        return x, None                              # 接受:草稿猜中了
    residual = torch.clamp(p - q, min=0)            # 残差分布 max(0, p - q)
    residual = residual / residual.sum()
    return None, torch.multinomial(residual, 1)     # 拒绝:从残差重采样补位

证明只需要一行全概率公式:最终取到 x 的概率 = 接受分支 q(x) · min(1, p(x)/q(x)) + 拒绝分支 residual(x) · 拒绝概率,展开化简后恰好等于 p(x)。论文把它写成定理:对任意草稿模型,投机采样的输出分布与只用大模型完全相同。这意味着它是一种「无损」加速——换 draft 模型、改草稿长度,都只影响速度,不影响生成质量(严格地说,是在硬件数值精度内等价)。

有意思的是这个方案被独立发明了两次:Google 两支团队在 2022 年 11 月与 2023 年 2 月先后发表论文。Leviathan、Kalman、Matias 的版本(arXiv:2211.17192,ICML 2023 Oral)在 11B 的 T5-XXL 上用 60M 的 T5-small 起草,拿到 2 到 3 倍加速;DeepMind 的 Chen 等人(arXiv:2302.01318)称之为 speculative sampling,在 70B 的 Chinchilla 上拿到 2 到 2.5 倍。两篇论文的算法实质相同,如今通常合并简称为「投机解码」。

一轮能赚多少:接受率的算术

投机解码值不值,取决于两个量的博弈:接受率 β(草稿单个 token 被接受的概率)与草稿长度 γ(每轮猜几个)。原论文给出每轮期望产出:

(1 - β^(γ+1)) / (1 - β)

代入几组数字感受一下:

接受率 β 草稿长度 γ 每轮期望产出 token 相比逐 token 生成
0.5 4 约 1.94 几乎白干
0.8 4 约 3.36 赚 3 倍有余
0.9 6 约 5.22 接近猜满全中

规律很清楚:β 过低时投机解码得不偿失——草稿猜三个错两个,验证成本全打水漂。β 高时则应加大 γ,因为「全中」的期望收益随草稿长度指数衰减得很慢。

真实的加速比还要除以成本:一轮耗时 ≈ γ × t_草稿 + t_验证,所以加速比约为 期望产出 × t_验证 / (γ × t_草稿 + t_验证)。草稿模型越小越快收益越大,但越小的模型接受率又越低——多伦多大学 2025 年对自投机方法的刻画把这对矛盾说得很明白:更便宜的草稿意味着更弱的预测、更低的平均接受率,这是一笔绕不开的算力再平衡账。γ 因此成为部署时真正要调的旋钮,不存在放之四海皆准的最优值。

草稿从哪来:三代方案

原始论文直接拿现成小模型当草稿,之后三年,草稿的来源经历了一轮明显的迭代:

代际 代表方法 草稿来源 额外训练 典型加速
独立草稿模型 原始论文(2022) 现成小模型 无 2–3 倍
自投机 Medusa、早期退出(2023–2024) 目标模型自身的多头 / 浅层 需微调 2–3 倍
特征级学习草稿 EAGLE-1/2/3(2024–2025) 目标模型的多层特征 训练草稿头 3–6.5 倍
原生多 token 预测 DeepSeek-V3 MTP(2024 起) 预训练内置的 MTP 头 预训练阶段完成 约 2 倍,可叠加

真正把上限拉开的是 EAGLE 系列。EAGLE-3(微软研究院,2025 年 3 月,arXiv:2503.01840)做了两个关键改动:一是放弃「只看最高层特征」,改用低、中、高三层特征融合——浅层特征编码语法与形态,深层特征编码语义,草稿模型两头都看得见;二是提出 training-time test,训练时就模拟测试时「读取目标模型特征」的行为,解决了训练与推理分布错位的问题。在 Vicuna 系列上最高拿到约 6.5 倍加速,开源实现在 GitHub 的 SafeAILab/EAGLE 仓库,被引用 300 余次,是当前事实上的标杆。

另一条路线是把草稿能力直接训练进主模型:DeepSeek-V3 在预训练阶段附带一个 MTP(Multi-Token Prediction)模块,让它顺手预测「下下一个 token」,推理时这个模块天然就是草稿头;Qwen 系列也训练了类似的 MTP 头。这条路省去了单独维护草稿模型的麻烦,2026 年 9 月 Red Hat 还发布了围绕 FastMTP 头的推理优化指引。两个方向之外,2026 年又出现了把投机解码当作调度问题求解的 DSpark、面向并行场景的 P-EAGLE(AWS,2026 年 3 月)等新工作,赛道仍在快速演化。

工程现状:2026 年生产引擎里怎么开

截至 2026-10-08,主流推理引擎都把投机解码当成一等公民:vLLM 支持以 eagle3 方法挂载社区草稿头,DeepSeek/Qwen 的 MTP 头原生可用(且支持流水线并行);SGLang 自 0.5.x 起把 EAGLE 与 MTP 提升为一级特性;TensorRT-LLM 还提供 N-gram 投机——直接从输入提示词与前文里「抄」草稿,对翻译、摘要、代码续写这类与输入高度重叠的任务意外地好用。

以 vLLM 为例,开 EAGLE-3 大致是给启动命令加一段投机配置(以官方文档为准):

vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --speculative-config '{"method": "eagle3", "model": "yuhuili/EAGLE3-LLaMA3.1-Instruct-8B", "num_speculative_tokens": 4}'

几个实操要点:num_speculative_tokens 就是前文的 γ,从 3 到 5 试起,观察实际吞吐再调;挂 EAGLE 草稿头需要额外几百 MB 显存与少量计算,小显存机器要留意;MTP 路线则要求模型本身带 MTP 头(DeepSeek/Qwen 系列可用),好处是不用另找草稿模型。

边界与代价:什么时候别开

投机解码不是免费的,五类场景要掂量:

  • 高并发批次:batch 拉满时 GPU 本来就饱和,验证多出来的 token 会挤占正常请求的算力,总吞吐反而下降——2026 年 4 月 vLLM 社区就有开启 EAGLE-3 后首 token 延迟明显回退的 issue。它最适合 batch 小、延迟敏感的场景(本地部署、Agent 单会话、交互式应用)。
  • 首 token 延迟:草稿阶段是串行的,首 token 时间(TTFT)可能不降反升,对「第一响应」敏感的产品要单独压测。
  • 接受率随领域波动:代码、结构化文本、翻译这类「答案相对确定」的任务接受率高;自由创作、头脑风暴类任务接受率明显走低,收益随之缩水。
  • 草稿成本与接受率的跷跷板:换更大的草稿模型提 β,草稿开销也涨;换更小的则 β 掉。最优解依赖模型对、任务、硬件三者,没有通用配置。
  • 「分布不变」的精确边界:数学保证在数值精度内成立,且保证的是分布一致而非贪心意义上的逐字一致(greedy 模式下才是逐字相同)。对质量评估严苛的场景,仍应按常规流程重跑评测。

小结

投机解码是一条难得的「免费午餐」:在「解码受内存带宽限制」与「自回归必须串行」这两个约束下,它用闲置算力换带宽时间,再用一小段拒绝采样数学把质量风险归零。它的三代演进——独立草稿模型、自投机、特征级草稿头——本质都是在「草稿便宜」与「猜得准」之间找更好的平衡点。判断一个推理栈是否成熟,投机解码的支持完备度是个不错的参考指标;而在它继续演化的同时,记住那条底线:无论草稿怎么猜,读者拿到的都必须是大模型的分布——这正是这项技术从论文走进每台推理服务器的原因。

参考资料

← 返回资讯列表

读者留言

COMMENTS 暂无
仅本站原创文章开放留言 · 请勿留下手机号、邮箱等个人信息

还没有留言,来说第一句?