技术深度解析
KV缓存利用了Transformer架构的一个基本特性:注意力机制基于查询与所有键之间的相似度,计算值的加权和。在自回归生成中,序列一次只增长一个词元。没有缓存,每个新词元都会导致模型重新计算所有先前词元的键和值——这是巨大的浪费,因为这些张量与上一步计算的结果完全相同。
工作原理: 在第一次前向传播(预填充阶段)中,模型并行处理整个输入提示,计算每一层的所有中间键张量和值张量。这些张量存储在GPU内存中。在随后的解码阶段,对于每个新词元,模型仅计算该词元的查询,并针对缓存的键和值执行注意力操作。新词元自身的键和值随后追加到缓存中。这使每词元浮点运算从O(n²)降至O(n),其中n是序列长度。
内存占用: 缓存大小随批次大小、序列长度、层数和隐藏维度线性增长。对于一个80层、隐藏维度8192、32位精度的700亿参数模型,每个词元消耗约80 × 8192 × 2 × 4字节 = 5.2 MB。32K词元上下文需要约170 GB缓存内存——远超单张A100的80 GB。这就是为什么内存管理是首要瓶颈。
优化技术:
- PagedAttention(vLLM): 受操作系统虚拟内存启发,它将KV缓存划分为固定大小的块(页面),可以非连续存储。这消除了碎片,并实现了跨请求的高效内存共享。开源vLLM仓库(GitHub超过30,000颗星)实现了这一技术,吞吐量比朴素缓存提升2-4倍。
- 多查询注意力(MQA)和分组查询注意力(GQA): 这些架构修改减少了键和值头相对于查询头的数量。Llama 2和3使用GQA,配备8个KV头和32个查询头,缓存内存减少4倍,质量损失极小。
- KV缓存量化: 以8位或4位精度存储键和值,内存减少2-4倍。KIVI和Atom等技术使用逐通道和逐词元量化来保持准确性。基准测试显示,量化到8位时,MMLU上的准确率下降不到1%。
- 滑动窗口缓存: Mistral的方法仅保留最近词元(例如4096个)在缓存中,丢弃更早的词元。这限制了内存使用,同时通过辅助注意力机制保留长距离依赖。
性能数据:
| 模型 | 缓存策略 | 延迟(毫秒/词元) | 吞吐量(词元/秒) | 内存(32K上下文,GB) |
|---|---|---|---|---|
| Llama 2 70B | 朴素全缓存 | 85 | 12 | 170 |
| Llama 2 70B | PagedAttention | 22 | 45 | 95 |
| Llama 3 70B | GQA + 8位量化 | 18 | 55 | 48 |
| Mistral 7B | 滑动窗口(4K) | 8 | 125 | 6 |
| Falcon 180B | 朴素全缓存 | 210 | 5 | 440 |
数据要点: PagedAttention和GQA结合可将内存降低40-70%,同时吞吐量提升3-5倍。架构变化与缓存优化的结合对于大规模服务大型模型至关重要。
主要玩家与案例研究
OpenAI: GPT-4和GPT-4o使用KV缓存的专有变体,结合多头注意力。虽然确切架构未公开,但推理延迟基准显示GPT-4o在短上下文中达到约30毫秒/词元,表明采用了激进缓存,可能还有推测解码。OpenAI的API定价——每百万输入词元5美元,每百万输出词元15美元——反映了缓存带来的成本节约,输出词元价格是输入的3倍,因为顺序解码是瓶颈。
Anthropic: Claude 3.5 Sonnet使用200K词元上下文窗口,这只有借助高级KV缓存管理才可行。Anthropic已发表关于缓存感知注意力的研究,可能结合了滑动窗口和量化。其API收费为每百万输入词元3美元,每百万输出词元15美元,输出溢价5倍。
Mistral AI: Mistral 7B和Mixtral 8x7B推广了滑动窗口缓存,仅保留最近4096个词元。这使得7B模型能在单张24 GB显存的RTX 4090上运行,实现本地部署。Mistral的开源发布在GitHub上获得超过12,000颗星,广泛用于边缘应用。
Meta: Llama 3 70B和405B使用分组查询注意力,配备8个KV头,这是为了减少缓存内存而刻意做出的架构选择。Meta的研究论文明确指出选择GQA是为了提高推理效率。Llama 3.1 405B模型拥有128K上下文窗口,可能结合了GQA、8位量化和PagedAttention风格的内存管理。
vLLM(UC Berkeley): 开源vLLM库实现了PagedAttention。