重新思考生产推理中的 KV 缓存管理

你以为模型越便宜,推理成本就会一路下降?很多团队已经被现实狠狠打脸:token 单价跌了 80%,账单却翻倍。问题往往不在模型,而在你怎么管理上下文和 KV 缓存。要是继续无脑把所有历史和文档一股脑塞给模型,预算迟早会炸。接下来这套思路,能帮你重新审视生产环境里的推理流水线。

斯坦福研究人员分析了真实 AI 代理的调用数据,发现一个扎心的事实:每次请求中大约 62% 的内容是重复的。系统提示、工具定义、长文档,这些东西在每一步代理行动时都会被原封不动地重新发送。

换句话说,代理刚刚读完一遍“说明书”,下一步操作时你又让它从头读一遍。对开发者来说,这些内容看起来是“必要上下文”;对 GPU 来说,就是一遍又一遍做同样的矩阵乘法。

示意图

从 2023 到 2026 年,GPT-4 级别模型的价格从每百万 token 30 美元跌到 0.40 美元,看起来像是“白菜价时代”。但代理工作流每个任务消耗的 token,往往是普通聊天问答的 5 到 30 倍,因为每一步都重新发送整段上下文。

结果就是:单个 token 便宜了,总费用却被用量的爆炸式增长吃掉。有用户反馈,他们在迁移到“更便宜”的模型后,月度账单不降反升,原因就是引入了复杂的多步代理。

Uber 的案例很典型。工程团队在全公司推开 Claude Code 后,只用了 4 个月就烧光了 2026 年的全年 AI 预算。Gartner 甚至预测,到 2027 年会有 40% 的 AI 代理项目因为成本失控被砍掉。

行业这几年一直在死磕“降低 token 单价”,却很少认真问一句:这些 token 里,有多少本来就不该被算费?

有点反直觉:真正决定成本的,不是模型的“标价”,而是你有没有把重复计算的那一大块切掉。

接下来要聊的,就是一个把缓存管理彻底从推理引擎里“拆”出去的开源架构——LMCache,它改变的不是模型,而是你和模型打交道的方式。

LMCache 动图

有团队在生产上接入这套架构后,首次 token 生成时间提速约 14 倍。说实话,这种量级的提升,已经不只是“省点钱”,而是能直接改变你敢不敢上更大模型的决策。


模型内部到底在算什么:KV 缓存的真实代价

注意力、Key/Value 和那堆被丢掉的张量

每次你给模型发一段提示,模型都会对每个 token 跑一遍注意力机制。对每个 token、每一层注意力,它都会算出一个 Key 向量和一个 Value 向量,用来表示这个 token 和上下文里其他 token 的关系。

KV 缓存示意

这整套 Key/Value 向量,就是我们常说的 KV 缓存。注意力计算的复杂度会随着输入长度近似按平方级增长,长上下文一上来,算力就被拖垮。

计算复杂度图

一块 MI300X GPU 一天大概会生成 15 TB 的 KV 缓存数据,但绝大多数在请求结束后就被直接丢弃。系统提示的 KV 缓存每次都是一样的,上传文档的 KV 缓存在同一用户会话里也几乎不变,可模型每次都从零开始重新理解。

这就像有人问你“第七章的细节”,你每次都从第一页把整本教材重读一遍。你明明已经理解了前六章,却没有一个机制能把这种“理解状态”保存下来复用。

前缀缓存:有用,但远没到“终极解”

业界早就意识到这个问题,于是出现了各种提示缓存(prompt caching)方案。思路很直接:如果两个连续请求的开头 token 完全一样,就把第一次算出来的 KV 缓存存起来,第二次直接复用,模型只需要对新增的 token 做计算。

前缀缓存示意

Anthropic 的内部实现数据显示,这种前缀缓存可以让缓存命中的输入 token 成本降低约 90%。在系统提示和工具定义比较稳定的场景,命中率能做到 60%–85%,对很多团队来说已经是“最划算的一刀”。

问题在于,前缀缓存有一个非常硬的约束:被缓存的部分必须是新请求的字节级完全前缀。只要中间多了一个空格、换了一个文档顺序,整段缓存就作废。

前缀缓存限制示意

常见的“踩坑”场景包括:

  • 多文档 RAG:你分别缓存了文档 A 和文档 B。新查询需要 A+B 时,B 的缓存状态无效,因为它当初计算时没看到 A。
  • 文档顺序变化:同样的三个文档,顺序一变,之前所有排列对应的缓存都互不通用。
  • 对话历史增长:每轮对话都会改变后续上下文,之前缓存的 KV 状态很快就失去复用价值。

缓存命中分布

阿里云的生产数据给了一个很直观的数字:只有 10% 的 KV 缓存块贡献了 77% 的命中率,大部分缓存内容几乎从未被复用。严格的前缀匹配规则,让很多“理论上可复用”的计算在实践中被浪费掉。

换个角度看,前缀缓存更像是“长系统提示优化器”,而不是通用的 KV 复用方案。

如果你的工作负载上下文结构高度动态,单靠前缀缓存,很难把成本压到你想象中的水平。


性能的隐形杀手:缓存和推理抢同一块资源

推理引擎内置缓存的资源争用问题

几乎所有主流推理引擎的 KV 缓存库,都是在引擎进程内部运行的。听上去很方便,但代价是:缓存操作(存、取、移动 KV 张量)和真正的推理计算要抢同一套资源。

资源争用示意

在这种架构下,缓存 I/O 和矩阵乘法没法真正并行:引擎忙着搬 KV 张量时,推理就得等;推理在跑大算子时,缓存又被挂起。Google 的 TurboQuant 就是一个典型例子,它把 KV 缓存压缩到每值 3 bit 且几乎无精度损失,但在推理引擎内执行时,整体推理速度反而下降了 20% 以上。

本质上,缓存管理是 I/O 密集型工作,要在 GPU、CPU 和存储之间搬运大块张量;推理服务则是计算密集型,要把 GPU 算力压榨到极致。把这两种负载绑死在一个进程里,很难不互相拖后腿。

我之前帮一支团队排查延迟抖动问题,最后发现瓶颈不是模型本身,而是高并发下缓存搬运把 GPU 的 PCIe 带宽打满了,推理算子被迫排队,那一刻大家才意识到“缓存也会拖慢模型”。

LMCache:把缓存从引擎里“拆”出去

LMCache 是一个 GitHub 上超过 1 万星的开源项目,走的是完全不同的路线:不再让推理引擎自己管缓存,而是把缓存管理做成一个独立进程,与引擎并行运行。

LMCache 架构图

在实际部署中,LMCache 通过共享 GPU 内存与推理引擎连接。引擎只需要发一个很小的消息:“我要这些块 ID”,而不需要自己搬运大张量。

所有在 GPU、CPU、本地 SSD、远程存储之间移动 KV 张量的重活,都由 LMCache 自己的进程负责。推理引擎只管算,不再被 I/O 细节拖住手脚。

LMCache 优势

这种分离式架构带来三类直接收益:

  • 无资源争用:缓存 I/O 不再阻塞推理,推理也不会卡住缓存。像 TurboQuant 那种“优化 KV 却损失 20% 吞吐”的情况,在分离架构下基本消失。
  • 跨 GPU 零拷贝共享:传统做法要在两个 GPU 之间共享缓存,需要多次内存拷贝;LMCache 允许多个 GPU 直接读写同一片共享内存区域,绕过中间拷贝环节。
  • 多层并行加载:缓存可以分布在 GPU 内存、CPU 内存、本地 SSD、远程对象存储上。传统方案往往逐层检查,速度被最慢那层拖住;LMCache 会同时向多层发起请求,并行流式拉取数据。

在 H200 GPU 上跑 Qwen3-235B,50 并发用户场景下,LMCache 把首次 token 生成时间加速到原来的约 1/14,解码速度也提升到约 4 倍,模型启动时间从 3 分钟多压缩到 30 秒左右。

更现实的一点是,LMCache 已经支持 vLLM、SGLang、TensorRT-LLM 等主流推理引擎,也兼容 NVIDIA 和 AMD GPU。你不用推倒重来,只要在现有推理服务旁边多挂一块“缓存侧车”。


CacheBlend:打破“前缀”这条隐形锁链

多文档、多轮对话,为什么前缀缓存总是失效

LMCache 解决了缓存和推理抢资源的问题,但前面提到的另一个痛点还在:多文档查询、文档顺序变化、对话历史增长,这些场景下前缀缓存命中率依旧惨淡。

LMCache 团队在一篇名为 CacheBlend 的论文里给出了一种新思路,这篇论文拿到了 EuroSys 2025 最佳论文奖。核心观察是:在现代 Transformer 模型里,大多数 token 的注意力主要集中在局部上下文,只有少数 token 会跨文档边界产生强关联。

换句话说,模型并不是对“所有 token 和所有其他 token”都一样上心。真正需要“跨文档重算”的,只是那一小撮关键位置。

CacheBlend 的做法:只重算真正重要的 token

CacheBlend 示意

CacheBlend 的策略是:

  • 先从各个文档的独立缓存中加载它们各自的 KV 状态;
  • 分析哪些 token 在跨文档注意力上最关键,把它们标记出来;
  • 只对这部分关键 token 重新计算注意力,让模型“补上”跨文档理解;
  • 其余大部分 token 的 KV 直接复用原缓存,不再重算。

这样一来,多文档 RAG 之类的场景就不需要把所有文档拼成一个长前缀再从头算一遍,而是以极小的额外计算成本,恢复模型对文档之间关系的理解。

实验结果显示,在多文档查询场景下,CacheBlend 能把处理速度提升到原来的 2–4 倍,同时几乎不牺牲输出质量。有一位使用者的反馈挺有代表性:他们在接入 CacheBlend 后,RAG 查询的平均延迟从 3 秒多降到 1 秒出头,用户主观体验变化非常明显。

我也不太确定这个说法对不对,但从这些数据看,真正的“增量”不在于再压缩多少 bit,而在于敢不敢承认:不是所有 token 都值得被同等对待。


生产环境落地:LMCache 的工程化细节

监控、部署和故障恢复

LMCache 不是只在论文里好看的一次性原型,而是带着完整工程配套的生产级组件:

  • 内置 Prometheus 和 OpenTelemetry 集成,可以监控缓存命中率、I/O 吞吐、延迟分布等关键指标;
  • 提供 Kubernetes Operator,方便在集群里做弹性扩缩容和滚动升级;
  • 附带命令行工具,用于本地调试、压测和对比不同缓存策略的收益。

在可靠性上,它也做了不少“兜底设计”。如果推理引擎崩溃,LMCache 会把缓存数据保存在 CPU 内存和持久化存储里,引擎重启后可以直接复用,不必重新“热身”长上下文。

如果 LMCache 自己挂了,推理引擎会自动进入降级模式,暂时关闭缓存但继续提供推理服务,等缓存进程恢复后再自动接回。任何一方出问题,都不会把整个系统一起拖死。

有用户在一次机房网络抖动事故中验证了这一点:缓存节点短暂失联,推理服务只是延迟略有上升,并没有出现大面积 5xx。

什么时候你真的该上 LMCache

很多团队会问:我到底需不需要这么一套“重型”缓存系统?可以用下面这几个信号做个快速判断:

  • 单次请求上下文经常超过几千 token,且包含大量重复的系统提示、工具定义或文档;
  • 使用多步代理、复杂 RAG、代码助手等场景,单任务 token 消耗远高于普通聊天;
  • GPU 利用率不稳定,经常出现“算力没跑满,但延迟很高”的情况;
  • AI 成本在整体云成本中的占比持续上升,且预算压力已经传导到业务层面。

如果你在其中两三条上点头,LMCache 这类分离式 KV 缓存架构,基本值得认真评估。它带来的不是一个小优化,而是对“怎么用大模型”这件事的重新设计。

我自己接触过的几个团队,在引入 LMCache 后,最大的感受不是“省了多少钱”,而是终于敢在生产上用更大的模型、更长的上下文,而不用每天盯着账单心惊肉跳。


这个判断 KV 缓存是否值得重构的思路,在不少团队里已经被反复验证有效。你可以先收藏起来,等下次预算评审或架构升级时拿出来对照一下。如果你正准备上马一个多代理、多文档的复杂系统,这篇内容往往比问身边人“你们用什么模型”更有用。


常见问题

Q:我的应用只是普通聊天问答,有必要上 LMCache 吗?

A:如果你的场景主要是短对话、上下文长度有限,LMCache 的收益会相对有限。原因在于,KV 缓存的优势在长上下文和高重复度场景里才会被放大,短对话中重复计算本身就不多。更实际的做法是先用模型提供商自带的前缀缓存或简单的系统提示优化,把上下文控制在合理长度,再观察 GPU 利用率和成本曲线。如果未来引入多轮长对话、RAG 或代理工作流,再考虑迁移到 LMCache 这类分离式架构会更划算。

Q:LMCache 会不会增加系统复杂度,反而带来新的故障点?

A:引入 LMCache 确实会多一个独立服务,但它通过降级模式和持久化缓存,把风险控制在可接受范围内。推理引擎在 LMCache 故障时会自动关闭缓存功能,继续提供基础推理服务,不会直接宕机。你可以在早期用灰度方式接入,比如只让一部分流量走 LMCache,配合 Prometheus 和 OpenTelemetry 监控命中率、延迟和错误率,再逐步扩大覆盖面。上线前做一次压力测试和故障演练,是非常值得的投入。

Q:CacheBlend 会不会影响模型输出质量,尤其是多文档 RAG 场景?

A:在公开实验中,CacheBlend 在多文档查询上的输出质量几乎与全量重算持平,同时带来 2–4 倍的速度提升。原因是它只对跨文档注意力最关键的那部分 token 重新计算,而保留了大部分局部上下文的原始 KV 状态。为了在你的业务里更放心使用,建议先选一批典型查询样本,分别跑“无缓存、前缀缓存、CacheBlend”三种模式,对比准确率、召回率和人工评审结果。如果发现某些任务对跨文档细节极度敏感,可以针对这些任务单独配置更保守的缓存策略。

Q:如何判断是该优化提示工程,还是该上 KV 缓存架构?

A:可以从“重复度”和“复杂度”两个维度来判断。若你发现大量请求共享相同的系统提示、工具定义或文档片段,且这些内容难以再精简,说明重复度高,适合用 KV 缓存来节省计算。如果上下文结构简单、主要问题是提示写得冗长,那先做提示工程优化更划算。一个实用做法是:先用日志统计每次请求的上下文长度和重复片段比例,再用火焰图或性能分析工具看 GPU 时间花在哪些阶段,据此决定是先“减肥”(精简提示)还是先“增肌”(上缓存架构)。

Q:LMCache 对多 GPU、跨机房部署有什么特别要求吗?

A:在单机多 GPU 场景下,LMCache 可以通过共享 GPU 内存实现零拷贝共享,对部署要求不高,只要驱动和推理引擎版本兼容即可。跨机房或跨可用区部署时,主要风险在网络延迟和带宽瓶颈,因为缓存数据可能需要在不同节点之间流动。建议把 LMCache 部署在尽量靠近推理 GPU 的位置,优先保证同机或同可用区内访问,并对远程存储层做带宽和延迟监控。如果必须跨区域共享缓存,可以考虑只在远端保留冷数据,把热数据限制在本地节点,以免网络抖动放大延迟波动。


很多人以为“模型越来越便宜,一切都会自然变好”,但真正拉开差距的,往往是这些看起来有点“工程味”的细节。你可以慢慢试,不必一口吃成胖子,但别忽略了这块潜在的巨大杠杆。