2.5 KV Cache 压缩三路


文档摘要

2.5 KV Cache 压缩三路 本节摘要:前四节把复用做足了——单请求内不重算、请求间共享块、多轮前缀命中。可显存是硬天花板,复用再聪明也存不下无限历史。显存见底时,只能让缓存本身变小。压缩有三条彼此正交的路:减少 KV 头数(GQA/MQA)、降低存储精度(KV 量化)、少留 token(稀疏化与滑窗)。这一节把每路的原理、收益、质量代价和代表方案讲清,再给一张对比表,最后点回全册主线——显存是缓存最大的成本项,压缩就是直接砍成本。 当显存成为天花板 先把账翻回来。2.2 算过,7B 在 128K 上下文、FP16、低并发下 KV 就要 64GB,已经压过权重;再叠高并发、再叠长多轮(2.4 的命中虽省 Prefill,但缓存实体仍驻显存),单卡迟早见顶。

2.5 KV Cache 压缩三路

本节摘要:前四节把复用做足了——单请求内不重算、请求间共享块、多轮前缀命中。可显存是硬天花板,复用再聪明也存不下无限历史。显存见底时,只能让缓存本身变小。压缩有三条彼此正交的路:减少 KV 头数(GQA/MQA)、降低存储精度(KV 量化)、少留 token(稀疏化与滑窗)。这一节把每路的原理、收益、质量代价和代表方案讲清,再给一张对比表,最后点回全册主线——显存是缓存最大的成本项,压缩就是直接砍成本。

当显存成为天花板

先把账翻回来。2.2 算过,7B 在 128K 上下文、FP16、低并发下 KV 就要 64GB,已经压过权重;再叠高并发、再叠长多轮(2.4 的命中虽省 Prefill,但缓存实体仍驻显存),单卡迟早见顶。PagedAttention 把碎片吃净、RadixAttention 把命中率拉高,它们优化的是"用已有的显存服务更多请求",却不能"变出更多显存"。

到这一步,只剩一条路:让每个 token 的缓存变便宜。公式里能动的因子就那几个——KV 头数、精度字节、序列长。三路压缩恰好一一对应这三个旋钮。它们不提升命中率,而是降低"单位命中"的成本,让同等预算装下更多命中。这是"算力预付、缓存回收"的最后一环:回收不动了,就少预付。

第一路:砍 KV 头数(GQA 与 MQA)

公式里"KV 头数"这一项,在标准多头注意力中和查询头数相等。每多一个 KV 头,每层就要多存两份(K、V)头维度长度的向量。多人查询注意力(MQA)把 KV 头数压到 1——所有查询头共用同一份 K、V;分组查询注意力(GQA)取中间值,把查询头分成若干组,每组共享一个 KV 头(如 64 个查询头配 8 个 KV 头)。

收益是直接的乘法。Llama-2-70B 用 GQA 把 KV 头从 64 砍到 8,KV Cache 体量相对标准多头缩到八分之一——2.2 那张表里 70B 之所以在 128K 也才 40GB,GQA 功不可没。MQA 更狠,可把 KV 头压到 1,缓存再降数倍。

代价在质量。KV 头是注意力的"视角"数量,视角太少,模型捕捉多样关系的能力下降。MQA 在不少任务上会明显掉点,GQA 用"分组"折中,通常把损失压到可忽略。这条路的硬约束是:它写在模型架构里,必须训练时就定,事后很难把已训的多头模型无损改成 GQA。所以它是"新模型设计时的首选投资",不是"线上救火的工具"。代表方案:Llama 2/3 的 GQA、PaLM 的 MQA、Falcon 的 MQA。

第二路:降精度(KV 量化)

精度字节这一项,从 FP16 的 2 字节降到 INT8 的 1 字节,缓存立刻对半;再降到 4-bit、2-bit,还能再砍。原理极简:KV 是连续向量,量化成低位整数存储,使用时反量化为原精度参与注意力。INT8 在多数生成任务上几乎无损,因为注意力对 K、V 的绝对数值精度本就不敏感,吃的是相对排序;4-bit 以下开始有损,尤其伤"精确引用前文"类任务,但靠一小批校准数据往往能救回大半。

这条路的最大优点是"后处理友好"——不用动模型权重、不用重训,上线时换存储类型、在注意力算子入口加反量化即可。它和第一路可叠加:GQA 模型再上 INT8,缓存是八分之一再减半。代表方案:用了 INT8/INT4 KV 的各类推理引擎,以及专门做 2-bit、4-bit KV 量化的研究实现。代价主要是工程复杂度(反量化位置、溢出处理)和低位下的质量兜底。

第三路:少留 token(稀疏化与滑窗)

序列长这一项,前面三节都默认"全留"。可真有那么多 token 都值得缓存吗?滑窗注意力只保留最近 W 个 token 的 KV,更早的一律丢弃,缓存长度被钉死在窗口大小,和总上下文无关——超长流式场景里它能把缓存从"随长度爆炸"变成"恒定上限"。更聪明的是淘汰式稀疏:StreamingLLM 发现注意力离不开开头的少数"锚点" token,于是保留这些 sink token 加最近窗口,中间的按重要性驱逐;H2O 则按注意力得分动态淘汰"水"token,只留"金"token。

收益随窗口策略可变,窗口压得越狠省得越多,超长序列下可达十倍甚至更高。代价也最刺眼:丢掉的历史就是丢掉的信息,需要全局长程依赖的任务(长文档推理、跨段指代)会直接掉点。所以它适合"记近期、丢远古"的流式对话、实时摘要,不适合"通读万言再作答"。实现难度中等,要改注意力掩码或加淘汰策略,且不改变模型本身,多属推理期可调。

三路对比与选型

把三条路摆在一张表里,选型就清楚了:

路线 收益倍数 实现难度 质量风险 适用场景
GQA / MQA(砍 KV 头) 高,4 至 8 倍 高,需架构与重训 低到中,MQA 略损、GQA 可控 新模型设计、长上下文首选投资
KV 量化(降精度) 中,2 倍(INT8)至 4 倍(4bit) 低,后处理可加 低(INT8)到中(4bit 以下) 已训模型快速降本、高并发救火
稀疏 / 滑窗(少留 token) 高且可变,随窗口可达 10 倍+ 中,改注意力或淘汰策略 高,丢长程依赖 超长流式、可丢历史的对话与摘要

三条路彼此正交,可以叠加:一个用 GQA 训练的模型,再上 INT8 量化,必要时再开滑窗,缓存能压到原始的数十分之一。工程上我更倾向"先架构后精度再稀疏"的顺序——GQA 在训练期就把蛋糕做大,量化是上线即用的安全减震,稀疏是最后才动的、会伤质量的杀手锏。

三路叠加的真实账单

把三路叠起来,用 2.2 的 70B 数字算一笔账,能直观看到压缩的复利。70B 在 FP16、128K 下 KV 为 40GB,这一步 GQA 已经在架构里兑现(KV 头只有 8),属于"出厂即压缩"。再叠 INT8 量化,精度字节从 2 降到 1,40GB 直接对半成 20GB。此时若开滑窗、把有效历史钉在最近 8K,序列长从 131072 缩到 8192,KV 再乘 8192/131072 ≈ 1/16,20GB 降到约 1.25GB。三路合力,40GB 压到 1.25GB,是三十二分之一——这就是正交叠加的威力:每路各砍一刀,乘起来才吓人。

反过来用 7B(标准多头、32 个 KV 头)走同一条路:FP16、128K 是 64GB;它没 GQA,第一刀砍不掉,只能靠量化到 INT8 变 32GB,再靠滑窗 8K 变 2GB。比 70B 起点高,但退到同一条滑窗线后两者趋同——说明长上下文下,架构红利(GQA)只在"不滑窗"时拉开差距,一旦都靠滑窗兜底,头数多少不再关键。选型时记住:能上 GQA 的模型,长上下文成本低一大截;只能量化加滑窗的模型,得用更短的窗口换同等显存。

收束:压缩也是回收的一部分

全册的主调是"算力是预付的,缓存是回收的"。前三路复用(单请求、页式、前缀)是"提高回收率",让付过的算力被更多次免单调出;这一节的压缩三路则是"降低预付单价",让每次回收的成本更低。两者方向相反,目标一致:在显存这张有限预算里,塞下尽可能多的有效缓存。

要点一句收尾:显存是缓存最大的成本项,不是模型权重,也不是算力本身。所有设计——PagedAttention 的块管理、RadixAttention 的前缀组织、本章的压缩三路——本质上都是在和这块显存讨价还价。看懂了这笔账,你就握住了理解第 3 章的钥匙:平台级缓存无非是把这套"本地显存复用"搬出单机,做成跨请求、跨时间、按命中计费的云化服务。当复用能被计价、被调度、被售卖,它就从工程技巧升格成一门生意——那是下一章的舞台。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U