跳转至

KV 稀疏化

算法维度(横向)之二:在已经训练好的模型上,推理时丢掉一部分 KV,以降低显存占用和读带宽压力。

与 Attention 变体 的区别:那里改的是模型本身的结构,本章讨论的是给定模型不变,在推理阶段动态决定哪些 K/V 可以扔掉。

1. 为什么可以丢

经验观察:attention 分布是高度稀疏的——大部分 query 对大部分 key 的 attention 权重接近 0。如果能识别出"对未来 decode 几乎不影响"的 K/V,丢掉它们对最终输出影响有限。

剪枝粒度可以分四类:

粒度 操作 代表方法
Token 级 丢掉序列中某些 token 的 K/V StreamingLLM、H2O、SnapKV、Scissorhands
Head 级 不同 head 重要性不同,丢掉次要 head 的 K/V Ada-KV、MoA
Layer 级 跨层共享 K/V 或跳过部分层的缓存 YOCO、CLA
基于 query 的动态稀疏 每个 decode 步只读一小部分相关 K/V Quest、Loki、RetrievalAttention

2. Token 级稀疏

Attention sink + 滑动窗口(StreamingLLM)

观察:模型在前 \(k\) 个 token("attention sink")上集中了大量 attention 概率,简单丢弃会让分布塌陷。

策略:永久保留前 \(k\) 个 token + 滑动窗口最近 \(w\) 个 token,中间的全部丢掉。 代价:长程依赖可能丢失,适合"短期局部依赖为主"的对话场景。

重要性评分驱动(H2O / Heavy-Hitter Oracle)

观察:少数 token("heavy hitters")在 attention 中被频繁高分关注,它们的 K/V 不能丢。

策略:用累积 attention 分数为每个 token 打分,保留 top-K 个高分 token,其余驱逐。 工程难点:

  • 评分需要在线维护,不能太重
  • 与 paged 内存管理的整合:被剪掉的 K/V 释放后,块复用策略要重新设计
  • 长序列下评分窗口的滑动逻辑

代表论文:H2O (2023)。

提示驱动(SnapKV)

观察:在 prefill 完成时,可以从最后几个 prefill token 的 attention 模式预测整个 prompt 中哪些 token 会被 decode 频繁关注。

策略:prefill 结束时一次性筛掉不重要的 K/V,进入 decode 时 KV 已是"瘦身版"。 优点:实现简单,与 paged attention 兼容性好。 代价:依赖 prefill 末尾的 attention 是否真能反映 decode 期间的需求——RAG / Coding 等场景可能不准。

代表论文:SnapKV (2024)。

3. Head 级稀疏

观察:同一层不同 attention head 的"信息容量"差异巨大,部分 head 高度重复或承担"分发"角色。

策略:

  • 离线:用校准集评估每个 head 的重要性,对低重要性的 head 进行更激进的压缩或丢弃
  • 在线:保留 head 数量随上下文长度自适应变化

代价:与 GQA / MLA 的"绑定"——head 已经被压缩过的模型上,进一步 head 级剪枝空间有限。

代表论文:Ada-KV (2024)。

4. Layer 级稀疏

YOCO(You Only Cache Once)

策略:只在少数几层真正缓存 K/V,其余层共享或重计算。 效果:KVCache 体积可下降一个数量级。 代价:需要从训练阶段就考虑这一架构(属于"半改架构、半改运行时")。

代表论文:YOCO (2024)、CLA (Cross-Layer Attention)。

5. 基于 query 的动态稀疏

前面几类是与 query 无关的剪枝——一次决定哪些 K/V 留下。Query-aware 的方法每个 decode 步都重新选 K/V:

Quest

每个 decode 步:

  1. 把 KV 划成块,为每块计算一个紧凑的"摘要"(min/max/平均向量)
  2. 用 query 与摘要做粗筛,选出 top-\(k\) 个块
  3. 只对选中的块做完整 attention

效果:每步只读 \(k\) 个块的 K/V,HBM 带宽压力大幅下降。 难点:摘要质量、top-\(k\) 阈值、块大小选择。

代表论文:Quest (2024)、Loki、RetrievalAttention。

6. 稀疏化在系统层面的代价

理论上稀疏可以让 KV 变小,但工程上有几个常见陷阱:

陷阱 描述
与 paged 内存管理的不兼容 被剪掉的 K/V 在块内位置不连续,要么留空(碎片)要么压实(额外搬运)
prefix cache 的语义破坏 跨请求 prefix 相同但稀疏决策不同 → 物理 KV 不一致,无法复用
kernel 改写成本 稀疏 attention 需要 indirection,kernel 复杂度上升、效率下降
质量回归不易评估 短任务上看不出差异,长任务、多轮、reasoning 上才暴露问题

工业落地里 SWA + attention sink 是最稳的,token 级重要性剪枝在特定场景部署,layer/head 级和 query-aware 还多停留在论文阶段。

7. HiSparse:稀疏注意力后的内存系统

HiSparse 的关键判断是:top-k sparse attention 只减少"每步计算哪些 KV",没有自动减少"哪些 KV 必须常驻 HBM"。在 GLM-5.1-FP8、32K input + 8K output、8xH200、256 并发场景中,baseline sparse attention 很快被 HBM 容量卡住;HiSparse 通过 hot device buffer + host inactive KV + swap-in kernel,使高并发长上下文吞吐超过 baseline 3 倍,部分配置最高约 5 倍。

组件 作用 调优边界
hot device buffer HBM 中保留当前 top-k 更可能访问的 KV buffer 越小 miss 越多,buffer 越大容量收益越小
host inactive KV 把非活跃 KV 下沉到 CPU memory 依赖 CPU-GPU 带宽与 sparse locality
swap-in kernel 在 decode 路径中识别 miss、更新 page table、搬回 KV miss 频繁时会直接落在 decode critical path

HiSparse 适合高并发、长上下文、sparse pattern 有局部性的 decode 侧;低并发或短上下文下,主动 offload 只会增加 I/O。它和 Offload 的差别在于:offload 的对象由 sparse attention 当前访问集合驱动,而不是由会话空闲或 LRU 单独决定。

来源:主站 reading HiSparse:稀疏注意力真正缺的那层内存系统

8. 推理型负载:逐出不是压缩的同义词

reasoning / CoT 负载暴露了永久逐出的硬边界:DeepSeek-R1-Distill-Qwen-7B 在 GSM8K 上把 50% KV 永久逐出时,准确率可从 71% 崩到 2.5% 或 0%。语义感知内存层级的实验显示,准确率主要由永久逐出比例决定,而不是由 HBM 中保留比例决定;把低重要性 token 全精度 offload 到 DDR 再预取回来,可以在释放约一半 HBM 的同时保留 91.5% 的 baseline 准确率。

这意味着 reasoning 场景里应区分三种动作:

动作 信息是否保留 适合场景
Evict 否 只适合确定不再需要的 token,比例必须极低
Offload 是,全精度搬家 CoT / reasoning token 的默认安全路线
Quantize 是,低精度 需要 reasoning-aware 校准,8-bit 也可能不稳

来源:主站 reading 推理的 KV 逐出是一场灾难

关联章节

版本历史

版本 日期 说明
v0.2 2026-06-02 新增 HiSparse 分层稀疏内存系统与 reasoning 负载中逐出/搬家/量化的边界
v0.1 2026-05-14 框架搭建