大模型一次只能生成一个Token,为什么投机解码还能让它快2到3倍?

摘要:大语言模型最让人觉得“违反直觉”的优化之一,是Speculative Decoding。自回归模型在逻辑上必须一个Token接一个Token生成:第51个Token取决于前50个,没看到第50个就无法确定第51个。既然这个因果链不能打...

投机解码示意图:Draft Model 先猜测,Target Model 批量验证

大语言模型最让人觉得“违反直觉”的优化之一,是Speculative Decoding。自回归模型在逻辑上必须一个Token接一个Token生成:第51个Token取决于前50个,没看到第50个就无法确定第51个。既然这个因果链不能打破,为什么还能把生成速度提高两三倍,而且理论上保持与原目标模型相同的输出分布?答案并不在绕过自回归,而在GPU的工作方式。

Decode阶段有一个长期存在的效率问题:大模型每生成一个Token,都需要读取庞大的模型权重,但每一步参与计算的数据量又相对小。以70B级模型为例,权重可能达到上百GB。KV Cache避免了重复计算历史Attention,却没有让模型权重消失。一次Decode仍然要让所有主要层参与,每层都要从HBM读取权重做矩阵运算。在单用户或小Batch场景里,这些矩阵形状往往不够大,GPU强大的Tensor Core并没有完全吃满,时间更多消耗在“把权重搬进计算单元”上。

ByteByteGo在8月26日的一篇文章里把这个现象描述得很直观:70B模型以BF16计算时,大约需要读取140GB级权重;在现代数据中心GPU上,数据搬运可能占据一次Token步骤的大部分时间,而数学单元真正做乘加的时间只是一部分。投机解码利用的正是这块“已经付了读权重成本、算力却还没有被充分利用”的空间。

先让小模型猜,再让大模型一次批改多道题

最常见的Speculative Decoding会准备一个Draft Model。它比目标模型小很多,生成速度很快。假设目标模型当前已经有100个Token,Draft Model先连续猜5个候选:101、102、103、104、105。然后目标模型不是逐个验证,而是在一次Forward里输入这5个候选,并并行计算每个位置的概率分布。

这里有一个关键点:训练和Prefill阶段的Transformer本来就能一次处理多个位置,只是在Decode阶段因为下一个Token未知,才被迫串行。Draft Model提前提供了候选序列,相当于暂时填上未来位置,目标模型便可以利用GPU并行能力一次检查多个位置。

如果5个候选全部符合目标模型的接受规则,一次目标Forward就推进了多个Token;即便中间某个Token被拒绝,前面已经接受的部分仍然有效。只要Draft Model足够“懂”目标模型,平均每次Target Forward能接受两三个甚至更多Token,整体速度自然提高。这并没有消除目标模型,高质量输出仍然由Target Model裁决,小模型只是提出建议。可以把它看成一个资深工程师批改助手预写的代码:助手写得越接近资深工程师想法,资深工程师一次审核就能通过更多内容。

投机解码工作流信息图:标准解码、草稿模型、批量验证与提速条件

为什么一次验证多个Token不会让算力爆炸

直觉上,大模型一次计算5个位置,不也需要5倍计算吗?这正是Memory-Bound和Compute-Bound区别发挥作用的地方。

单Token Decode的矩阵非常“瘦”,GPU要把一整层权重读出来,却只拿来处理很少向量。一次验证多个候选以后,权重仍然只需要被读入一次,但可以同时与多个Token向量做运算。矩阵变宽以后,Tensor Core利用率提高,额外计算成本远小于重复做5次独立Forward的成本。

因此Speculative Decoding的收益通常在低Batch、交互式推理里更明显。当服务本来就有很大的Batch,GPU已经用大量真实用户Token把矩阵做宽,数学单元利用率很高,再塞入投机Token就不一定便宜。大Batch时,系统从Memory-Bound逐渐向Compute-Bound移动,投机解码的优势会下降,甚至可能反向拖慢吞吐。

这一点很重要:投机解码不是“所有场景无脑2~3倍”。它本质上是一种把空闲计算换成更少串行步骤的技术,是否划算取决于GPU还有多少空闲计算能力。

“质量不下降”为什么在数学上可以成立

投机解码最吸引人的地方,是标准算法可以保持Target Model原来的采样分布。对于Greedy Decoding很好理解:Draft提出一个Token,Target如果也认为这是Top-1就接受,不一致就从第一个错误点开始改。

Sampling模式更复杂。Draft和Target都会给候选Token一个概率。标准接受规则会根据两者概率比决定候选是否保留;当候选被拒绝时,新Token不是直接从Target原始分布随便采,而是从经过修正的“残差分布”采样。把接受路径和拒绝后的修正路径加起来,每个Token最终出现的概率恰好等于Target Model单独采样时的概率。

因此“lossless speculative decoding”里的lossless,指的是概率分布层面的等价。使用随机采样时,两次独立运行本来就可能输出不同文字;投机解码保证的是统计分布不被Draft Model改变,而不是逐字复现某一次原模型运行。实际系统中还可能有浮点误差、不同Kernel计算顺序等数值差异,但从算法设计上,Draft Model不会获得最终决定权。

Draft Model不一定是另一个完整小模型

早期方案通常需要单独训练一个小Draft Model。这个做法有明显成本:多一套权重、多一份显存、还要保持Tokenizer和目标模型兼容。后来出现了多种Draft来源。

一种是同系列小模型,例如70B目标配7B草稿。优点是容易理解和部署,缺点是额外占显存。另一种是Medusa、MTP等额外预测头:目标模型内部增加几个轻量Head,尝试直接预测未来多个Token,不需要完整第二模型。DeepSeek、Kimi等新架构越来越多地原生训练MTP能力,就是因为这种方式可以把投机能力直接嵌进模型。

还有一种是Prompt Lookup。代码补全、文档问答等任务里,大量未来Token其实可能已经在Prompt中出现,例如复制函数名、JSON字段、变量或文档原句。系统可以直接从上下文里寻找N-gram候选,连Draft Model都不用跑。对于高复制率场景,这种“几乎免费”的投机候选很有吸引力。

再往前,像vLLM 0.28已经开始做confidence-scheduled verification和adaptive speculative token budget。框架根据置信度动态判断这次值得猜几个Token,让Speculative Decoding从固定算法升级成调度策略。

接受率决定了它到底值不值

Speculative Decoding的核心指标之一是Acceptance Rate。Draft越接近Target,候选越容易被接受;但Draft越强,生成候选本身又越贵。系统需要在草稿成本和接受率之间找到平衡。

代码往往是比较适合投机的场景。语法、缩进、常见模板和重复片段让后续Token可预测性高。自由创作、温度很高的对话,候选分布更加发散,Draft的命中率会降低。长周期Agent任务也会出现动态变化:读日志、复制工具输出时容易投机,遇到复杂推理拐点时接受率可能突然下降。

因此成熟系统不会只报告一个“加速3倍”。更应该观察平均接受长度、Draft开销、Target Forward次数、TPOT、单用户速度以及大Batch下吞吐变化。对企业部署来说,最好按不同任务类型分别测试,而不是拿单一聊天Benchmark决定是否开启。

和KV Cache、Prefix Cache并不冲突

很多人会把投机解码和其他推理优化混在一起。KV Cache解决的是“不要重复计算历史Attention”;Prefix Cache解决“多个请求共享相同前缀时,不要重新做Prefill”;量化降低权重带宽和容量;Speculative Decoding解决“Decode必须串行调用Target Model太多次”。

这些机制可以叠加。一个Coding Agent可能先从Prefix Cache复用几十K系统提示和仓库上下文,KV Cache继续维护会话历史,再通过Speculative Decoding减少后续Target Forward次数,权重本身还可以是FP8或INT4。现代推理性能不是靠某一个魔法算法,而是多层优化同时作用。

这也解释了为什么vLLM、SGLang等框架越来越复杂。要把这些优化一起开,调度器必须知道缓存是否命中、Draft是否值得运行、显存是否足够、Batch里还有多少请求、是否应该异步调度。单个算法论文很漂亮,真正把它变成线上稳定收益,需要大量系统工程。

为什么未来模型会越来越“原生支持投机”

如果Speculative Decoding依赖外部Draft Model,推理服务要承担多模型部署和显存成本。模型团队如果在训练阶段就加入MTP,让主模型同时学习未来多个Token预测,推理框架就能用很小的额外参数获得高质量候选。DeepSeek、Kimi等模型已经推动MTP和投机解码进入主流架构,vLLM 0.28也在为这些链路做专门优化。

这一趋势很可能继续。模型训练不再只追求单Token准确率,也会考虑“这个模型在推理系统里能不能更高效”。未来架构可能直接为草稿、验证、缓存和长上下文调度设计专门Head或状态。模型和推理引擎共同设计,会像数据库查询执行器与存储引擎那样越来越紧密。

Speculative Decoding最值得记住的并不是“它能快3倍”,而是它揭示了一个常见的系统优化原则:当一个流程因依赖关系无法并行时,可以先用便宜方法预测未来,再用昂贵方法批量验证。它没有改变自回归模型的因果约束,只是让GPU在已经付出内存带宽成本时,顺便多做一些有价值的计算。

参考资料


分享到