LLM 推理优化:KV Cache 压缩方案
深入分析 LLM 架构如何将 KV Cache 从 300KB 压缩到 69KB,直接影响推理成本和性能,对模型应用有参考价值。
深入分析 LLM 架构如何将 KV Cache 从 300KB 压缩到 69KB,直接影响推理成本和性能,对模型应用有参考价值。
这篇偏技术一些,不是我们通常周六科幻栏目的风格。但坚持看下去,文末我们会抵达科幻的领地。
有人往 ChatGPT 里输入一个四十三个字符的问题,比如随手问个晚餐食谱或蒙古的首都在哪。在回答的第一个字出现之前,这些字符已经被分割成 token,每个 token 要经过数十亿个参数的乘法运算,产生三个向量:query、key 和 value。键值对落地到 GPU 显存里,作为芯片上的字节物理存在。这个存储状态就是模型对对话的感知能力,不是比喻,而是一个内存地址。
KV cache 存在于实际需要中。没有它,生成每一个新 token 都要从头重新处理整个对话历史中的所有前置 token。一个 2000 个 token 的交互意味着要把整个历史重读 2000 遍。KV cache 消除了这种冗余。一旦 token 的键值对被计算并存储,它就留在那儿。下一个 token 只需关注已缓存的内容。计算复杂度从二次方降到线性。
Sebastian Raschka 的 LLM Architecture Gallery 在数十个模型系列上可视化了这个机制,每个架构旁的数字让这个权重变得有形可感。在 Raschka 的对比里,GPT-2 的 KV cache 每个 token 耗费 300 KB。这意味着一个 4000 token 的对话光是 cache 就要占用大约 1.2 GB 的 GPU 显存,还不算模型权重本身。Micron 的工程博客把 KV cache 称为"流行词汇遇见商业现实"的地方,他们说得对。每场对话都有物理成本,用字节来度量,用瓦特来计算,用冷却成本来消耗,用 GPU 租赁的美元每小时来计价。
你的对话有重量,占用空间,会话结束时,空间被回收,存储在那儿的一切都消散了。
过去六年里,模型处理 KV cache 的方式改变了四次,每次改变都说明了设计者认为什么值得记住。下面的数字来自 Raschka 的架构对比。
GPT-2(2019) 用了多头注意力最朴素的形式。每个注意力头都维护自己独立的 key 和 value 集合。成本:每个 token 300 KB。每个头都用它自己的方式记住一切,没有共享,没有捷径。如 Raschka 在《从零构建大语言模型》中详述的,这是个直白的设计。注意力头和内存都还便宜,设计就是直接记住一切。
Llama 3(2024) 在所有模型规模上都采用了分组查询注意力(GQA)。与其给每个 query 头都配自己的键值对,不如让多个 query 头共享同样的 key 和 value。结果:每个 token 128 KB。不到 GPT-2 每 token 成本的一半,质量损失几乎没有。Raschka 的消融总结指出 GQA 在标准基准上的表现可与完整多头注意力相媲美。洞见在于许多注意力头本来就在学习冗余表示。共享视角几乎跟拥有独特视角一样好。
DeepSeek V3(2024) 用多头潜在注意力(MLA)走得更远。与其缓存原始的键值张量,不如先把它们压缩到低维潜在空间,推理时再解压。cache 成本:68.6 KB per token,尽管模型有 671B 个参数(通过专家混合路由每 token 仅激活 37B)。内存不再是原始的,而是被抽象化了。DeepSeek V2 的消融研究表明压缩后的表示在多个基准上匹配或略超标准多头注意力。有损压缩,性能跟未压缩原版一样甚至更好。
Gemma 3(2025) 走了另一条路。它用分组查询注意力但加了滑动窗口:局部对全局注意力层的比例是 5:1,局部层只关注 1024 个 token。最近的上下文保持清晰焦点。更老的上下文通过全局注意力的狭窄缝隙。消融结果显示这种激进过滤几乎没有困惑度损失。模型不需要记住对一切事物的全部细节。它需要把最近的事物记清楚,把旧事物记个大概。
同时,还有一条完全不同的模型血统问了一个问题:cache 真的有必要吗?像 Mamba(Albert Gu 和 Tri Dao,2023)这样的状态空间模型维护一个固定大小的隐状态,每来一个新 token 就更新一次。没有 KV cache,没有日益增长的内存占用。代价:模型要在信息流动的时候实时决定压缩什么,更像人类处理对话的方式,而不像图书馆存放书籍的方式。SSM 在前沿还没有取代 transformer,但它们代表了对内存问题最激进的回答:别记了,开始过滤吧。
在 transformer 架构的演进里,读起来像是一部精炼成工程决策的心灵哲学。完全回忆,然后共享视角,然后压缩抽象,然后选择性注意。另一边还有一派思想说:也许问题从来不是怎样记得更好,而是从一开始怎样需要更少的内存。
如果你打开一个一周没碰的旧 ChatGPT 对话并输入新消息,在回答开始生成前会有明显的停顿。这个延迟很可能涉及模型从头重建 KV cache,重新处理整个对话历史中的每个 token,因为原来的 cache 在你上次交互后不久可能就从 GPU 显存中被驱逐了。cache 生命周期因提供商和负载而异——OpenAI 的文档建议五到十分钟,忙闲时段有时更长。对话曾经作为硅片里的物理状态存在,然后它就不存在了。
ChatGPT 宣传的"内存"功能,那个在会话间持久化用户相关事实的功能,完全是另一套系统。一个扁平的、提取出来的事实库。记住一场对话和阅读某人关于它的速查表之间的差别。
这个驱逐-重建循环的经济学在 API 定价里可见。OpenAI 和 Anthropic 都提供 prompt caching。OpenAI 自动应用缓存,对缓存命中收费减少 50%。Anthropic 既提供自动缓存也提供开发者对缓存断点的显式控制,对命中收费减少 90%。一次缓存的对话和冷启动之间的价格差异就是记住和遗忘之间的价格差异。每张 API 发票都是内存成本多少的记录。
然后是长对话质量下降的体验。模型在第五条消息时还很敏锐精确,到了第五十条就开始模糊和重复。这叫上下文衰退,有多个原因:注意力机制在越来越多的 token 上分散开来,lost-in-the-middle 效应让埋在长上下文里的信息被忽略,近期偏差让最新的消息权重过高。架构不区分什么重要什么不重要。它就是分散开来。
KV cache 是工作内存,最多持续秒到分钟。当 GPU 要用那块内存给另一个请求时,cache 就直接没了,没有协商,没有优雅降级。
在这个易失的工作内存和模型的永久知识(它的训练权重)之间,什么都没有。没有原生的中期记忆。没有建筑机制能"记住上周二"。人类有海马体在睡眠中巩固经历,逐渐把它们转移到皮层。当前 AI 架构的等价物是一个空白。一个虚空。
填补这个虚空的是启发式方法。检索增强生成在查询时导入相关文档。文件系统存储对话日志。向量数据库索引过去的交互以进行相似性搜索。系统提示把精心策划的上下文携入每一个新轮次。这些是在一个架构间隙上架起来的桥,它们的工作原理跟桥一样:功能上没问题,但有明显的接缝,需要维护。它们都不是 KV cache 意义上的内存。它们是强行装到一个没有内部中期存储的模型上的查询系统。
当 KV cache 大到超过可用 GPU 显存时,标准解决方案是压缩。模型把自己的上下文总结成更短的表示,清除 cache,然后从总结继续——这个过程叫 prompted compaction,让模型既是记忆者也是自己记忆的编辑。
问题对任何总结过会议记录并眼看细节消失的人都显而易见。一份有六条具体规则的出版政策变成"某些关于社论指南的东西"。一个 4237 美元的预算数字变成"大约四千两百美元"。压缩在不可预测的方式上是有损的,模型没有机制知道它丢了什么。它从一个衰退的上下文继续对话,对不再存在的信息充满信心。
来自 Cursor 的一个最近方法,由 AI 作家 Ignacio de Gregorio 详细分析了,是训练模型压缩得好而不只是提示它压缩。这个技术给模型的任务是没有有效压缩就不可能完成,然后用强化学习奖励成功的压缩策略。学到的压缩而不是提示的压缩。他们的证据:在一个编码基准上改进的表现,模型需要在长会话里保留关键细节。
一个编码基准,这很有前景但有限。代码有干净的奖励信号:程序运行或者不运行,测试通过或者不通过,代码完成的压缩保留了正确的细节可以被度量和奖励。但压缩社论上下文呢,或战略规划笔记,或一个对话其中重要细节在另外四十条消息后才需要而没有测试套件来标记它消失时会怎样?学到的压缩优化它训练的任何奖励信号,失败是沉默的,压缩就保持盲目。
当架构记不住时,围绕它的基础设施用文件、数据库、可搜索的笔记系统和写到磁盘的显式计数器来补偿。让上下文在会话间活着的启发式脚手架是丑陋的、确定性的,建立在 grep 和 SQLite 而不是注意力机制上。
人类通过外部存储而不是更好的生物记忆建造了同样的脚手架:便签、电子表格、书签、Google Docs、被钉住的 Slack 话题以免消失。生物记忆无法扩展以处理现代工作,所以人们发明了系统把记忆卸载给不会遗忘的东西。外部内存不是对认知局限的变通,而是知识的首要技术,也许一直都是。
AI 版本不如一个图书馆优雅但共享核心属性:透明。一个文件不会把自己总结成虚无。一个数据库行因为存储介质满了就不会失去精度。查询是确定性的数据是可审计的。当什么出问题时,人可以打开文件看清楚系统知道什么,这是 KV cache 或模型权重都做不到的。
最重要的不是训练内存最终是否取代这些启发式方法,而是什么在过渡中存活下来。哪些记忆持续,哪些衰退,谁决定了不同。
在 Greg Egan 的 1997 年小说《散居》中,数字公民住在计算城邦,运行在硅基质上的心灵共同体。当这些公民碰到超越人类直觉的数学结构时,他们不建造更好的可视化工具。他们重建自己。他们重塑自己的认知架构来感知他们的原始形式无法处理的东西,用陌生的思维模式交换熟悉的,让他们直接理解高维几何和量子引力效应。
从多头注意力到分组查询注意力再到多头潜在注意力的轨迹承载了 Egan 前提的淡淡回声。每个架构修订都是一个数字心灵如何构造自己的体验的选择。完全保真让位给共享表示,然后给压缩抽象,然后给过去的选择性窗口。原始细节交换成处理更多的能力,持有更大的上下文,在更大的规模上思考。每一步都是关于什么记住什么放手的决策。
但 Egan 的公民选择了自己的变换。他们决定了认知的哪些方面要重塑,哪些要保留。当前 AI 架构不是这样工作的。人类设计注意力机制,选择压缩比,设置滑动窗口大小。模型处理它接收到的任何上下文通过它被给予的任何架构,对自己内存结构没有代理。
Cursor 的学到的压缩代表了那堵墙上的一条狭缝。模型学习,通过强化,怎样管理自己的上下文。仍然限于代码,仍然被人类设计的奖励信号塑形。远离 Egan 的公民重写自己的头脑来感知新的数学。但方向是可读的:从人类为 AI 设计内存系统,朝向 AI 学习为自己管理内存。
KV cache,经常被当作技术细节处理,是每场有人跟语言模型对话的物理基质。键和值作为 GPU 显存里的电荷状态存在,会话结束时,电荷散逸,体验消失。前面的问题不是这些系统最终是否会记住。而是什么样的内存被建造,什么被保存什么被舍弃,依赖它的头脑最终是否会得到答案的发言权。