推测解码算法在 MTT GPU 的应用实践
2024-11-25
前言
目前主流的大模型自回归解码每一步都只生成一个token, 尽管kv cache等技术可以提升解码的效率,但是单个样本的解码速度依然受限于访存瓶颈,即模型需要频繁从内存中读取和写入数据,此时GPU的利用率有限。为了解决这种问题,VLLM框架中提出的continues batching的推理方式则是充分利用批量推理来缓解或避免访存瓶颈,极大的提升了推理系统的吞吐量。不同于VLLM等框架在系统层面的加速优化,本文所想要介绍的推测解码(speculative decoding)技术则是聚焦于算法层面的加速优化,其核心想法是借助于更小的模型来并行或者串行生成多个token。
OpenAI 于2024年11月5日提出了 "Predicted Outputs" 特性,在某些情况下,LLM 的大部分输出是事先已知的。例如,如果用户要求模型对某些文本或代码进行仅有少量修改的重写,那么可以通过使用预测输出显著降低延迟,将已有内容作为预测传入。这种技术与prompt-lookup Decoding很相似,即通过匹配prompt中相似的token序列来生成候选token的方法,这种算法的优势是不需要额外的模型来验证候选的token是否是可接受的,但劣势是只适用于特定的任务,即输出大概率在输入中的,如果是翻译任务则大概率会适得其反。因此,"Predicted Outputs" 可以看成是一般性推测解码的一种特殊场景的引用。
对于一般性的推测解码技术而言,目前方法通常都分为两个步骤:一是使用Draft model生成若干个token序列;二是将候选token序列输入到LLM(Target model)中进行验证。因此大部分工作都集中在如何设计和训练一个准确性高同时参数量小的Draft model,以及如何在验证阶段更快的验证那些合理的token序列。一般来说Draft model 要比 Target model 参数量要小很多,每一次迭代至少会生成1个token,最多会生成K+1个Token。speculative decoding取得加速收益的两个关键因素:一是自然语言层面,存在一些比较容易的token可以用更小的代价来生成;二是硬件层面,Batch的情况下硬件不会陷入计算瓶颈。
本文首先会介绍推测解码及其比较经典的EAGLE算法 [1,2],并测试官方开源的权重在A100和S4000上的推理加速结果。接着,我们基于S4000,完成在7B和14B模型在中文数据集上的训练和推理,并报告其推理加速结果。最后是本文的总结。
推测解码与EAGLE算法
推测解码的验证策略
贪婪解码(greedy decoding)
当直接使用贪婪解码来生成,即取概率最大的token时, 只需要直接匹配top-1,遇到不匹配的直接丢弃。如下图,来自Draft model的y2,y3,y4,y5作为input_id输入到大模型中进行验证,最终根据大模型的输出来匹配得到y2,y3,y4这一个序列。

随机解码(Nucleus decoding)
当使用随机解码时,由于选择下一个token是偏随 机性的,此时验证的策略则会更复杂一些。下面介绍deepmind的一篇论文[3]中提出的验证算法,他们严格证明了对于任意分布和,通过从和进行投机采样所得到的标记的分布与仅从进行采样所得到的标记的分布是相同的。
算法: 生成并评分初步标记序列(draft tokens)
输入:
- 一个较小的自回归模型(draft model)
- 一 个目标大模型(target model)
- 期望生成的标记序列长度 K
输出:
- 最终生成的标记序列
步骤:
1. 生成 draft tokens
a. 使用 draft model 生成一个长度为 K 的初步标记序列(draft tokens)
b. 记录这 K 个草稿标记对应的概率值 p
2. 评分 draft tokens
a. 使用 target model 对这 K 个草稿标记进行评分,获得概率值 q
b. 评分时间与评分单个标记的时间相当
3. 判断是否接受
a. 对于每个草稿标记,计算 min(1, q/p) 作为接受该标记的概率
b. 生成 K 个 [0,1] 范围内的均匀随机数
c. 如果随机数小于等于 min(1, q/p),则接受该草稿标记,否则拒绝
4. 处理接受/拒绝结果
a. 如果所有 K 个草稿标记都被接受,从 target model 直接采样第 K+1 个标记
b. 如果第 t 个草稿标记被拒绝,则:
- 从 q(x) - p(x) >= 0 的修正概率分布中采样一个新标记
- 将之前接受的草稿标记和新采样的标记连接作为最终结果
5. 返回结果