使用自推测解码的更快文本生成
自推测解码通过 LayerSkip 方法实现,使得单个大型语言模型(LLM)能够通过使用其自身的早期层来草拟令牌、使用其更深层来验证令牌,从而加速文本生成。这种方法减少了与传统推测解码相关的内存占用和计算延迟,而传统推测解码需要两个独立的模型。
自推测解码与传统推测解码的对比
传统推测解码依赖于一个小型草拟模型来生成一系列令牌,并依赖一个较大的验证模型来验证它们。相比之下,自推测解码对两个角色使用同一个模型。通过在中间层退出模型以生成草拟令牌,系统消除了对次要模型权重的需求,从而节省内存并减少大规模推理的整体硬件占用。
技术实现:提前退出和未嵌入
为了启用自推测解码,模型必须能够进行“early exiting”,即生成过程在预先指定的中间层停止。
未嵌入的 logits
因为语言模型(LM)头通常仅在最终层进行训练,所以模型需要特定的训练来将中间层的 logits “unembed”。此过程将中间层的输出投射到 LM 头上以预测下一个令牌。
训练修改
在预训练或微调过程中,会使用两种主要修改来使提前退出变得可行:
- Layer Dropout:模型被训练以跳过某些层,随着层数加深, dropout 比率增加。这减少了对后续层的依赖并提高了泛化能力。
- Early Exit Loss:在每个退出(中间层)上应用归一化的损失,迫使 LM 头学习如何将来自模型各深度的输出进行 unembed。
推理过程:草拟和验证
推理过程分为两个不同的阶段:
- Self-Drafting:通过在中间层退出模型来生成令牌。推测令牌的数量和具体的退出层是平衡速度和准确性的超参数。
- Self-Verification:完整模型验证草拟的令牌。为了进行优化,系统会重复使用在草拟阶段缓存的早期层结果,仅计算剩余的层以进行验证。
硬件和性能优化
自推测解码利用 KVQ cache(KV 缓存和退出查询缓存的组合)来最小化冗余计算。相比两模型系统,这提供了三个主要优势:
- Shared Weights:前 $E$ 层在草拟和验证过程中被重复使用。
- Shared KV Cache:前 $E$ 层的键值对被重复使用。
- Shared Compute:退出查询缓存存储了退出层 $E-1$ 的查询向量,使得验证过程可以跳过对层 $0$ 到 $E-1$ 的计算。
基准测试和性能权衡
在 A100 GPU 上进行的基准测试表明,对于大多数模型规模——包括 Llama 3.2 1B、Llama 3 8B、Llama 2 13B 和 Llama 2 7B——早期退出的自推测解码速度快于传统的两模型推测解码。
提前退出的“甜点”
退出层与性能之间存在非线性关系。过早退出会导致准确率低且草拟令牌的接受率低;过晚退出则会增加草拟阶段的计算开销。对于大多数模型,存在一个“甜点”,在此点上预测准确性与生成开销之间的权衡得到优化,以实现每秒最大令牌数。
模型特定结果
- Llama 2 70B:虽然相比自回归解码速度显著提升,但与其他模型相比,其加速效果更有限,这可能是因为其持续预训练所使用的标记更少(328M 个标记),而 Llama 2 7B 变体使用了 52B 个标记。
- Baseline Models:未使用 LayerSkip 配方进行训练的模型不会看到加速,因为它们的早期层未被训练来预测输出,导致令牌接受率非常低。
与 Transformers 的集成
自推测解码已集成到 Hugging Face 的 transformers 库中。通过在 generate() 函数中添加 assistant_early_exit 参数,即可启用该功能,前提是模型检查点已经使用 LayerSkip 配方进行训练。