大模型回答时,一个 token 接一个 token 往外生成。前一个还没出来,后一个就没有完整条件可用。原始推测解码论文把这个限制写得很直白,生成 K 个 token,通常需要让大模型串行运行 K 次。模型越大,每一步读权重和计算的代价越高,用户看到的就是回答慢慢往外蹦。

推测解码找来一个更小、更快的辅助模型。小模型先连续猜出几个候选 token,大模型随后用一次前向计算验证这批候选。猜对的部分可以一起接受,猜错的位置由大模型接手,再开始下一轮。小模型负责提议,大模型保留最终决定。

快多少要看候选被接受多少

这套办法成立的关键在并行验证。原始论文给出的目标是保持大模型原来的输出分布,同时减少串行等待。Hugging Face 的 Transformers 文档也说明,验证会保证结果与大模型自己生成一致。这里谈的是算法按规定实现后的结果,接入时仍要用同一批提示核对文本和性能。

辅助模型太大,自己猜候选就很慢,省下的大模型时间可能被它花掉。辅助模型太弱,又会频繁猜错,大模型每轮接受不了几个 token。两者还要能顺利对应 token。Hugging Face 当前实现要求主模型与辅助模型共用 tokenizer,避免反复编码和解码。

因此,看到某个模型支持推测解码,还不能直接写下固定的加速倍数。短回答、批量请求、不同硬件和不同文本类型都会改变结果。应记录首 token 等待时间、每秒生成 token、候选接受率和显存占用,再与原来的单模型生成比较。

测试集也要分开。客服短答、长文续写和代码补全的候选接受率可能差很多,把三类请求混成一个平均数,很容易掩盖某一类已经变慢。每类先跑相同提示、相同采样参数,完成预热后多测几轮,才看得出加速来自哪里。

它有清楚的适用限制

Transformers 文档里的这套实现支持 greedy search 和 sampling,不支持批量输入。企业若主要跑大批离线任务,单请求变快未必会让整批吞吐更高。服务框架也可能有自己的实现和限制,测试时要按真实并发量来跑。

摘要、复述和代码补全有时会重复输入里的词。Hugging Face 还提供 prompt lookup decoding,从提示中的 n-gram 直接拿候选,再交给大模型验证。它省掉了另跑辅助模型的步骤,对输入与输出高度重合的任务更合适,对开放式创作则未必有同样效果。

我会把推测解码当成推理优化选项,先用现有模型和真实请求做一组基准。结果要同时看速度、资源和稳定性。接受率低时,换辅助模型或关闭这项功能都很正常。大模型最终回答什么由验证决定,系统能否更快,要由运行数据回答。

参考资料