投机解码:在不损失质量的前提下加速大模型输出
大模型生成文本时,每次只能输出一个 Token,而且每个 Token 都需要完整地运行一遍大模型。在低并发场景下,GPU 的大部分算力其实处于闲置状态,瓶颈在于反复从显存读取模型权重。投机解码(Speculative Decoding)巧妙地利用了这些闲置算力:先让一个小模型快速“猜”出接下来的几个 Token,再让大模型一次性并行验证这些猜测。 猜对了就一次前进多步,猜错了也不会影响输出质量。
基本原理
投机解码的流程可以分为三步:
- 起草:一个参数量小得多的草稿模型,快速连续生成若干个候选 Token;
- 验证:大模型把这些候选 Token 作为输入,一次前向计算就能同时得到每个位置上自己会给出的概率分布;
- 接受或拒绝:从第一个候选开始逐个检查,如果符合大模型的判断就接受,遇到第一个不符合的位置就拒绝,并用大模型自己的结果替换,然后从这里开始下一轮。
关键在于第二步:大模型验证多个 Token 的时间,与生成一个 Token 的时间相差不大,因为瓶颈在于读取权重,而不是计算本身。只要草稿模型的猜测有相当比例被接受,整体速度就能明显提升。
更重要的是,通过精心设计的接受规则,投机解码可以保证最终输出的概率分布与只用大模型完全一致,这意味着它是一种无损加速方法,而不是用质量换速度。
加速效果取决于什么
接受率
草稿模型的猜测与大模型越一致,每轮被接受的 Token 越多,加速越明显。对于格式固定、可预测性强的内容(如代码、结构化输出、复述原文),接受率通常较高;对于创意写作等开放性内容,接受率较低。
草稿模型的速度
草稿模型必须足够快,否则起草本身的时间会抵消验证带来的收益。
并发程度
在高并发场景下,GPU 的算力本来就已经被批处理充分利用,投机解码的额外计算可能反而降低整体吞吐。因此它最适合低并发、延迟敏感的场景。
常见变体
独立草稿模型
使用同一系列中参数量更小的模型作为草稿模型。要求两者使用相同的分词器。
自草稿方法
不使用独立的小模型,而是在大模型上增加轻量的预测头,让模型自己预测后续多个 Token。部署更简单,不需要额外维护一个模型。
基于检索的草稿
从输入文本或历史输出中查找匹配的片段作为候选。在需要大量复述或引用输入内容的任务中效果很好,例如基于文档的问答、代码修改。
多 Token 预测
部分模型在训练阶段就学习同时预测多个未来 Token,这些额外的预测能力可以直接用于投机解码。
部署时的权衡
- 额外的显存:草稿模型或额外的预测头需要占用显存,可能减少可用于 KV Cache 的空间,参见 KV Cache 详解;
- 吞吐与延迟的取舍:在高负载时可以动态关闭投机解码;
- 参数调优:每轮起草多少个 Token 需要根据接受率调整,太多会浪费计算,太少则加速有限;
- 框架支持:主流推理引擎大多已支持多种投机解码方式,部署前确认所用版本的支持情况,参见 vLLM 推理服务入门。
适合的场景
- 实时对话和语音助手等对延迟敏感的交互式应用;
- 代码补全和代码编辑,输出可预测性高;
- 基于文档的问答和摘要,大量内容来自输入;
- 本地部署的单用户场景,GPU 算力有富余。
小结
投机解码利用“小模型起草、大模型验证”的方式,在保证输出质量不变的前提下提升生成速度,特别适合低并发、延迟敏感的场景。它的效果取决于草稿的接受率和系统负载,部署时需要权衡显存占用和吞吐影响。更多降低延迟的方法可参考降低大模型应用延迟。