自回归解码是严重访存受限(Memory-Bound)的,GPU 的绝大部分算力处于闲置状态。投机解码(Speculative Decoding)正是把这段闲置算力变现的技术——先用廉价方式猜出未来若干 token,再让大模型用一次并行前向把它们一次性验证掉。本节从加速比的定量分析出发,证明其分布无损性,并依次剖析 Medusa、EAGLE 与 MTP 三代主流实现。
一次标准的解码步骤,要把整个模型的权重从 HBM 搬进片上 SRAM,然后只算出一个 token。以 70B 模型、BF16 权重为例:
单步 Decode 的成本拆解(70B 模型,BF16,H100,batch=1) 权重搬运量 ≈ 140 GB 计算量 ≈ 140 GFLOPs 访存耗时 = 140 GB / 3.35 TB/s ≈ 42 ms ← 瓶颈 计算耗时 = 140 GFLOPs / 990 TFLOPS ≈ 0.14 ms ← 几乎空闲 算术强度 = 140e9 / 140e9 ≈ 2 FLOPs/Byte H100 ridge point ≈ 300 FLOPs/Byte → GPU 有 99% 以上的时间在等内存
记目标模型(target model)为 M_p,其在前缀下的条件分布为 p;草稿模型(draft model)为 M_q,分布为 q。一轮投机解码由两个阶段构成。
Draft 阶段:用 M_q 自回归地生成 γ 个候选 token,同时保留每一步的完整分布(拒绝采样时要用)。
Verify 阶段:把 [x<t, x̃₁, ..., x̃_γ] 一次性送入 M_p。由于因果注意力的性质,这一次前向同时给出了 γ+1 个位置的分布:
注意最后一个分布 p_{γ+1}:它是"假设所有草稿都被接受"之后的下一个 token 分布。这意味着即使 γ 个草稿全部被接受,仍能白送一个 token,即所谓的 bonus token。因此单轮最多产出 γ+1 个 token。
一轮 draft-then-verify(γ = 4)
前缀: "The capital of France is"
Draft (小模型 4 步串行,每步很便宜)
→ [" Paris", ",", " a", " city"]
Verify (大模型 1 次并行前向,5 个位置同时出分布)
位置1 ✓ Paris 位置2 ✓ , 位置3 ✗ a → 拒绝
位置3 重采样 → " which"
位置4、5 丢弃,KV cache 回滚
本轮产出 3 个 token,代价 = 4×T_draft + 1×T_target
Verify 近似免费:一次处理 γ+1 个 token 的前向,耗时应接近处理 1 个 token。在 memory-bound 区间成立,随 batch size 增大逐渐失效。
Draft 足够便宜:记 c = T_draft / T_target 为单步成本比。独立小模型 c ≈ 0.02–0.1;Medusa / EAGLE 这类轻量头 c 可低至 0.01–0.05;n-gram / prompt lookup 则 c ≈ 0。
Draft 足够准:接受率 α 要高。α 与任务强相关——代码、摘要、格式化输出这类低熵任务 α 高;开放式创作、高温采样则 α 低。
定义单步接受率 α = E[min(1, p(x̃)/q(x̃))]。在"各步接受事件独立同分布"这一常用简化假设下,接受的草稿数服从截断几何分布,加上必得的 1 个 token(重采样 token 或 bonus token),单轮产出期望为:
这个量常被称为接受长度 τ(acceptance length),是评价投机解码方法最核心的指标,因为它与具体硬件无关。直觉检查:α → 1 时 τ → γ+1(全接受);α → 0 时 τ → 1(退化为普通解码)。另外 τ 关于 γ 是次线性增长且有上界 1/(1-α),这是"γ 不能无限加大"的根本原因。
单轮墙钟时间为 γ·T_draft + T_target = T_target·(γc + 1),而基线每个 token 耗时 T_target。于是:
代入几组典型值(Leviathan et al., 2023 的经典结果):
| α | c | 最优 γ* | 最优加速比 | 说明 |
|---|---|---|---|---|
| 0.6 | 0.05 | 4 | 1.92× | 草稿质量一般,独立小模型典型值 |
| 0.8 | 0.05 | 9–10 | 3.08× | 优秀草稿(EAGLE 级别) |
| 0.9 | 0.05 | 13–15 | 4.67× | 极强草稿 / 低熵任务 |
| 0.8 | 0.20 | 4 | 1.87× | 草稿模型过大,收益被吃掉一半 |
| 0.8 | 0.01 | 20+ | 4.0× | 近乎免费的草稿头 |
可以读出三条工程结论:
c 的影响巨大:同样 α = 0.8,c 从 0.05 涨到 0.2,加速比从 3.08× 掉到 1.87×。选草稿模型时"小"往往比"准"更重要——这正是 Medusa / EAGLE 用一两层网络而非独立小模型的动机。
γ 存在最优值:τ 有上界而开销线性增长,γ 过大反而变慢。α 越高、c 越小,最优 γ 越大。
投机解码不改变吞吐上限,只改善延迟:它把闲置算力换成 token,总 FLOPs 是增加的(被拒绝的草稿是纯浪费)。
接受事件并非独立:实测中越靠后的草稿 token 接受率越低(草稿模型误差累积)。真实 τ 低于几何分布的预测,最优 γ 也比公式给出的更小。
T_draft 不只是 FLOPs:草稿的 γ 步是串行的小 kernel,launch overhead、采样开销、调度开销都会被放大 γ 倍。CUDA Graph 捕获对投机解码几乎是必需的。
KV cache 管理:被拒绝的位置需要回滚 KV cache。在 PagedAttention 之类的分页系统里这是一次指针操作,代价可忽略;但草稿与目标模型要各维护一套 cache,显存占用增加。
长上下文下的比例漂移:上下文很长时,attention 部分成本随序列长度增长,其在 draft 与 target 之间的比例关系与 MLP 部分不同,c 会随上下文变化。
投机解码最漂亮的地方在于:它不是近似加速,而是在数学上精确等价于从目标模型采样。这一点使它区别于量化、剪枝、蒸馏等所有有损加速手段——你不需要重新跑一遍质量评测。
在单个位置上,给定草稿分布 q、目标分布 p 和草稿采出的 token x̃ ~ q,判定规则是:
关键在第 3 步:拒绝时不是从 p 重采(那样会破坏分布),而是从"p 比 q 多出来的那部分质量"里采。直觉上,接受步骤已经按照 min(p, q) 的比例把 token 发出去了,剩下的缺口恰好是 max(0, p−q)。
记接受概率 β = Σ_x q(x)·min(1, p(x)/q(x)) = Σ_x min(p(x), q(x))。最终输出 token 为 x 的总概率由两条互斥路径组成:
逐项化简。第一项:
第二项,先算归一化常数。注意到:
归一化常数正好抵消。两项相加,分情况讨论:
当温度为 0 时,p 退化为 one-hot。此时 min(1, p(x̃)/q(x̃)) 非零当且仅当 x̃ = argmax p,规则退化为逐位置精确匹配:草稿 token 等于目标模型的 argmax 就接受,否则用 argmax 替换。这也是实现里最常见的路径,通常称为 greedy verification。
采样变换必须一致。 temperature、top-k、top-p、repetition penalty 都会改变分布。若目标端做了 top-p 截断,那么用于计算接受率的 p 必须是截断并重归一化之后的分布,q 同理。混用(比如 q 用原始 softmax、p 用 top-p 后的)会破坏等价性。工程上的标准做法是:先对两侧应用完全相同的 logits processor,再进入拒绝采样。
bonus token 的正确性。 全接受时额外产出的 token 直接从 p_{γ+1} 采样,无需拒绝采样,因为它的前缀已经全部被验证过,p_{γ+1} 就是真实条件分布。
推广到多候选。 拒绝采样天然是"单条链"的。当需要在一个位置同时验证多个候选(树形草稿,见下节),需推广到 SpecInfer 提出的多轮拒绝采样:依次对候选做判定,每拒绝一个就把残差分布更新为 norm(max(0, p − q⁽ⁱ⁾)),再用下一个候选去试;全部拒绝则从最终残差分布采样。可以证明这仍保持分布不变,且接受概率随候选数单调上升。
独立草稿模型有两个现实问题:需要一个词表对齐、架构兼容的小模型(很多模型系列根本没有足够小的成员);以及它要维护自己的一整套 KV cache 和执行流。Medusa(Cai et al., 2024)提出了另一条路:不要独立模型,直接在目标模型上长出几个额外的预测头。
设目标模型最后一层的隐状态为 h_t。原始 LM head 用 h_t 预测 x_{t+1};Medusa 额外添加 K 个头,第 k 个头用同一个 h_t 预测 x_{t+1+k}:
即一个带残差连接的单层 MLP,后接(共享的)LM head。参数量极小(每个头约 d² ),前向开销可忽略,c 接近 0.01。训练有两种模式:
Medusa-1:冻结骨干,只训练新头。显存友好,可在量化模型上训练,原模型质量完全不受影响,但 α 受限。
Medusa-2:骨干与头联合训练,需用较小学习率 + 对原 LM head 的损失加权,以免损害模型本身能力。α 显著更高。
补救办法是用宽度换深度:既然单条链不准,就每个头取 top-k 个候选,组合成一棵候选树。只要其中任意一条路径被接受,这一轮就赚到了。朴素笛卡尔积会指数爆炸(k^K),所以 Medusa 用稀疏树:在校准集上统计每个头第 i 个候选的准确率,一条路径的期望接受率近似为路径上各节点准确率之积,按此贪心选取节点,构造一棵固定的(如 64 节点)树。典型形状是"头重脚轻"——浅层宽、深层窄。
问题来了:如何用一次前向验证整棵树?答案是把树展平成一个序列,然后定制 attention mask 与 position id:
Attention mask:节点只能 attend 到自己以及自己在树上的祖先节点(外加公共前缀),兄弟分支之间互不可见。这是一个由树结构决定的稀疏 mask,不再是标准下三角。
Position id:按节点在树中的深度赋值,而非展平序列中的下标。同一层的兄弟节点共享同一个 position id。这对 RoPE 正确性至关重要。
候选树: 展平序列:
[ ...prefix, x_t, A, B, AA, AB, BA ]
x_t
/ \ Attention Mask (■ = 可见)
A B pre A B AA AB BA
/ \ \ A ■ ■ · · · ·
AA AB BA B ■ · ■ · · ·
AA ■ ■ · ■ · ·
AB ■ ■ · · ■ ·
BA ■ · ■ · · ■
Position ID: A, B → t+1 AA, AB, BA → t+2
(兄弟节点共享 position,按树深度而非展平下标)
一次前向就得到了树上每个节点位置的目标分布,之后沿树从根往下找出最长的被接受路径,接受它,并把不在该路径上的 KV 条目从 cache 中剔除(实现上通常是把选中路径的 KV 搬到连续位置)。树形注意力是 Medusa 的核心工程贡献,此后被 EAGLE、SpecInfer、DeepSeek MTP 部署等几乎所有方案继承。
Medusa 在验证时默认不用严格拒绝采样,而是用 typical acceptance:
含义是:只要目标模型认为这个 token "不算离谱"就放行;分布越不确定(熵越高),门槛越低。
Medusa 的整体效果约为 2.2–2.8× 加速。
EAGLE(Extrapolation Algorithm for Greater Language-model Efficiency,Li et al., 2024)系列是目前开源方案中效果最好的一支,也是理解"草稿模型应该建模什么"的关键。
观察一:特征序列比 token 序列更规整。 直接预测 token 是在 |V| ≈ 1e5 的离散空间上做分类,误差大;而倒数第二层的隐状态(feature,记为 f)是连续的、低秩的、时间上平滑的序列,做自回归外推要容易得多。
观察二:仅有特征不够,必须消歧。 从 f_t 出发,下一步走向哪里取决于位置 t+1 实际采样出了哪个 token。例如前缀是 "I",采到 "am" 和采到 "always" 会导向完全不同的后续特征。所以必须把已经确定的下一个 token 的 embedding 一起喂进去。
两点合起来给出 EAGLE 的结构:
EAGLE 草稿循环
[f_t , e_{t+1}] → FC → Decoder → f̂_{t+1} → LM head → 采样 x̃_{t+2}
│ │
└──────┬──────────────┘
↓
[f̂_{t+1} , e_{t+2}] → FC → Decoder → f̂_{t+2} → LM head → 采样 x̃_{t+3}
↓
......
对比 Medusa: 第 k 步能看到前 k-1 步采出的 token → 草稿间存在依赖
一个重要细节是 training-test 不一致:训练时喂的 f_t 是目标模型的真实特征,而推理时第二步之后喂的是草稿模型自己预测的 f̂,带有误差。EAGLE 的处理是训练时对输入特征加入均匀噪声 U(−0.1, 0.1)。训练数据量很小(ShareGPT 约 68k 对话),单卡数天即可完成,且目标模型完全冻结——这是相对 Medusa-2 的一大优势,不存在损害原模型的风险。
EAGLE-1 沿用 Medusa 式的静态树:形状在校准阶段确定,推理时对所有输入都一样。但接受率是上下文相关的——"the United States of" 后面接 "America" 几乎必然被接受,而一段开放式叙述的下一个词则高度不确定,用同一棵树对待两者显然低效。
EAGLE-2 的贡献是发现:草稿模型输出的置信度是接受率的良好近似。于是可以在运行时动态构树:
Expand 阶段:逐层扩展,每层只从当前最有希望的若干节点继续展开。节点价值用从根到该节点的置信度累积乘积估计(近似整条路径被接受的概率)。
Rerank 阶段:扩展完成后,在全部候选节点中按累积置信度选出 top-m(例如 m=8 时性能已接近 m=60 的静态树),并保证被选中节点的祖先也一定入选(保持树结构合法),再送去验证。
相同验证预算下拿到更高的接受长度,EAGLE-2 相比 EAGLE-1 再提升约 20–40%。
改动一:去掉特征预测,改为 training-time test。
直接丢弃 L_reg,只保留 token 层面的目标。但这样一来,"喂给下一步的特征"就没有监督对齐了。解决办法是在训练时显式模拟多步草稿过程:把草稿模型自己产生的中间表示接回输入,走 2–3 步,每一步都算 token 级损失。这直接消除了 training-test 不一致,比加噪声的做法更彻底。
改动二:融合多层特征。
结果是接受长度显著提升,且随训练数据量持续增长而不饱和——具备了 scaling 性质。EAGLE-3 在 LLaMA、Qwen、DeepSeek 等模型上普遍达到 4–6.5× 加速(batch=1),接受长度 τ 可达 6–8。目前 SGLang、vLLM、TensorRT-LLM 均已内置支持,是开源部署的事实标准之一。
| 维度 | 独立小模型 | Medusa | EAGLE-1/2 | EAGLE-3 |
|---|---|---|---|---|
| 草稿单元 | 完整小模型 | K 个 MLP 头 | 1 层 decoder | 1 层 decoder |
| 草稿间依赖 | 有(自回归) | 无(并行头) | 有(特征级) | 有 |
| 输入 | token | h_t | f_t + e_{t+1} | 多层 h + e |
| 训练目标 | 独立预训练 | CE | SmoothL1 + CE | CE(多步模拟) |
| 骨干是否改动 | 否 | Medusa-2 会改 | 否 | 否 |
| 分布不变 | 是 | 否(typical) | 是 | 是 |
| 草稿树 | 通常无 | 静态树 | 静态 / 动态树 | 动态树 |
| 典型加速 | 1.5–2× | 2.2–2.8× | 2.5–4× | 4–6.5× |
前面的方法都是事后给一个已训练好的模型加装草稿模块。MTP 则把"预测多个未来 token"提前到预训练阶段,作为模型自身的一部分。
Gloeckle et al. (2024) 提出:在共享 trunk 上接 n 个独立输出头,第 k 个头预测 x_{t+k}:
他们发现这不只是为了加速,还能提升模型质量本身,尤其在代码等需要"规划"的任务上。直觉解释:next-token prediction 会让模型过度关注局部模式,很多 token 由前一个词就能猜出(teacher forcing 下的"捷径");强迫模型同时预测更远的 token,迫使它在隐状态中编码更长程的意图。同时每个位置提供 n 个训练信号,监督被致密化,数据效率更高。副产品是这些头天然可以拿来做自投机解码。注意该论文的头是并行独立的(与 Medusa 类似),预测之间没有因果链。
DeepSeek-V3 把 MTP 做成了保持完整因果链的形式,并作为正式的预训练目标之一。设深度为 D(V3 中 D=1),第 k 个 MTP 模块:
| 维度 | EAGLE | DeepSeek MTP |
|---|---|---|
| 训练时机 | 事后,目标模型冻结 | 与主模型联合预训练 |
| 数据量 | 约 68k 对话 | 全部预训练语料(万亿 token) |
| 对主模型的影响 | 无 | 提升主模型质量(额外训练信号) |
| 输入特征 | 倒数第二层 | 主模型最终隐状态 |
训练目标为各深度损失的平均乘以权重 λ 加到主损失上(V3 中前 10T token 用 0.3,后 4.8T 用 0.1)。推理时有两种用法:(a)直接丢弃 MTP 模块,主模型独立工作,此时 MTP 纯粹是一种训练时的正则/增强;(b)保留 MTP 模块做投机解码。DeepSeek 报告第二个 token 的接受率在 85%–90% 之间(跨任务稳定),配合投机解码可使 TPS 提升约 1.8×。
在 DeepSeek-V3 之后,MTP 迅速被主流开源模型采纳——Qwen3、GLM-4.5/4.6、MiniMax、Kimi 等都在预训练中加入了 MTP 模块并随权重一起发布。这带来一个重要变化:投机解码的草稿模块不再需要下游使用者自己训练,它作为模型权重的一部分直接发布,推理框架开箱即用。
工程上的若干要点:
多 MTP 层:D > 1 时可一次草稿多个 token,但深层模块接受率衰减;也可对单个 MTP 模块循环调用(自己的输出接回输入),此时会遇到与 EAGLE 相同的 training-test 不一致问题,接受率下降更快。
与树形注意力结合:MTP 草稿同样可配合树形候选与动态树构建(SGLang 的 EAGLE 风格调度可直接复用在 MTP 模块上)。
MoE 模型的特殊性:DeepSeek-V3 这类 MoE 模型算术强度更低(激活参数远小于总参数),memory-bound 更严重,投机解码收益更大;但验证多个 token 时可能激活更多专家,成本上升非线性。
验证方式:既可用严格拒绝采样保证分布不变,也可在贪心模式下做精确匹配。
演化脉络
Medusa 并行独立头,无依赖建模 → 靠树宽补救
↓
EAGLE 特征 + 下一 token embedding → 恢复因果链,事后训练
↓
EAGLE-3 多层特征 + 多步模拟训练 → 可 scaling
↓
MTP 同样的结构,搬进预训练 → 草稿质量随基座一起 scale
且反过来提升基座质量
MTP 是这条线的自然终点:既然草稿模块的质量随训练数据 scale,那就干脆让它跟着基座模型一起在万亿 token 上训练。
| 场景 | 推荐方案 |
|---|---|
| 模型自带 MTP 模块(DeepSeek-V3、Qwen3、GLM-4.5 等) | 直接开启 MTP 投机解码 |
| 有训练资源、追求最高加速 | EAGLE-3 |
| 无训练资源,输出与输入高度重叠(RAG、代码补全、文本编辑、格式化改写) | n-gram / prompt lookup decoding,零训练零成本 |
| 已有同系列小模型且词表对齐 | 经典 draft model |
| 高 batch 吞吐场景 | 谨慎评估,很可能应当关闭 |
不要只看端到端加速比(严重依赖硬件、batch、序列长度)。核心应报告接受长度 τ(与硬件无关,反映草稿质量)与 c(反映草稿开销),二者代入 1.6.1 的公式即可预估任意硬件上的收益。同时要区分延迟(TPOT)与吞吐(total TPS)两个维度——投机解码优化前者,可能损害后者。
draft 与 target 侧应用了完全相同的 logits processor
temperature、top-p 等参数在两侧一致
bonus token 路径没有重复采样
KV cache 回滚后位置编码正确
生产系统通常需要根据运行时信号动态调整:
batch size 超过阈值时降低 γ 或关闭投机解码
根据近期接受率的滑动平均调整草稿树的大小
对不同请求类型(低熵 vs 高熵任务)使用不同配置
Leviathan, Y., Kalman, M., Matias, Y. Fast Inference from Transformers via Speculative Decoding. ICML 2023.
Chen, C., Borgeaud, S., et al. Accelerating Large Language Model Decoding with Speculative Sampling. 2023.
Miao, X., et al. SpecInfer: Accelerating Generative LLM Serving with Tree-based Speculative Inference and Verification. ASPLOS 2024.
Cai, T., Li, Y., et al. Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads. ICML 2024.
Li, Y., Wei, F., Zhang, C., Zhang, H. EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty. ICML 2024.
Li, Y., et al. EAGLE-2: Faster Inference of Language Models with Dynamic Draft Trees. EMNLP 2024.
Li, Y., et al. EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test. 2025.
Gloeckle, F., Idrissi, B.Y., et al. Better & Faster Large Language Models via Multi-token Prediction. ICML 2024.
DeepSeek-AI. DeepSeek-V3 Technical Report. 2024.