土法炼钢兴趣小组的算法知识备份

【Transformer 与注意力机制】50|Speculative Decoding:用小模型加速大模型

文章导航

分类入口
transformer
标签入口
#transformer#speculative-decoding#inference#draft-model#rejection-sampling#llm-serving

Transformer系列导航

按系列顺序继续阅读,而不是停在单篇。

系列目录上一篇:【Transformer 与注意力机制】49|KV Cache:推理为什么是 O(n) 不是 O(n²)下一篇:【Transformer 与注意力机制】51|量化、蒸馏、剪枝:压缩改变的是三种不同的东西

目录

49|KV Cache 解决了自回归推理中的重复计算:历史 token 的 K/V 一旦算出就不用重算。但它没有解决另一个更根本的问题——decode 仍然是一个 token 接一个 token 的串行循环,而且这个循环大部分时间都在等显存带宽,不是在等算力。

Speculative Decoding(推测解码)的答案不是让每一步算得更快,而是让每一步能吐出不止一个 token。一个远小于目标模型(target model)的草稿模型(draft model)先猜出若干个候选 token,目标模型用一次 forward 并行验证这些候选——接受的直接采用,拒绝的按一个特定分布重新采样。关键约束是:这个过程产出的 token 序列,在统计上必须和直接从目标模型采样完全等价,不能是近似,不能是”差不多就行”。

本篇要交代清楚三件”上过线才知道”的事:

  1. KV Cache 之后 decode 为什么仍然卡在显存带宽上,这决定了投机解码到底在”偷”谁的算力;
  2. 接受-拒绝机制为什么能严格保持目标分布,这个证明可以逐步核对,不是”信任论文就行”;
  3. 接受率如何变成墙钉时间(wall-clock)加速比,以及批大小、显存约束什么时候会让这笔账倒贴。

Medusa、EAGLE、MTP 这些”draft 从哪来”的具体工程实现,本文只钉住它们的原理差异,完整的树形验证、引擎参数、部署细节参见 《大模型基础设施工程》15:推测解码与 MTP


一、KV Cache 之后,decode 卡在哪里

49|KV Cache 已经说明:decode 阶段每一步都要让新 token 的 Query attend 到所有历史 K/V,再产出下一个 logits。这一步省掉了”每步重算整条前缀”的浪费,但没有改变一个事实——每一步仍然只产出一个 token,却要把整套模型权重从 HBM 搬到计算单元一遍

以一个 70B 参数、FP16 权重的模型为例:仅权重就有 \(70\times10^9 \times 2\ \text{bytes} = 140\ \text{GB}\)。生成一个 token,GPU 要把这 140 GB 权重(加上对应的 KV Cache)流过一遍计算核心,换来的是一个 token 的 logits。H100 的 FP16 峰值算力接近 1 PFLOPS,但 decode 阶段矩阵乘法的两个维度里,一个维度(新增 token 数)恒为 1,算力利用率因此长期处在个位数百分比——带宽被吃满,算力却在闲置。这正是 roofline 模型里典型的 memory-bound 区间:算术强度(每字节数据换来的浮点运算数)太低,瓶颈从来不是”算得慢”,而是”数据搬得慢”。

这个观察直接指向一个机会:如果一次 forward 能同时算多个位置的 logits,只要这些位置的输入是一次性喂进去的,causal mask 自动保证第 \(i\) 个位置只看到前 \(i-1\) 个位置——这正是 prefill 阶段每天在做的事。既然权重已经搬进计算单元一次,多算几个位置的边际算力成本很低,只要新增的位置数不把 GPU 从 memory-bound 推成 compute-bound。Speculative Decoding 就是把这个”prefill 式的并行打分”接到 decode 循环里。


二、Draft 提草稿,Target 一次验证 K 个位置

\(\mathbf{x}_{<t}\) 是已经确定的前缀。一轮投机解码分两步:

第一步,起草。 草稿模型 \(q\) 以自回归方式生成 \(K\) 个候选 token:

\[ x_1 \sim q(\cdot \mid \mathbf{x}_{<t}),\quad x_2 \sim q(\cdot \mid \mathbf{x}_{<t}, x_1),\ \dots,\ x_K \sim q(\cdot \mid \mathbf{x}_{<t}, x_1, \dots, x_{K-1}) \]

这一步仍然是串行的 \(K\) 次小模型 forward,但因为 \(q\) 远小于目标模型,单步耗时也远低于目标模型。

第二步,验证。 目标模型 \(p\)\([\mathbf{x}_{<t}, x_1, \dots, x_K]\) 一次性喂入,像 prefill 一样并行算出 \(K+1\) 个位置的分布 \(p_1, \dots, p_{K+1}\)(下标对应第 \(t, t+1, \dots, t+K\) 个位置)。这一次 forward 的代价接近目标模型单步 decode 的代价(因为 decode 本来就是 memory-bound,多算几个位置几乎不增加墙钉时间,只要 \(K\) 不太大)。

然后逐位置做接受判定,这是下一节的核心。


三、接受-拒绝:为什么输出分布仍等于 target

3.1 判定规则

对每个草稿位置 \(i=1,\dots,K\),以概率

\[ \min\!\left(1,\ \frac{p_i(x_i)}{q_i(x_i)}\right) \]

接受 \(x_i\)。一旦在某个位置 \(n\) 第一次被拒绝,就丢弃 \(x_n, \dots, x_K\),改为从残差分布

\[ p'(y) = \frac{\max(0,\ p_n(y) - q_n(y))}{\sum_z \max(0,\ p_n(z) - q_n(z))} \]

中重新采样一个 token,本轮结束。如果 \(K\) 个候选全部被接受,再从 \(p_{K+1}\) 直接采一个”bonus token”——这一步不花额外的目标模型调用,因为 \(p_{K+1}\) 已经在验证 forward 里算出来了。

flowchart TD
    A["accepted prefix"] --> B["draft model q: draft x1..xK autoregressively"]
    B --> C["target model p: one forward scores K+1 positions"]
    C --> D{"for i = 1..K, accept x_i\nwith prob min(1, p_i(x_i)/q_i(x_i))"}
    D -->|"first rejection at i = n"| E["resample from norm(max(0, p_n - q_n))"]
    D -->|"all K accepted"| F["bonus token sampled from p_(K+1)"]
    E --> G["append n tokens, next round"]
    F --> H["append K+1 tokens, next round"]

3.2 正确性:逐步可核对的证明

这不是”论文说无损就信”,证明本身只有几行,可以自己核对。固定一个位置,记草稿分布为 \(q\)、目标分布为 \(p\),考察最终输出 token 为 \(y\) 的概率:

\[ P(\text{output}=y) = \underbrace{q(y)\cdot\min\!\left(1,\frac{p(y)}{q(y)}\right)}_{\text{直接接受 }y} + \underbrace{\Big(1-\textstyle\sum_x q(x)\min(1,\tfrac{p(x)}{q(x)})\Big)}_{\text{总拒绝概率}}\cdot \underbrace{\frac{\max(0,p(y)-q(y))}{\sum_z\max(0,p(z)-q(z))}}_{\text{拒绝后重采样到 }y} \]

注意 \(q(x)\min(1,p(x)/q(x)) = \min(q(x),p(x))\),所以总拒绝概率是 \(1-\sum_x\min(q(x),p(x))\)。再注意对任意 \(x\),恒有恒等式

\[ \min(p(x),q(x)) + \max(0,\ p(x)-q(x)) = p(x) \]

(两边分别验证 \(p(x)\ge q(x)\)\(p(x)<q(x)\) 两种情况即可)。把它对所有 \(x\) 求和,得到

\[ \sum_x \max(0,p(x)-q(x)) = 1 - \sum_x \min(p(x),q(x)) \]

也就是”总拒绝概率”恰好等于残差分布的归一化常数 \(Z=\sum_z\max(0,p(z)-q(z))\)。代回上式,分母分子的 \(Z\) 相消:

\[ P(\text{output}=y) = \min(p(y),q(y)) + \max(0,\ p(y)-q(y)) = p(y) \]

也就是说,不论草稿模型 \(q\) 是什么,只要按上面的规则接受/拒绝/重采样,输出 token 在这个位置上的分布精确等于 \(p(y)\)——和直接从目标模型采样完全一致。这是 Leviathan, Kalman & Matias 在 Fast Inference from Transformers via Speculative Decoding(ICML 2023)里的核心定理,DeepMind 同期独立发表的 Accelerating Large Language Model Decoding with Speculative Sampling(Chen et al., arXiv:2302.01318, 2023;预印本,提交时间与 Leviathan et al. 几乎重合,内容上是等价算法的独立发现,常被称为”maximal coupling”表述)给出了本质相同的构造。两篇论文几乎同时给出同一个结论,是这套方法能被工业界迅速接受的关键——它不是一个需要反复验证的经验技巧,而是一个可以证明的采样等价关系。

草稿模型只负责”提出候选、决定验证顺序”,从不直接替代目标模型的采样决策——这也是它和”直接把小模型的输出当结果”最本质的区别:换成小模型会改变输出分布,投机解码不会。


四、接受率如何变成墙钉时间加速比

4.1 期望产出 token 数

定义接受率 \(\alpha = \mathbb{E}_{x\sim q}\big[\min(1, p(x)/q(x))\big] = \sum_x \min(p(x), q(x))\),它衡量草稿分布 \(q\) 有多接近目标分布 \(p\)。如果假设各位置的接受事件独立同分布(近似,实际中相邻位置接受率会相关),一轮产出的 token 数是一个上限为 \(K+1\) 的截断几何分布,期望值是(Leviathan et al. 2023, Theorem 3.5):

\[ \mathbb{E}[\text{tokens per round}] = \frac{1-\alpha^{K+1}}{1-\alpha} \]

4.2 墙钉时间改进因子

\(c\) 为草稿模型单步耗时与目标模型单步耗时的比值(cost coefficient)。一轮投机解码要跑草稿模型 \(K\) 次、目标模型 \(1\) 次,相对代价是 \(Kc+1\) 个”目标模型单步等价时间”。于是期望墙钉时间改进因子是(Theorem 3.8):

\[ \mathbb{E}[\text{speedup}] = \frac{1-\alpha^{K+1}}{(1-\alpha)(Kc+1)} \]

这个公式把三个变量绑在一起:\(\alpha\) 越高越好、\(K\) 太大会在分母里拖后腿、\(c\) 越小(草稿模型越便宜)越好。代入一组数字看直觉:\(\alpha=0.7\)\(K=4\)\(c=0.05\) 时,\(\mathbb{E}[\text{tokens}] = (1-0.7^5)/(1-0.7) \approx 2.773\),代价 \(Kc+1=1.2\),speedup \(\approx 2.31\times\)。如果接受率掉到 \(\alpha=0.4\),同样 \(K=4\)\(c=0.05\)\(\mathbb{E}[\text{tokens}] = (1-0.4^5)/(1-0.4) \approx 1.659\),speedup \(\approx 1.38\times\)——收益还在,但已经薄了很多;继续掉到 \(\alpha=0.2\),speedup 会跌到略高于 \(1\times\),草稿模型的开销几乎吃掉全部收益。

下图是这个公式在不同 \(K\) 下随 \(\alpha\) 变化的理论曲线(固定 \(c=0.05\),对应 draft 比 target 小两个数量级时的典型量级)。这是公式直接生成的曲线,不是某一次实测的拟合,生成脚本见 images/gen_speedup_curve.py

接受率与理论加速比的关系,K 越大对接受率越敏感

图上能读出两个直觉:\(K\) 越大,曲线在高接受率区涨得越猛,但在低接受率区跌破 \(1\times\) 的位置也越早——更长的草稿在赌一个更高的接受率,赌输了亏得也更多。这就是为什么”draft model 要多强”没有统一答案,而要看具体任务和硬件下的 \(\alpha\)\(c\)

4.3 接受率的决定因素

\(\alpha\) 不是一个固定属性,它由三件事共同决定:


五、批大小、显存与调度:什么时候投机解码开始亏本

第一节说过,decode 之所以有”免费算力”可用,是因为它是 memory-bound。这个前提在小 batch 下成立,但随 batch 增大会失效——batch 越大,GPU 需要处理的并发 token 越多,算术强度上升,系统会从 memory-bound 逐渐转向 compute-bound。一旦目标模型的验证 forward 本身已经在吃满算力,验证阶段里那些”最终被拒绝”的候选 token 就不再是免费的,而是实打实占用的算力。

这不是纯理论推测。Liu, Yu, Park, Stoica & Cheung 在 Speculative Decoding: Performance or Illusion?(arXiv:2601.11580,2025,UC Berkeley,预印本,尚未同行评审;论文在生产级 vLLM v0.10.1.1 上做的系统评测)给出了具体数字:

显存约束是另一条独立的线,和算力约束不完全同源。同一篇论文测了几种方案的显存开销(Table 2,FP16):EAGLE 类方法只多一层 Transformer,静态显存开销 1.4%–5.3%,每 token KV Cache 开销 1.3%–3.1%;而独立 draft model 方案的开销明显更高——用 0.6B draft 配 8B target 时,每 token KV Cache 从 144 KiB 涨到 256 KiB,增加了 1.77 倍。对于长上下文、高并发的服务场景,这意味着独立 draft model 会直接和目标模型抢显存,挤占本可以用来扩大 batch 的 KV Cache 空间;调度器要同时管理两套模型的 KV Cache 生命周期,这也是 continuous batching 在接入投机解码后变得更复杂的原因之一。

这些数字共同指向一个工程判据:投机解码的收益随 batch 增大而单调收缩,收缩速度和模型规模正相关。vLLM 提供的 --speculative-disable-by-batch-size 参数就是在用一个静态阈值近似这条曲线,但阈值怎么选依赖具体模型、硬件和 workload,还没有一个通用的解析式——这也是第九节开放问题之一。


六、Medusa、EAGLE、MTP:三条「draft 从哪来」的路线

经典投机解码需要单独部署一个同词表的小模型,这本身是额外的运维负担。后续工作把”draft 从哪来”这一步做了三种不同选择,只看原理差异,完整的树形注意力、引擎参数和部署命令见 《大模型基础设施工程》15:推测解码与 MTP

方法 draft 来源 是否真自回归 训练方式 原理上的限制
Medusa(Cai et al., ICML 2024) 目标模型最后一层 hidden state 上加若干额外 LM head,每个头独立预测 next+1…next+n 否——各头独立条件于同一个 hidden state,不建模草稿 token 间的依赖 冻结目标模型,只训练新增的几个头(代价很低) 忽略 token 间条件依赖,单头准确率有上限;靠 tree attention 同时验证多条候选路径来补偿接受率
EAGLE(Li et al., ICML 2024) 一个小型自回归模块,在 feature(hidden state)层 做链式预测,输入是上一步 hidden state + embedding 是——draft 本身是链式自回归,更贴近真实 token 生成过程 单独训练这个小自回归头,目标模型冻结 draft head 必须与目标模型 checkpoint 严格匹配;目标模型微调后通常需要重训 draft head
MTP(DeepSeek-V3,DeepSeek-AI 2024) 预训练阶段内嵌的额外预测模块,模块间串联保持因果链(不是独立头) 是——模块 \(k\) 的输入包含模块 \(k-1\) 在该位置的 hidden state,链式传递 与主干模型一起预训练/后训练,是训练目标的一部分,而不是事后微调 只有从零训练模型才能获得;已发布的模型不能事后”补”上这条能力

三者的分野本质上是”draft 的自回归性从哪里来”:Medusa 放弃自回归性换训练简单;EAGLE 把自回归性搬到 feature 层,用一个小模块弥补;MTP 把它做进预训练目标本身,用更高的一次性训练成本换来更高的位置无关接受率。DeepSeek-V3 技术报告(DeepSeek-AI, arXiv:2412.19437, 2024)汇报第二个 token 的预测接受率在 85%–90% 之间,对应的 decode 端到端加速约 \(1.8\times\)——这是官方自测数字,论文并未给出独立第三方复现,读者需要知道这一点再引用。


七、关键概念回顾


八、常见误解

8.1 “Speculative Decoding 让小模型替代了大模型”

不是。小模型只负责起草,最终每个 token 的分布严格由目标模型的接受-拒绝规则决定,证明见第三节。

8.2 “它总能加速,开着就好”

不对。第五节的实测数据说明:batch 大到系统进入 compute-bound 区间后,验证阶段变成实打实的算力成本,speedup 会持续下降,某些宽 tree 配置甚至会跌破 \(1\times\)——比不开投机解码更慢。

8.3 “接受率越高,用更大的 K 肯定更划算”

不一定。第四节的公式和图表显示,\(K\) 越大,曲线对 \(\alpha\) 的下降越敏感——用大 \(K\) 赌一个高 \(\alpha\),一旦接受率没达到预期,亏得也比小 \(K\) 更多。第五节的宽 tree 数据(k=21 在 batch=64 跌破 1x)是这一点的实测印证。

8.4 “它能让模型输出质量变好”

不会。严格 rejection sampling 版本的投机解码只优化延迟,输出分布和不做投机解码时完全一致,不会更好也不会更差。


九、争论与开放问题

9.1 争论:“无损”这个词的边界在哪里

第三节的证明只对严格 rejection sampling成立。Medusa(Cai et al., ICML 2024)在论文里明确指出,严格匹配目标分布在高温采样场景下并不是必需的,于是提出了typical acceptance方案:用目标模型自身在该位置的预测概率 \(p_{\text{original}}(x_{n+k}\mid \dots)\) 与一个基于熵的阈值 \(\min(\epsilon,\ \delta\exp(-H(p_{\text{original}})))\) 比较,超过阈值就接受,不再要求分布严格匹配。这个方案在实践里几乎看不出质量差异,而且在高温下比严格 rejection sampling 接受率更高——因为严格版本要求 draft 概率不超过 target 概率太多,而高温下 target 分布本身更平,惩罚更重。

这构成一个真实的工程取舍:严格数学等价(可证明输出分布不变,适合任何对 bit-exact 复现有要求的场景)vs typical acceptance 的近似(牺牲严格等价性,换取高温采样下更高的接受率和更好的”创意”表现)。生产部署如果需要 bit-exact 复现,必须确认引擎走的是精确 rejection sampling 而不是 typical acceptance 模式——两者在 API 层面看起来都是”开了投机解码”,但严格性完全不同。

9.2 开放问题一:何时应该关闭投机解码,判据能不能量化

第五节的实测(Liu et al. 2601.11580)给出了具体现象:batch 增大、模型变大都会压缩收益,宽 tree 甚至会倒贴。但目前工程上的应对(如 vLLM 的按 batch 阈值静态关闭)仍是经验参数,没有一个基于 \(\alpha\)\(c\)、当前系统算力占用率的解析判据能通用地回答”这个请求负载下该不该开”。这本身是该论文提出的”理论加速上限与实测差距”这一研究方向的一部分,值得读者跟进后续工作。

9.3 开放问题二:高温/多样性采样下接受率的下降,还缺系统性刻画

Xia et al. 的综述(Unlocking Efficiency in Large Language Model Inference: A Comprehensive Survey of Speculative Decoding, Findings of ACL 2024)把 drafter 与目标模型的对齐度列为决定接受率的关键因素,但公开评测里,包括这篇综述引用的大多数工作,主要在贪心解码或低温设置下报告加速比。严格 rejection sampling 下,温度升高、top-p 放宽会怎样系统性地压低 \(\alpha\),目前缺少跨模型、跨温度的公开量化研究——这不是”没人讨论过”,而是”讨论停在直觉层面,还没有像第四节那样可以直接核对的公式或实测曲线”。对高温创意写作场景要不要开严格投机解码,读者目前只能自己测,而不能直接套用论文里贪心解码的接受率数字。

9.4 开放问题三:draft/target 长期维护成本缺少公开的成本模型

目标模型持续微调后,独立 draft model 或 EAGLE/Medusa 的 draft head 是否需要跟着重训,重训代价、监控接受率漂移的运维流程,目前没有公开的成本核算框架。Liu et al. 2601.11580 的动机之一正是”研究原型评测 vs 生产系统实测”之间存在系统性差距,这说明这类长期运维成本此前一直是评测盲区,还需要更多生产环境的公开数据。


十、下一步

Speculative Decoding 用”多花一点算力换延迟”解决了 decode 阶段的串行瓶颈,但它没有改变模型本身的参数量、显存占用和单次 forward 的成本结构。51|量化、蒸馏、剪枝会转向另一条正交的路径:直接压缩模型本身,看量化、蒸馏、剪枝分别在数值精度、训练目标和结构稀疏性上做了什么取舍,以及它们能不能和投机解码叠加使用。


十一、参考文献

核心论文

  1. Leviathan, Y., Kalman, M., Matias, Y. “Fast Inference from Transformers via Speculative Decoding.” ICML 2023(同 arXiv:2211.17192)。接受-拒绝算法与正确性证明(Theorem 3.5、3.8)的原始出处。
  2. Chen, C., Borgeaud, S., Irving, G., et al. “Accelerating Large Language Model Decoding with Speculative Sampling.” arXiv:2302.01318, 2023。预印本,未见正式同行评审版本;DeepMind 团队与 Leviathan et al. 几乎同期独立提出等价算法。
  3. Cai, T., Li, Y., Geng, Z., et al. “Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads.” ICML 2024(同 arXiv:2401.10774)。多头 draft 与 typical acceptance 方案。
  4. Li, Y., Wei, F., Zhang, C., Zhang, H. “EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty.” ICML 2024。特征层自回归 draft。
  5. DeepSeek-AI. “DeepSeek-V3 Technical Report.” arXiv:2412.19437, 2024。MTP 训练目标与自报告的接受率、加速比数字。

综述

  1. Xia, H., Yang, Z., Dong, Q., et al. “Unlocking Efficiency in Large Language Model Inference: A Comprehensive Survey of Speculative Decoding.” Findings of the Association for Computational Linguistics: ACL 2024, pp. 7655–7671。

实测/工具

  1. Liu, X., Yu, J., Park, J., Stoica, I., Cheung, A. “Speculative Decoding: Performance or Illusion?” arXiv:2601.11580, 2025。预印本,尚未同行评审;生产级 vLLM 上的系统评测,批大小、显存开销、执行时间拆解数据均引自此文并标注了图表出处。
  2. Kwon, W., et al. “Efficient Memory Management for Large Language Model Serving with PagedAttention.” SOSP 2023。vLLM 论文,第五节引用的实测环境背景。

← 上一篇:49|KV Cache | 下一篇:51|量化、蒸馏、剪枝

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-15 · transformer

【Transformer 与注意力机制】49|KV Cache:推理为什么是 O(n) 不是 O(n²)

自回归推理和训练不是同一种程序。本文解释 KV Cache 为什么成立:历史 token 的 Key/Value 一旦算出,在后续 decode 中不会改变;缓存它们可以避免反复重算前缀。文章同时讲清 prefill 与 decode 的差异、cache 显存公式、长上下文为什么受限,以及 PagedAttention、MQA/GQA、cache 量化等方向各自在解决什么。

2026-08-06 · transformer

【Transformer 与注意力机制】40|三大路线之争:为什么大模型几乎都是 Decoder-only

Encoder-only、Encoder-Decoder、Decoder-only 的差异不是谁更聪明,而是谁能看见谁的信息流不变量。本文从可见性图出发,解释这个不变量如何锁死任务接口与训练管线,KV Cache、continuous batching、投机解码为什么默认假设单流 causal Decoder,以及 embedding、rerank、强制双向抽取场景为什么不该硬上生成式大模型。

2026-04-15 · transformer

【Transformer 与注意力机制】42|FlashAttention:注意力计算的硬件级重写

FlashAttention 的关键不是近似注意力,也不是把公式改掉,而是重新安排标准 attention 在 GPU 内存层级里的计算路径。本文解释为什么标准 attention 的瓶颈常常是 HBM 读写,FlashAttention 如何用 tiling 和 online softmax 避免物化完整注意力矩阵,以及它为什么省显存、提吞吐,却没有消除 O(n²) 的根本复杂度。

2026-08-06 · transformer

【Transformer 与注意力机制】51|量化、蒸馏、剪枝:压缩改变的是三种不同的东西

量化、蒸馏、剪枝常被当成同一件事的三种手段——"让模型变小",但它们改变的对象、误差来源和失败模式完全不同。本文从 weight-only 与 activation quantization 的假设差异、GPTQ/AWQ/SmoothQuant 的数学分野,讲到 attention、FFN、KV Cache 承受压缩代价的不同,以及 PPL 为什么骗过了很多人的质量评测。


By .