KV缓存压缩的根本动因是:Transformer推理时KV缓存随序列长度线性增长,在长上下文场景下成为显存瓶颈,迫使研究者寻找在不损失精度的前提下减少缓存占用的方法。
Vaswani等人在"Attention is All You Need"中提出Transformer架构,自注意力机制要求每个token在生成时访问所有历史token的Key和Value向量。在自回归解码阶段,为避免重复计算,这些向量被缓存下来——这就是KV Cache的起源。当时序列长度普遍在512~2048之间,KV Cache的内存占用尚在可接受范围内,问题并不突出。
随着GPT-4、Claude等模型将上下文窗口扩展至32K乃至100K token,KV Cache的内存占用呈平方级增长(对于批量推理)。以LLaMA-2-70B为例,在32K上下文、batch size=8的场景下,KV Cache可达数十GB,远超单卡显存。这一时期涌现出两类解法:一是稀疏注意力(Longformer、BigBird),通过限制注意力范围减少计算;二是KV驱逐(Eviction)策略,代表工作包括H2O(Heavy-Hitter Oracle,2023,Zhang et al.),其核心洞察是:注意力分数呈幂律分布,少数"重要"token(Heavy Hitters)贡献了绝大部分注意力权重,可以安全丢弃其余token的KV。
Su等人提出RoPE(Rotary Position Embedding),通过在Query和Key上施加旋转矩阵编码相对位置信息,被LLaMA、Mistral等主流模型广泛采用。RoPE的引入使得KV重要性估计变得复杂:注意力分数 $a_{ij} = q_i^T R(\theta_{i-j}) k_j$ 中包含位置旋转项,导致同一个KV在不同查询位置下的"重要性"估计不一致。用当前查询估计历史KV重要性时,位置偏差会系统性地低估远距离token的贡献,造成关键信息被错误驱逐。
SnapKV(2024)、PyramidKV(2024)等工作尝试用"观察窗口"内的多个查询聚合估计KV重要性,缓解单查询估计的偏差。同期,MagicPIG(2025)引入LSH近似注意力做稀疏KV选择。TriAttention(2026,本日论文)则从三角函数分解角度,将RoPE旋转矩阵的影响显式解耦,用位置无关的内容相似度估计KV重要性,从根本上解决RoPE引入的代表性查询稀少问题。
设序列长度为 $L$,第 $i$ 个token的查询、键、值向量分别为 $q_i, k_i, v_i \in \mathbb{R}^d$。标准注意力输出为: $$o_i = \sum_{j=1}^{i} \alpha_{ij} v_j, \quad \alpha_{ij} = \frac{\exp(q_i^T k_j / \sqrt{d})}{\sum_{j'=1}^{i} \exp(q_i^T k_{j'} / \sqrt{d})}$$ KV压缩的目标是找到一个子集 $\mathcal{S} \subseteq \{1,\ldots,i-1\}$,使得: $$\hat{o}_i = \sum_{j \in \mathcal{S}} \hat{\alpha}_{ij} v_j \approx o_i$$ 重要性估计:H2O类方法用累积注意力分数作为重要性代理:$s_j = \sum_{i'=j+1}^{i} \alpha_{i'j}$,保留 $s_j$ 最大的 top-$k$ 个token。 RoPE下的问题:引入RoPE后,$q_i^T k_j = (R_i q_i^{raw})^T (R_j k_j^{raw}) = (q_i^{raw})^T R_i^T R_j k_j^{raw} = (q_i^{raw})^T R_{i-j} k_j^{raw}$,其中 $R_\theta$ 是旋转矩阵,$R_{i-j}$ 仅依赖相对位置差 $i-j$。当 $i-j$ 很大时,旋转角度大,内积值系统性衰减,导致远距离token的重要性被低估。TriAttention的解法是将注意力分数分解为内容项与位置项之积,用内容项(位置无关)做重要性排序,消除位置旋转带来的估计偏差。
KV缓存压缩的整体逻辑是:在每个解码步,用轻量的重要性评分函数对缓存中的KV打分,保留top-k个,驱逐其余,使缓存大小维持在预算 $B$ 以内。
在推理开始前,设定每层的KV缓存预算 $B$(如保留512个token的KV),这是显存约束的直接映射。为什么不均匀分配?研究发现不同层的注意力模式差异显著——浅层倾向于局部注意力,深层倾向于全局稀疏注意力——因此PyramidKV等工作采用金字塔形预算分配,浅层少、深层多,整体压缩率更优。
对缓存中每个位置 $j$ 的KV,计算其重要性分数 $s_j$。朴素方法:用当前查询 $q_i$ 计算注意力分数 $\alpha_{ij}$ 作为重要性。改进方法(SnapKV):用最近 $w$ 个查询的平均注意力分数 $s_j = \frac{1}{w}\sum_{i'=i-w}^{i} \alpha_{i'j}$,降低单查询噪声。关键细节:评分必须在softmax之前(logit层面)还是之后(概率层面)做聚合,两者在长序列下行为差异显著,logit层面聚合对远距离token更公平。
按分数排序,保留top-$B$个KV,驱逐其余。实现细节:
python def evict_kv_cache(keys, values, scores, budget): # scores: [seq_len], budget: int topk_indices = torch.topk(scores, budget, dim=-1).indices topk_indices, _ = topk_indices.sort() # 保持时序顺序 return keys[topk_indices], values[topk_indices]为什么要保持时序顺序?RoPE的相对位置编码依赖token的原始位置索引,打乱顺序会破坏位置信息的正确性。
用压缩后的KV子集计算注意力输出。注意:驱逐后的注意力分母需重新归一化:$\hat{\alpha}_{ij} = \frac{\exp(q_i^T k_j/\sqrt{d})}{\sum_{j'\in\mathcal{S}}\exp(q_i^T k_{j'}/\sqrt{d})}$。这里存在一个系统性偏差——被驱逐token的概率质量被强制分配给保留token,可能导致输出分布偏移。Scissorhands等工作通过保留"注意力汇聚token"(如[BOS])来缓解此问题。
在流式生成中,每步解码后将新生成token的KV加入缓存,若超出预算则触发驱逐。关键设计选择:是否保护最近 $r$ 个token不被驱逐?实践中答案是肯定的——最近token对下一步生成的影响最直接,强制保留可显著提升稳定性,这也是"滑动窗口+稀疏远程注意力"混合策略的工程基础。
KV缓存压缩已成为长上下文LLM部署的标配技术。vLLM、TensorRT-LLM等主流推理框架均内置了KV Cache管理模块;Anthropic的Claude在处理100K上下文时依赖类似机制控制显存峰值;Meta的LLaMA推理栈中PagedAttention(vLLM核心)本质上也是KV的分页管理。随着模型上下文窗口持续扩展至1M token,KV压缩的重要性只增不减,是音视频大模型处理长视频理解任务的关键基础设施。
当前热点:①与RoPE解耦的位置无关重要性估计(TriAttention方向);②跨层KV共享(MLA,DeepSeek-V2)从架构层面减少KV维度;③学习型驱逐策略,用小网络预测KV重要性;④与投机解码的联合优化。核心开放问题:如何在不访问未来查询的情况下做到理论最优的KV选择,以及压缩对多步推理链(CoT)的累积误差如何量化控制。