更快的解码
一个以批大小为一运行的前沿模型,大部分时间都在等待。为产出一个词元,它要把每一个权重从高带宽内存流入加速器的计算单元,做一次乘法,然后丢弃。矩阵乘法是瘦长的,一个向量去乘每个权重矩阵,于是芯片在下一批权重到达之前早已把算术做完,随后空等内存。第 31 章 与 第 32 章 从服务一侧确立了这个瓶颈:解码受内存限制,算术强度远低于硬件所能维持的水平。更快的解码正是利用这段闲置算力,改写「一次传播一个词元」的规则:一个廉价过程猜出若干未来词元,昂贵模型用一次目标传播验证多个猜测。解码一个词元,就是从模型在整个词表上给出的概率分布里把它采样出来;所谓目标分布,不过是昂贵模型对下一个词元给出的那组概率。推测解码(speculative decoding)就是这个模式的精确版本:草稿模型先提出词元,目标模型并行验证它们,同时保持目标分布不变。Medusa、Hydra、EAGLE 系列、前瞻解码(lookahead decoding)与多词元预测,主要差别在于猜测从何而来。加速不是方法自身的固定属性。它在小批大小的内存受限场景中成立,因为闲置 FLOPs 确实存在;一旦服务转为算力受限,它就可能消失。
基本动作
自回归生成有一个看似根本的顺序瓶颈:解码 个词元要 次前向传播,每一次都要等它前面那一次。这个瓶颈最直接地体现在用户感知到的延迟上。第 30 章 中的推理模型会在给出答案之前输出长串的中间词元,于是实际耗时由纯粹的顺序解码步数所主导。
本章一切的背后只有一个思想:用额外的并行算力去换更少的顺序步数。一个廉价的过程猜出若干未来词元,昂贵的模型在一次前向传播中检验它们全部,每一个通过检验的猜测,就是一个无需为其单独走一步的词元。因为对 个候选词元做一次前向传播,几乎与对一个词元做一次传播同价,那些闲置算力几乎不额外增加成本。
有两个量主宰着收益。接受率 是目标保留的草稿词元的比例;草稿成本是猜测者比目标便宜多少。这里 越高,说明草稿越像目标模型会自己采出的续写,每次目标传播所产出的期望词元数也随之上升。关键在于让草稿既廉价又与目标对齐,并一次验证许多候选。后面的讨论围绕两个问题展开:猜测从何而来,以及检验如何保持正确。
图 33.1 把收益画得更具体。在接受率 与一次传播检验 个草稿词元之下,其中 是草稿长度,每次目标传播发出的期望词元数是几何级数和 。这个式子把「连续接受多少个草稿词元」求和,从一个也不被接受时的一,升向全部被接受时的 。更长的草稿只在 高时才有帮助,因为一次早早的拒绝会浪费掉整条尾巴。
试着直接模拟接受/拒绝循环,看蒙特卡洛平均值如何收敛到闭式的几何级数和。
import numpy as np
rng = np.random.default_rng(0)
alpha, gamma, trials = 0.7, 4, 50000
def simulate():
emitted = np.ones(trials) # 修正/奖励词元
alive = np.ones(trials, dtype=bool) # 尚未被拒绝的运行
for _ in range(gamma):
accept = (rng.random(trials) < alpha) & alive
emitted += accept # 计入每个被接受的草稿词元
alive &= accept # 在首次拒绝处停止
return emitted.mean()
closed_form = (1 - alpha**(gamma + 1)) / (1 - alpha)
print(f"simulated mean tokens/pass: {simulate():.4f}")
print(f"closed-form tokens/pass: {closed_form:.4f}")
让检验保持精确
决定性的设计抉择,是验证如何保住正确性;而真正让这套方法可以放心部署的,是它可以做到精确。推测解码由 Leviathan 等 (Leviathan et al. 2023) 与 Chen 等 (Chen et al. 2023) 独立提出,正保证了这一点。一个小的草稿模型提出一段 个词元的续写。目标模型在一次并行传播中给所有 个位置打分,在每个位置同时给出它自己的分布 与草稿的分布 。这里 是最终必须保持不变的目标分布, 是便宜草稿分布。一条修正过的拒绝采样规则随后从左到右逐个接受或拒绝草稿词元:从 提出的词元 以概率 被接受,而在第一次拒绝处,从残差分布 归一化后重采样出一个修正词元。这个残差只保留目标分布比草稿分布多出来的概率质量,用来补回被拒绝处的缺口。这条规则背后的定理是:被接受的词元流,其分布恰如它逐词元地从 采样而来 (Leviathan et al. 2023)。加速是真实的,而输出分布丝毫未动。该方法不是对模型的近似,它就是同一个模型,只不过换了个顺序来采样。
图 33.3 画出了这条循环。它所展示的那一串接受/拒绝决策是最简单的情形,即一条单一的线性续写。下文的自草稿方法用一棵树取代了那条线。
寻找猜测的来源
这些方法可以看成一场关于「猜测从何而来」的搜索:从一个独立的模型,向目标自身的部件移动,最终进入目标如何被训练。
第二个、更小的模型
第一个答案是第二个、更小的模型。Leviathan 等与 Chen 等都用了一个与目标同族的现成草稿模型,例如一个小 Chinchilla 为一个 70B 的 Chinchilla 打草稿 (Chen et al. 2023)。这无需改动目标,且可证明无损,但它要训练、托管并对齐第二个模型,而一个匹配不佳的草稿接受率很低。
目标模型自身的草稿头
Medusa (Cai et al. 2024) 去掉了那个独立模型。它不用草稿网络,而是在目标的最后一层隐藏状态上接入若干轻量解码头,每个头并行预测一个更远的未来词元。这些头产出的候选构成一棵树,而一个树状结构的注意力掩码让目标能在一次传播里验证那棵树的许多分支,而非一条单一的线性续写。Medusa 的头彼此独立地预测各个未来词元,这就限制了一个多词元猜测能有多连贯。它还提供了一种典型接受(typical-acceptance)方案,为换取更多速度而放松精确采样,所以处于该模式的 Medusa 是刻意不保持分布的,与投机解码的精确性是另一笔交易 (Cai et al. 2024)。
Hydra (Ankner et al. 2024) 修正了这个独立性的局限。它的草稿头是顺序依赖的:预测第三个词元的头能看到第二个头提出了什么,于是多词元猜测在内部是连贯的,接受率随之上升。EAGLE 系列在「草稿应预测什么」上推得更远。EAGLE (Li et al. 2024) 观察到,在特征层级,即倒数第二层的隐藏状态上,自回归比在词元层级上更有规律,于是它通过预测下一个特征、再把它映射到一个词元来打草稿,并通过喂入已经领先一步采样出的词元来化解不确定性。EAGLE-2 (Li et al. 2024) 让验证树变成动态的:因为一个草稿词元的接受与否取决于上下文而不只取决于其位置,它在草稿自信处展开草稿树、在不自信处剪枝。EAGLE-3 (Li et al. 2025) 放弃了特征预测,转而在低、中、高层的融合之上做直接的词元预测,用作者称为训练期测试(training-time test)的流程训练,这让草稿器能随其训练数据增长而持续改进。
无草稿分支
一条平行的支线则彻底去掉了草稿。前瞻解码 (Fu et al. 2024) 把自回归生成重述为用 Jacobi 迭代(一种不动点迭代,一次同时更新一整窗的未来位置)求解一个非线性系统,并沿途收集该迭代产出的 n-gram。一条验证分支随后在同一步里把那些 n-gram 与目标核对。没有草稿模型,也没有额外训练的头;并行性来自该问题的不动点结构,而该方法是精确的。
猜测还可以是检索来的,而不必是算出来的。提示词查找解码把生成末尾的几个词元与提示词做匹配,把当初跟在后面的那段 n-gram 提出来作草稿,完全不动用模型 (Saxena 2023)。它已是 vLLM 与 TensorRT-LLM 里的标准投机方法之一,在输出大量复用输入的场景,检索增强的回答、编辑、代码,效果最强。
把猜测训练进去
最后一步把猜测折进了训练。多词元预测 (Gloeckle et al. 2024) 用若干共享主干的输出头训练基座模型,使每个位置一次预测后续 个词元。作者发现这作为辅助目标能提升样本效率,而关键在于,那些额外的头在推断时兼作内建的草稿器。DeepSeek-V3 (DeepSeek-AI 2024) 把这带进了一个前沿系统:它的 MTP 模块与主模型一同训练,随后被复用于投机解码,据报告它的第二个预测词元有 80% 到 90% 的时间被接受,并把生成吞吐量提高约 1.8 倍。
图 33.4 描出了这场搜索。
加速何时成立
这里的每一种方法,都用更多的并行算力与更多用于验证的内存流量,换取更少的顺序步数。边界,就在那笔交易不再划算之处,而其中最清楚的一条,是由服务场景而非方法本身所设定的。
图 33.5 展示了为何同一种方法可以提升性能,也可能降低吞吐。在小批大小下,加速器的计算单元空等权重而闲置,于是投机为验证候选所花的 FLOPs 原本也没有被充分利用。在大批大小下,权重被摊到许多序列上,计算单元本已饱和,于是验证那些随后被拒绝的词元会与真正的工作争抢 FLOPs,反而可能降低总吞吐。整章的前提,即解码是内存受限的,只在小批大小这个场景中成立。
这笔交易下面还有另外三项取舍,值得逐一点出,因为它们解释了这条谱系为何这样一路演进。
- 接受率与草稿成本。 一个更大或训练得更好的草稿器会提高接受率,但每次提议的成本也更高。最优草稿,是其接受率高到所省下的目标传播能盖过草稿自身成本的、那个最便宜的草稿。这正是自草稿头与特征层级打草稿胜出的原因:它们成本很低,却又与目标对齐。图 33.6 画出了这所蕴含的最优点:随着草稿变长,经成本调整的加速先升、到顶、再落,因为过了某个长度,额外的验证工作就盖过了它节省的词元,而一个更便宜的草稿器会把那个顶点推向更长的草稿。
- 树宽与浪费。 验证一棵更宽的候选树,每次传播能接受更多词元,但会在终将被拒绝的分支上消耗算力。动态树,如 EAGLE-2 中的,正是为了只在草稿自信处使用那份宽度而存在。
- 无损与有损。 投机解码、前瞻解码与 EAGLE 系列精确地保持目标的输出分布。Medusa 的典型接受模式用那份精确性换速度。多词元预测改变的是训练,而非采样保证。一条有损捷径是否可接受,是一个应用决策,并不是服务系统天然得到的收益。
这一文献中所报告的加速,原始投机解码的 2 到 3 倍、EAGLE-2 (Li et al. 2024) 的 3 到 4 倍、EAGLE-3 (Li et al. 2025) 的更大数字,都是在小批大小下测得的,那时服务是延迟受限的,加速器的算力确实在闲置。它们在论文之间并不可比,因为每篇用的基线、硬件与任务都不同,它们也不会迁移到每一种部署。随着批大小增长,服务器会从内存受限变为算力受限:投机原本使用的闲置 FLOPs 不再富余,而验证那些随后被拒绝的词元反会降低总吞吐。投机解码在高吞吐的生产服务中是否划算,如今有了运维上的答案:对自带训练好草稿器的模型,它已是生产默认,SGLang 报告在开启 MTP 的情况下,DeepSeek-V3 的输出吞吐最高提高 60% (Eigen AI Team and SGLang Team 2025);引擎还会随批大小缩短草稿,在高并发下缩到零。于是这条场景边界从一个开放问题变成了一条调度策略。仍然悬而未决的,是这个切换点该定在哪里,以及独立草稿、自草稿与无草稿三种设计之间的取舍,它们以不同的方式权衡托管成本、训练成本与接受率,尚无定论。把任何单一的加速数字都当作某种服务场景的属性,而非该方法本身的属性。
整章都说明了一个下层约束如何决定算法形状。第 31 章 与 第 32 章 描述的内存带宽瓶颈,即单流解码每个词元都重新载入每个权重、让计算单元闲置,正是「花并行算力去省顺序步数」一开始就值得的原因。倘若解码是算力受限的,就没有闲置的 FLOPs 可用,这些方法也都帮不上忙。解码算法的形状,是由它之下那块芯片的带宽对算力之比所设定的。
验证这一步的内部
值得具体看的是验证这一步,因为正确性就住在那里。给定来自 的草稿词元 ,以及来自一次并行传播的目标分布 ,这里下标按草稿位置编号, 是草稿长度。接受循环很短:
for i in range(gamma):
r = uniform(0, 1)
if r < min(1, p[i][x[i]] / q[i][x[i]]):
emit(x[i]) # 被接受,无需额外的目标步
else:
emit(sample(normalize(relu(p[i] - q[i])))) # 修正词元
break # 在首次拒绝处停止
# 若全部 gamma 个都被接受,从 p[gamma] 采样一个奖励词元
让它精确的两个细节是:拒绝时从残差 重采样,以及在一段全接受之后的奖励词元;残差项表示目标分布相对草稿分布尚未覆盖的概率质量,两者合起来正是分布保持定理所要求的。对于自草稿与基于树的方法,同样的接受逻辑跑在一棵树而非一条线上:一个树注意力掩码让单次目标传播给每个分支打分,而穿过那棵树的最长被接受路径被输出。图 33.7 展示了这为何胜过线性草稿。一条线性草稿只提出一种续写,于是一次早早的拒绝就浪费掉它之后的一切。一棵树则在每个位置上覆盖若干续写,树注意力掩码几乎以一次的代价在同一次目标传播里给它们全部打分。目标随后输出每个词元都被接受的那条最长路径。
在运维上,服务栈把这暴露为一个草稿器的选择。一个独立草稿模型是要载入并调度的第二个检查点。EAGLE 式与 Medusa 式的草稿器,是针对一个冻结目标训练、并与之并排载入的小头模块。如 DeepSeek-V3 那样的多词元预测打草稿,则根本不需要单独的产物,因为那些头已被训练进了模型。实际的失效模式,是草稿器对该工作负载的接受率太低,到那时投机不是削减延迟,反而在增加延迟。正因如此,生产中要盯的指标是接受率,而不是某篇论文里醒目的加速数字。
延伸阅读
- Leviathan et al., “Fast Inference from Transformers via Speculative Decoding,” 2023. arXiv:2211.17192推测解码用一个小型草稿模型提出词元、再由大目标模型并行校验,在不改变输出分布的前提下实现 2X-3X 加速。
- Chen et al., “Accelerating Large Language Model Decoding with Speculative Sampling,” 2023. arXiv:2302.01318推测采样利用小草稿模型生成候选词元,再由大目标模型并行验证,在 Chinchilla 上实现 2–2.5 倍推测解码加速,且不改变输出分布。
- Cai et al., “Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads,” 2024. arXiv:2401.10774MEDUSA 通过在 LLM 上附加多个额外解码头并结合基于树的注意力机制,在每步并行预测并验证多个词元,无需独立草稿模型即可实现 2.2-2.8 倍推测解码加速。
- Ankner et al., “Hydra: Sequentially-Dependent Draft Heads for Medusa Decoding,” 2024. arXiv:2402.05109Hydra heads 是一种序列相关的草稿头,用于推测解码,通过将每次预测条件化于先前候选词元,相比自回归解码最高提升 2.70 倍吞吐量。
- Li et al., “EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty,” 2024. arXiv:2401.15077EAGLE 是一种推测解码框架,通过以超前一步的词元序列为条件预测次顶层特征,在保持输出分布不变的情况下实现对自回归 LLM 解码 2.7x-3.5x 的延迟加速。
- Li et al., “EAGLE-2: Faster Inference of Language Models with Dynamic Draft Trees,” 2024. arXiv:2406.16858EAGLE-2 将推测解码中的静态草稿树替换为上下文感知的动态草稿树,无需额外训练即可实现 3.05x-4.26x 的无损 LLM 推理加速。
- Li et al., “EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test,” 2025. arXiv:2503.01840EAGLE-3 用直接词元预测和多层特征融合替代特征预测,通过 training-time test 技术发现推测解码的扩展律,推理加速比最高达 6.5x。
- Fu et al., “Break the Sequential Dependency of LLM Inference Using Lookahead Decoding,” 2024. arXiv:2402.02057Lookahead Decoding 无需草稿模型,通过 Jacobi 迭代并行生成并验证 n-gram,将大语言模型自回归解码速度提升最高 4 倍。
- Gloeckle et al., “Better & Faster Large Language Models via Multi-token Prediction,” 2024. arXiv:2404.19737通过让大语言模型使用 n 个独立输出头同时预测多个未来词元,可提升样本效率、在代码基准上提升约 15
- DeepSeek-AI, “DeepSeek-V3 Technical Report” (multi-token prediction reused for speculative decoding), 2024. arXiv:2412.19437
- Eigen AI Team and SGLang Team, “Accelerating SGLang with Multiple Token Prediction,” 2025. lmsys.orgSGLang 为 DeepSeek-V3 实现的多词元预测投机解码,据报告在小规模部署中把输出吞吐最高提高 60
- Saxena, “Prompt Lookup Decoding,” 2023. github.com提示词查找解码用对提示词的 n-gram 匹配取代投机解码中的草稿模型,在输出大量复用输入的任务上带来 2 至 4 倍加速且不改变输出质量;已进入 transformers 与 vLLM。
评论
登录后评论