一个70亿参数的语言模型,在处理128K上下文时,光是KV Cache就要占用约40GB显存——这还没有算上模型权重本身。当大模型的上下文窗口从4K扩展到128K甚至更长时,一个看似不可逾越的障碍横亘在研究者和工程师面前:KV Cache的内存占用随序列长度线性增长,迅速吞噬有限的GPU显存。
然而,2023年到2024年间,一系列创新性的压缩技术相继涌现,彻底改变了这一困境。从MIT韩松实验室的StreamingLLM发现"注意力锚点"现象,到H2O提出的"重击者"驱逐策略,再到KIVI和KVQuant的极低比特量化——这些技术共同构成了一套完整的KV Cache压缩工具箱,使得百万级token的超长上下文推理从理论走向现实。
KV Cache:被忽视的内存怪兽
要理解KV Cache压缩的紧迫性,首先需要明白它为什么会成为大模型推理的主要瓶颈。
在Transformer的自回归生成过程中,每生成一个新token,模型都需要访问之前所有token的Key和Value向量。为了避免重复计算,这些向量被缓存到GPU显存中,形成所谓的KV Cache。对于一个具有$L$层、隐藏维度$d$、注意力头数$h$的模型,处理序列长度为$n$的输入时,KV Cache的显存占用为:
$$\text{Memory} = 2 \times L \times n \times d \times \text{sizeof}(\text{float16})$$以LLaMA-2-70B为例,假设$L=80$、$d=8192$(考虑GQA后的有效维度),处理128K上下文时:
$$\text{Memory} = 2 \times 80 \times 131072 \times 8192 \times 2 \text{ bytes} \approx 40 \text{ GB}$$这个数字意味着,即使使用80GB显存的A100 GPU,模型权重和KV Cache加在一起也会撑爆显存。更糟糕的是,随着批量大小和序列长度的增加,KV Cache的占用呈线性增长,迅速成为制约吞吐量的核心瓶颈。
对于不同规模模型在不同上下文长度下的KV Cache内存占用,可以参考LMCache提供的KV Cache计算器。对于70B模型,128K上下文需要约40GB,而256K上下文更是超过80GB,已经超出了单卡A100的承载能力。
Attention Sink:一个反直觉的发现
2023年9月,MIT韩松实验室在论文《Efficient Streaming Language Models with Attention Sinks》中揭示了一个令人惊讶的现象:当使用滑动窗口注意力(Window Attention)限制KV Cache大小时,模型会在窗口起始位置突然崩溃——即使被驱逐的只是几个无关紧要的初始token。
研究团队通过可视化注意力分布发现了一个反直觉的事实:模型对序列开头的几个token给予了异常高的注意力分数,即使这些token在语义上毫无重要性。
以Llama-2-7B为例,在前两层之后,所有注意力头都会将大量注意力权重分配给第一个token(通常是<s>或BOS token)。这种模式在不同模型、不同任务中普遍存在。
为什么会这样?论文给出的解释触及了Softmax函数的本质。Softmax要求所有注意力权重之和为1:
$$\text{softmax}(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}}$$当当前查询向量与历史token都没有强匹配时,模型仍需将这些"多余的"注意力权重"倾倒"到某些token上。由于自回归语言的因果特性,初始token对所有后续位置都可见,因此更容易被训练成这种"注意力锚点"(Attention Sink)。
2025年4月,牛津大学和Meta AI的研究团队在论文《Why do LLMs attend to the first token?》中进一步深入分析了这一现象,指出Attention Sink机制实际上是模型用来避免"过度混合"(over-mixing)的一种方式,这与信息在Transformer中传播的数学特性密切相关。
基于这一发现,StreamingLLM提出了一个简单而有效的解决方案:保留前几个token的KV Cache作为锚点,同时维护一个滑动窗口保留最近的token。
KV Cache = [Attention Sinks (4 tokens)] + [Rolling Cache (recent tokens)]
这种方法使得模型能够在有限KV Cache大小下处理任意长度的输入,在Llama-2、MPT、Falcon等模型上实现了400万token的稳定推理,相比滑动窗口重计算基线实现了最高22.2倍的加速。
Heavy Hitter:识别真正重要的token
StreamingLLM的发现揭示了一个重要问题:并非所有token都对模型推理同等重要。2023年6月,在StreamingLLM发表之前,另一篇论文《H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models》就提出了更具一般性的解决方案。
H2O的核心观察是:注意力矩阵的高度稀疏性。研究团队发现,即使模型是密集训练的,推理时的注意力矩阵稀疏度仍超过95%。这意味着,每个生成步骤实际上只需要访问约5%的历史KV Cache。
更深入的分析揭示了"Heavy Hitter"(重击者)的存在:一小部分token累积获得了大部分注意力权重。这些Heavy Hitter与文本中频繁共现的词存在强相关性,暗示它们承载了关键的上下文信息。
H2O提出的驱逐策略结合了两类token:
- Heavy Hitters:累积注意力分数最高的token
- Recent tokens:最近生成的token
算法维护一个固定大小的缓存,动态平衡这两类token的比例。当缓存已满需要驱逐时,选择累积注意力分数最低的token进行驱逐。
# H2O驱逐策略伪代码
def h2o_eviction(cache, budget):
# budget分为heavy_hitter部分和recent部分
hh_budget = budget * 0.2 # 20%给heavy hitters
recent_budget = budget * 0.8 # 80%给recent tokens
# 保留累积注意力分数最高的hh_budget个token
heavy_hitters = top_k(accumulated_attention, hh_budget)
# 保留最近的recent_budget个token
recent = last_n_tokens(recent_budget)
return merge(heavy_hitters, recent)
实验结果显示,H2O仅使用20%的KV Cache预算,就能在OPT、LLaMA、GPT-NeoX等多种模型上达到与完整KV Cache相当的性能。在系统层面,H2O相比DeepSpeed、HuggingFace Accelerate和FlexGen分别实现了最高29倍、29倍和3倍的吞吐量提升。
TOVA:更简洁的驱逐策略
2024年1月,Meta AI和特拉维夫大学的研究团队在论文《Transformers are Multi-State RNNs》中提出了TOVA(Token Omission Via Attention)策略。这篇论文从一个新颖的视角重新审视了Transformer架构:解码器-only Transformer本质上可以被视为具有无限隐藏状态的多状态RNN。
当限制KV Cache大小时,Transformer就变成了有限状态RNN。TOVA的核心思想是:不需要区分heavy hitters和recent tokens,只需根据注意力分数决定驱逐哪个token。
TOVA的驱逐策略极其简洁:
def tova_eviction(cache, budget):
# 计算每个token的平均注意力分数
avg_attention = mean_attention_score_per_token()
# 驱逐注意力分数最低的token
evicted = argmin(avg_attention)
return cache - evicted
实验表明,TOVA在长上下文任务上优于StreamingLLM和H2O。使用仅1/8的原始缓存大小,TOVA就能达到与完整模型相当的性能,转化为4.8倍的吞吐量提升。
量化:从精度压缩到内存压缩
驱逐策略通过减少存储的token数量来压缩KV Cache,而量化则通过降低数值精度来实现压缩。两条技术路线可以正交结合,实现更高的压缩比。
KIVI:非对称的2比特量化
2024年2月,威斯康星大学麦迪逊分校的团队在论文《KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache》中系统研究了KV Cache的元素分布特性,发现了Key和Value在量化上的根本差异:
Key Cache:元素的分布在不同通道间差异巨大,某些通道存在显著的异常值。这意味着通道内量化(Per-Channel Quantization)更为合适——同一通道的元素共享量化参数。
Value Cache:元素的分布在同一token内相对均匀,适合按token量化(Per-Token Quantization)。
基于这一分析,KIVI提出了非对称量化策略:
- Key Cache:按通道量化到2比特
- Value Cache:按token量化到2比特
同时,KIVI引入了一个小的FP16缓冲区来处理最近的token,避免量化误差的累积。
实验结果表明,KIVI在不损失精度的前提下,将内存占用减少2.6倍,吞吐量提升2.35到3.47倍。更关键的是,KIVI无需任何微调或校准,可以直接应用于预训练模型。
KVQuant:向千万级上下文迈进
2024年12月,加州大学伯克利分校的研究团队在NeurIPS 2024上发表了《KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization》,将KV Cache量化推向了新的高度。
KVQuant的核心贡献包括:
-
Pre-RoPE Key Quantization:对RoPE旋转位置编码之前的Key进行量化,避免了旋转后数值分布的复杂性
-
非均匀量化(Non-Uniform Quantization):针对KV Cache的非均匀分布设计专门的量化区间
-
密集-稀疏混合量化:对异常值采用稀疏存储,对正常值采用密集量化
这些技术的结合使得KVQuant能够在2比特精度下保持与FP16相当的性能,同时支持高达1000万token的上下文推理。相比KIVI,KVQuant在相同精度下实现了1.5倍的额外压缩。
层间共享与动态预算分配
除了在token维度和精度维度上的压缩,研究者还探索了更深层次的优化空间。
跨层KV Cache共享
2024年的一项研究发现,相邻Transformer层的KV Cache存在高度相似性。基于这一观察,Cross-Layer Attention(CLA)和MiniCache等技术提出在相邻层之间共享KV Cache,将内存占用减少近一半。
这种方法需要修改模型架构或进行微调,因此在预训练阶段的应用更为广泛。DeepSeek-V2和YOCO(You Only Cache Once)等模型就采用了类似的设计理念。
金字塔式预算分配
PyramidKV和Ada-KV等技术指出,不同层的KV Cache对模型性能的影响不同。浅层更多关注局部信息,深层更多关注全局语义。因此,可以为不同层分配不同的缓存预算:
- 浅层:较小的缓存预算
- 深层:较大的缓存预算
这种"金字塔"式的预算分配在相同总预算下,可以比均匀分配获得更好的性能。
RAG场景的特殊优化
在检索增强生成(RAG)场景中,KV Cache压缩面临着独特的机遇与挑战。
LMCache提出的CacheBlend技术针对RAG中的前缀复用问题进行了优化。传统的Prefix Caching只能复用完全相同的前缀,而CacheBlend允许复用任意位置的KV Cache块,并通过选择性更新机制处理新插入的检索内容。
实验显示,结合LMCache的vLLM在RAG场景下可以实现3-10倍的延迟节省。这对于需要频繁检索和更新的企业级RAG应用具有重要意义。
警惕压缩的陷阱
KV Cache压缩并非免费的午餐。2025年的一项研究《The Pitfalls of KV Cache Compression》揭示了几个容易被忽视的问题:
指令丢失现象:在多指令场景下,某些指令会比其他指令更快地从KV Cache中被驱逐,导致模型"忘记"这些指令。特别是系统提示(System Prompt)容易成为压缩的牺牲品。
性能下降的非均匀性:不同任务对KV Cache压缩的敏感度不同。需要精细推理的任务(如数学问题)比生成任务更脆弱。
驱逐偏置:现有的驱逐策略可能存在对特定类型token的系统性偏置,需要针对性的调整。
研究团队建议在部署KV Cache压缩时,特别注意系统提示的保护,并进行针对具体任务的评估。
工程实践指南
基于上述分析,KV Cache压缩的实践建议如下:
场景选择:
- 长上下文对话:优先考虑StreamingLLM或H2O
- RAG应用:结合LMCache的前缀复用
- 高吞吐量服务:量化+驱逐策略的组合
参数配置:
- 缓存预算:从20%开始,根据任务复杂度调整
- 注意力锚点数量:通常4个足够
- 量化精度:INT8几乎无损,INT4需要谨慎评估
部署策略:
- 监控压缩前后的性能差异
- 保护关键指令和系统提示
- 考虑与Flash Attention的兼容性
从理论到实践的价值
KV Cache压缩技术的演进揭示了一个深刻的工程洞见:在当前的硬件架构下,算法优化往往需要在"存什么"和"存多精"两个维度同时发力。
驱逐策略回答了"存什么"的问题——不是所有token都同等重要,识别并保留关键的Heavy Hitter和Attention Sink,可以在有限空间内最大化信息密度。量化技术回答了"存多精"的问题——数值的存储精度可以远低于训练精度而不显著影响推理质量。
两条技术路线的正交结合,再加上层间共享和动态预算分配等补充优化,共同构成了一套完整的解决方案。从StreamingLLM实现400万token的无限流式推理,到KVQuant支持1000万token的超长上下文,这些突破正在重塑大模型推理的边界。
当然,压缩永远伴随着代价。性能下降的非均匀性、系统提示的丢失风险、不同任务对压缩的敏感度差异——这些都是工程师在实际部署时需要权衡的因素。但总体而言,KV Cache压缩已经从一个学术研究课题,演进为一项不可或缺的工程实践。当下一代大模型将上下文窗口扩展到百万token级别时,这套工具箱将是它们落地的关键基础设施。
参考文献
- Xiao, G., et al. (2024). Efficient Streaming Language Models with Attention Sinks. ICLR.
- Zhang, Z., et al. (2023). H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models. NeurIPS.
- Oren, M., et al. (2024). Transformers are Multi-State RNNs. EMNLP.
- Liu, Z., et al. (2024). KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache. ICML.
- Hooper, C., et al. (2024). KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization. NeurIPS.
- Li, Y., et al. (2024). SnapKV: LLM Knows What You are Looking for Before Generation. arXiv.
- Ge, S., et al. (2024). Model Tells You What to Discard: Adaptive KV Cache Compression for LLMs. ICLR.
- Barbero, F., et al. (2025). Why do LLMs attend to the first token? arXiv.
- Cai, Z. (2024). Awesome-LLM-KV-Cache: A curated list of LLM KV Cache Papers. GitHub.
- LMCache Team. (2024). An Efficient KV Cache Layer for Enterprise-Scale LLM Inference. arXiv.