推测解码
推测解码是一种推理优化方法,其中一个小而快的"草稿"模型提前预测若干 token,随后大型目标模型在一次并行前向传播中对它们进行验证,接受那些与自己本会生成的内容相符的 token,并拒绝其余部分。用户得到的输出与普通解码完全一致,但速度快 2 到 4 倍。
推测解码是一种推理优化方法,其中一个小而快的"草稿"模型提前预测若干 token,随后大型目标模型在一次并行前向传播中对它们进行验证,接受那些与自己本会生成的内容相符的 token,并拒绝其余部分。用户得到的输出与普通解码完全一致,但速度快 2 到 4 倍。
为什么重要
LLM 的生成受制于顺序依赖:每个 token 都必须等待前一个 token。大模型的瓶颈不在于原始算力,而在于内存带宽,即每生成一个 token 就要把庞大的权重搬到 GPU 计算单元一次。推测解码通过把多个推测 token 批量放进一次前向传播,打破了这种顺序链条,从而大幅减少昂贵的大模型调用次数。Google 于 2022 年首次发表了这一方法;到 2024 至 2025 年,每一款主流推理引擎(vLLM、TensorRT-LLM、llama.cpp、together.ai)都把推测解码作为标准优化项,在保持相同输出质量的前提下,将服务成本降低 30% 到 70%。
工作原理
1. 草稿模型提议:一个小而廉价的模型(例如 700 亿目标模型的 10 亿参数孪生版本)自回归地生成接下来的 k 个 token。由于草稿模型的权重较小,这一步很快。
2. 目标模型验证:目标模型对这 k 个草稿 token 并行运行一次前向传播,计算出它自己在每个位置本会生成什么。
3. 接受或拒绝:从第一个草稿 token 开始,如果目标模型自己的首选项(或经概率匹配的采样结果)与之一致,就接受它,并持续进行,直到出现分歧。
4. 修正并继续:在第一处分歧处,用目标模型的 token 替换草稿的 token。流程从那里重新开始。
5. 净效果:如果草稿平均有 70% 的概率正确,那么目标模型每次前向传播能生成约 3 倍的 token,延迟也随之成比例降低。
为什么是无损的
正确实现的推测解码,会产生与普通解码完全相同的输出分布。其数学原理在于:目标模型充当验证者,草稿提出的任何 token 都必须通过目标模型的接受测试,因此最终序列与目标模型单独生成的结果完全一致。这里没有质量上的取舍,只有速度上的提升。
变体
朴素推测解码(Google 2022):一个草稿模型,一个目标模型。最初的方案形式。
Medusa:在目标模型自身上增加多个"头",用于提前预测若干 token,从而省去单独的草稿模型。部署更简单。
EAGLE:一种更准确的变体,利用目标模型自身的内部表示来起草,比外部草稿能达到更高的接受率。
树状推测解码:并行起草多棵候选 token 树。接受概率更高,但验证所需的算力也更多。
自推测:跳过目标模型的若干层,用同一套权重构造出一个廉价的"草稿"。
何时帮助最大
单批次推理:单用户的交互式聊天是受内存带宽限制的。推测解码在这里大放异彩。
长输出:模型生成的 token 越多,累积的节省就越可观。
重复性结构:当输出遵循可预测的模式(如代码、JSON)时,草稿的接受率非常高。
冷硬件利用:在 GPU 本会因等待内存而闲置的情况下,推测可以填补这段算力空档。
何时帮助较小
大批量服务:高吞吐量的工作负载本就受算力限制,而非内存带宽限制。推测会增加开销,却节省不了多少。
极具创造性 / 随机的输出:草稿接受率低,会限制提速效果。
极小的模型:用 10 亿草稿去配 30 亿目标,节省有限,因为目标本身已经很廉价。
短提示配短答案:搭建推测所需的开销会超过其带来的收益。
权衡取舍
内存中多了一个模型:现在你要同时服务目标模型和草稿模型。除非使用自推测,否则内存占用会增加。
实现复杂度:管理验证循环、拒绝采样和 KV 缓存回滚并非易事。请使用现成的库。
对接受率敏感:草稿匹配不佳时,如果拒绝占主导,反而可能拖慢速度。
冷启动:在草稿"热身"期间,最初的几个 token 无法从推测中受益。
常见错误
使用来自不同家族的草稿模型:用 Llama 草稿去配 Mistral 目标,很少能被接受。草稿必须与目标对齐。
草稿过大:用 70 亿草稿去配 700 亿目标,接受率很高,但运行成本过高。草稿规模应为目标的 5% 到 20%。
忽视 KV 缓存回滚:被拒绝的 token 必须回滚目标模型的 KV 缓存。忘记这一点会破坏状态。
用在本就很快的模型上:Haiku/Flash 级别的模型内存负担本就很轻,推测能节省的不多。
不做端到端测量:要对整条请求路径做基准测试。单纯的每秒 token 提升,有时会在负载之下或在网络延迟占主导时消失。
Sources: