kvpress:把 KV cache 压缩做成可插拔的 press 集合
LLM KV cache compression made easy
秒懂
- 它是什么?
- NVIDIA 开源的 kvpress 用 transformers pipeline 把多种 KV cache 压缩方法统一成可替换的 press 对象,本文梳理它的机制、接入方式、DecodingPress 的边界,以及什么时候它并不合适。
- 适合谁用?
- 如果你的场景是长上下文推理、上下文会被多个问题复用,并且你愿意在 transformers 的注意力层上挂一个 press 对象,kvpress 值得先跑一遍它的 Wikipedia notebook,再决定是否接入。如果你的推理栈不是 transformers(例如自研 kernel 或非 PyTorch 运行时),或者你需要压缩发生在训练阶段、需要对压缩后的 cache 做梯度回传,这个库目前不覆盖这些路径。
- 能商用吗?
- 可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 1 天前。
- 用什么语言写的?
- 主要是 Python(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它要解决的是显存,不是速度
README 给出的算术很直白:Llama 3.1-70B 在 float16 下处理 1M tokens,KV cache 可以占到 330GB。这个数字决定了 kvpress 的目标读者不是做短对话应用的人,而是长上下文推理的部署方和研究新压缩方法的作者。KV cache 随序列长度线性增长,权重是固定的,所以显存瓶颈最终落在 cache 上。kvpress 把注意力放在这一块,而不是量化权重或改模型结构。
它的定位也体现在 API 命名上。库把每一种压缩方法叫 press,每个 press 带一个 compression_ratio 属性,用来度量 cache 被压掉多少。这个抽象让方法之间可以互换,也让评测可以复用同一套 pipeline。对于要比较多种压缩策略的研究者,省掉的是每次重写注意力 hook 的工夫。
press 的机制:打分、剪枝、在 prefilling 阶段动手
从 README 列出的类继承关系看,所有 press 都继承 BasePress,其中一批继承 ScorerPress。ScorerPress 的逻辑是给每个 KV 对打一个重要性分数,然后把分数最低的那些剪掉。不同 press 的差别就在分数怎么算。
KnormPress 用 key 的逆范数当分数,对应论文 arXiv 2406.11430。SnapKVPress 用最后若干 query 的平均注意力权重。TOVAPress 只看最后一个 query 的注意力权重,并在 head 之间平均。ObservedAttentionPress 用的是 prefilling 阶段实际观察到的平均注意力权重。ExpectedAttentionPress 算的是生成阶段预期会出现的注意力权重,README 的示例用的就是它。StreamingLLMPress 不走打分路线,直接保留最初和最近的 token。PyramidKVPress 换了一个维度,按层分配 cache 预算,底层给得多、高层给得少。QFilterPress 把 key 投影到 query 向量的主 SVD 分量上来近似注意力分数。LagKVPress 依据的是 KV 的 lag-relative 信息,README 在此处被截断,完整描述需要看源码或论文。
这些方法全部是 training free,也就是说不需要微调模型。代价是压缩决策依赖启发式打分,质量随任务和模型变化,库本身不保证某个 press 在你的数据上不掉点。
接入方式:一个注册好的 pipeline 加一个 press 对象
安装是标准的 pip install kvpress。本地开发用 uv:先 git clone https://github.com/NVIDIA/kvpress.git,进入目录后 uv sync。要装可选依赖则用 uv sync --extra eval --extra flash-attn。
使用路径是 transformers 的自定义 pipeline。导入 kvpress 之后,会注册一个名为 kv-press-text-generation 的 pipeline,它替你处理 chat template 和 tokenization。README 的示例把模型设为 Qwen/Qwen3-8B,device_map 用 auto,dtype 用 auto,然后构造 ExpectedAttentionPress(compression_ratio=0.5),把 context 和可选的 question 一起传给 pipe。返回值取 ["answer"]。
这里有个容易被忽略的细节:示例中压缩只作用在 context token 上。这意味着同一段被压缩的上下文可以拿不同的问题反复查询,评测压缩质量时不用每次重新 prefill。这个设计对做对比实验的人很实用,对只跑一次问答的场景则没有额外收益。
DecodingPress:实验性功能,边界写得很清楚
默认情况下压缩发生在 prefilling 阶段。README 把 decoding 阶段的压缩标为 experimental,通过 DecodingPress 包装器实现。它按固定间隔在生成过程中压缩 cache,参数包括 base_press、compression_interval(默认 512)、target_size(默认 2048)和 hidden_states_buffer_size(默认 256)。
与 prefilling 用 compression_ratio 不同,decoding 用 target_size 表达目标:每过 compression_interval 步压一次,压缩比由系统反推,使压缩后的 cache 大小等于 target_size。这个语义差异不是命名偏好,而是因为生成过程中 cache 在持续增长,固定比例没有固定目标好表达。
限制也很明确。README 指出并非所有 press 都能配合 DecodingPress,原因是 decoding 与 prefilling 的压缩机制有根本差异,只支持 ScorerPress 作为 base_press。此外部分 press 不需要缓存的 hidden states,此时 hidden_states_buffer_size 可以设为 0。如果你的方法依赖 prefilling 阶段观察到的注意力,它大概率不能直接搬到 decoding 路径上。
它不做什么
kvpress 不训练模型,不修改权重,也不提供自己的推理引擎。它挂在 transformers 的注意力实现上,因此继承了后者的约束。README 的 decoding 示例显式指定 attn_implementation 为 flash_attention_2,这提示注意力实现的选择会影响可用性,换实现前需要自行验证。
另一个边界是评测。仓库提供 Hugging Face Space 上的 leaderboard 和 arXiv 论文 2510.00636,但 README 没有给出各 press 在统一基准上的具体数字。也就是说,选哪个 press 不能靠排行榜直接抄答案,得在自己的任务上跑。对于希望开箱即得最优配置的团队,这个库给的是工具箱,不是调好的方案。
还有一点:压缩是有损的。compression_ratio=0.5 意味着丢掉一半 KV 对,长文档问答、多跳推理这类对远距离依赖敏感的任务,掉点风险比摘要类任务高。库不会替你判断这个损失是否可接受。
和手写注意力补丁相比,差别在抽象层
常见的替代做法是直接改 transformers 的注意力模块,在 forward 里插入自己的剪枝逻辑。这条路控制力最强,可以针对具体模型做特化,也不受库的接口约束。代价是每换一个模型架构、每换一次 transformers 版本,补丁都要重新对齐,方法之间也无法横向比较,因为每个补丁的输入输出约定都不一样。
kvpress 选择的是另一层:把压缩方法收敛成 BasePress 和 ScorerPress 两个基类,方法之间的差异被压缩到打分函数里,剪枝逻辑和 pipeline 集成由库负责。好处是换方法只改一行构造代码,坏处是当你的方法不符合打分加剪枝这个范式时,比如需要跨层联合决策或需要修改 cache 的数据布局,基类的约束会变成摩擦。PyramidKVPress 按层分配预算,说明这个抽象还留有一定空间,但它仍然是在 press 框架内实现的。
选择取决于你的目标是产出可比较的实验结果,还是压榨某一个具体模型的最后一点性能。前者适合 kvpress,后者手写补丁更直接。
维护成本与许可
仓库未归档,最近一次 push 是 2026-09-07,最近的发布是 v0.5.4(2026-07-02),此前有 v0.5.3 和 v0.5.2。版本号仍在 0.x,README 也把 decoding 压缩标为实验性,这两点合起来说明 API 存在变动可能。接入前建议锁定版本,并在升级时重跑自己的评测集,而不是只看变更日志。
许可为 Apache-2.0。这意味着可以商用、可以修改、可以再分发,但需要保留版权与许可声明,修改过的文件要标注变更。Apache-2.0 还包含专利授权条款,具体到你的产品和分发方式是否满足要求,属于法律判断,本文不提供法律意见。
依赖方面,kvpress 建立在 transformers 和 PyTorch 之上,可选依赖通过 uv sync --extra eval --extra flash-attn 安装。升级 transformers 主版本时,注意力接口的变化可能影响 press 的行为,这是使用这类挂载式库的固有成本。
编辑结论
如果你的场景是长上下文推理、上下文会被多个问题复用,并且你愿意在 transformers 的注意力层上挂一个 press 对象,kvpress 值得先跑一遍它的 Wikipedia notebook,再决定是否接入。如果你的推理栈不是 transformers(例如自研 kernel 或非 PyTorch 运行时),或者你需要压缩发生在训练阶段、需要对压缩后的 cache 做梯度回传,这个库目前不覆盖这些路径。动手前先确认三件事:目标模型的 attn_implementation 是否与所选 press 兼容(README 的 decoding 示例显式指定了 flash_attention_2)、你要的压缩发生在 prefilling 还是 decoding(后者只支持 ScorerPress 作为 base_press)、以及压缩比在 0.5 这类常见取值下对你任务的答案质量影响。这三点都能在本地用一条 pipeline 调用验证,不需要先读论文。
社区笔记