AI 开发者必须了解的4种LLM缓存
AI 系统中有 4 种不同的缓存机制,它们位于不同的层级。其中三种主要决定了你浪费多少计算资源和资金。
梯形图转SCL | AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo
你可能认为你的 LLM 很慢,因为模型太大了。你可能认为你的 AI 账单很高,因为你发送了太多令牌。这两个假设都可能是错误的。
你的应用程序可能正在为重新计算已完成的工作付费。
相同的系统提示、相同的指令、相同的文档,有时甚至是相同的问题。
直到我开始更深入地研究这个技术栈,我才意识到:"LLM 缓存"并不是一种机制。
AI 系统中有 4 种不同的缓存机制,它们位于不同的层级。其中三种主要决定了你浪费多少计算资源和资金。
第四种可能会返回一个看起来完全成功但实际上是错误的答案。
一旦你理解了每种缓存的所在位置、它实际重用的内容以及缓存未命中时会发生什么,调试昂贵或缓慢的 LLM 应用就会变成一个完全不同的问题。
让我们逐一分析这四种缓存。
0、放大前的全局视图

第 1 到 3 层实际上是在三个不同范围内的同一个概念。第 4 层则完全不同,我稍后会解释原因。

1、KV 缓存

每次 LLM 生成一个令牌时,它都需要之前令牌的信息。
如果你有一个 1,000 个令牌的提示,而模型正在生成答案的第 1,000 个令牌,模型仍然需要考虑之前的上下文。为每个新令牌从头开始做所有这些工作将是巨大的浪费。
KV 缓存就是避免这种重复工作的机制。
当模型处理每个令牌时,其注意力层会产生两个信息,称为键(K)和值(V)。模型不会在处理完令牌后丢弃它们,而是将它们保存在 GPU 内存中。
当下一个令牌生成时,模型会重用已处理令牌的存储键和值。

模型仍然为每个生成的令牌执行新的计算。重要的节省在于它不会为所有先前的令牌重复计算注意力信息。
这就是为什么 KV 缓存对实际的自回归生成至关重要。
但存在一个权衡:
缓存必须存储在某个地方,通常是 GPU 内存,而且它随着序列变长而增长。
短提示可能需要很少的 KV 缓存内存。长对话、大文档或许多并发请求可能需要大量内存。
因此你面临一个根本性的权衡:

这就是长上下文推理是一个基础设施问题的原因之一,而不仅仅是给模型更大的上下文窗口。
这也是接下来三种缓存的关键边界
KV 缓存通常属于一个活动序列/请求。完成请求后,该缓存状态通常不能被全新请求自动重用。
因此,如果你在五秒钟后在全新请求中再次提出完全相同的问题,服务系统通常必须重新处理该提示。
这就是下一层变得有趣的地方。
KV 缓存保存活动请求内的重复计算。前缀缓存提出了一个更大的问题:如果我们能在不同请求之间重用该计算呢?
这种区别是通向第 2 层的桥梁。
2、前缀缓存

假设 200 个不同的用户都打开一个支持聊天,他们的系统指令完全相同。如果不共享,模型将毫无理由地重复执行这些相同的指令 200 次。
前缀缓存就是解决方案。服务系统不会在请求结束时立即丢弃 KV 缓存,而是保留它并建立索引,这样下一个以相同令牌开头的请求就可以重用它。
请求 A:[系统提示] + "退货政策是什么?"
请求 B:[系统提示] + "你们发货到加拿大吗?"
相同的系统提示令牌在前面。
支持前缀缓存的服务引擎会重用该共享部分,
只计算之后的内容。
这里有一个容易让人措手不及的地方:重用仅在之前的令牌完全匹配时才有效。不是接近,不是相似,而是完全相同,逐个令牌匹配。
vLLM 等引擎通过将令牌序列切分成固定块来实现这一点,其中每个块的身份取决于它之前的所有块。
这种链接使其成为真正的前缀匹配,而不是松散的巧合集合。这也意味着开头的一个不匹配令牌会破坏其后的所有内容。
适用场景: 任何许多请求共享真实开头的流量,如通用系统提示。缺点:这些缓存块与你的实时运行请求位于同一内存池中,因此在高负载下,系统会驱逐较旧的缓存条目,而这正是你最希望它们保留的时候。而且它只能加速提示的读取。
它对模型编写答案所需的时间没有任何作用。
3、提示缓存

提示缓存是 Anthropic 和 OpenAI 通过其 API 暴露的功能。与第 2 层相同的理念,运行在提供商自己的服务器上,不同之处在于你现在可以设置缓存边界,并获得一个收据告诉你是否成功。
在 Anthropic 的 API 上,你可以用缓存断点标记可重用部分的结尾,通常是你的系统指令或大型参考文档。第一次包含该内容的调用需要支付写入溢价: 5 分钟缓存为正常输入价格的 1.25 倍,或 1 小时缓存为 2 倍。
在此窗口内命中相同缓存内容的每次后续调用仅支付 0.1 倍,即该部分的 90% 折扣。
这就是人们算错账的地方,而且代价高昂:
5 分钟缓存(基础输入价格的倍数)
完全不缓存 ........... 两次调用 2.0x
写入 + 1 次读取 ............ 1.35x <- 已经比什么都不做便宜
写入 + 9 次读取 ........... 十次调用 2.15x(vs 10x 未缓存)
1 小时缓存
写入 + 1 次读取 ............ 2.1x <- 比完全跳过缓存更差
写入 + 2 次读取 ........... 三次调用约 2.2x(vs 3x 未缓存)<- 现在它赢了
5 分钟缓存在一次命中后就能收回成本。
1 小时缓存需要两次命中才开始有价值。
如果你的流量在该窗口内没有现实地重复相同的前缀两次,你就是在为没有任何好处而支付溢价。
我见过人们认为缓存一旦启用就能自动省钱。如果流量在窗口内从不重复前缀,那就不是这样。在假设这对你有帮助之前,请先查看你的实际使用数据。
这里的故障模式几乎总是自找的。任何放在缓存边界之前但每个请求都会变化的内容——时间戳、用户 ID、实时搜索结果——都会静默地杀死其后的所有读取。切换模型、切换网络搜索,甚至更改推理努力设置都会重写底层提示文本并在没有任何警告的情况下破坏缓存。总结聊天历史以节省令牌也会产生同样的效果,因为摘要就是新文本,而旧前缀不再匹配。
4、语义缓存

以上所有内容都只是节省计算资源。它们永远不会改变你得到的答案。这一层完全打破了这个规则,这正是为什么它值得比其他三层加起来更多的怀疑。
语义缓存存储已完成的答案,而不是注意力计算。新问题进来后,被转换为称为嵌入的数值表示,并与已回答问题的嵌入进行比较。清除相似度阈值后,你会在没有模型调用的情况下获得旧答案。
这很强大,因为它节省了输入令牌和模型本会生成的输出令牌。但也有风险,因为"相似含义"和"相同的正确答案"不是一回事,而且它们之间的差距比大多数人假设的要小。
这就是它实际崩溃的地方:
"如何重置我的密码?" -> 真正的释义,相同答案有效
vs "我怎么重置密码?"
"API 有速率限制吗?"
vs "API 没有速率限制吗?" -> 一个词(否定)翻转了答案
"年度计划的退款政策"
vs "月度计划的退款政策" -> 一个操作细节翻转了答案
令人不安的是,以上三对在相似度上得分非常接近,通常在百分之一以内。 如果设置阈值足够宽松以捕获真正的释义,它也会捕获一些这样的陷阱。
如果设置足够严格以避开陷阱,你将拒绝很多真正的释义,同时仍然为每个请求支付嵌入检查的费用,无论是否命中。
这里的错误匹配不会抛出错误。它返回一个正常、看起来健康的响应。输出中没有任何内容告诉你答案可能是错的。在我希望在任何低风险 FAQ 流量之外启用此功能之前,我要将这一点烙印在任何人的记忆中。
5、值得记住的一句话
这四种缓存中有三种只能在未命中时让你付出更多代价。第四种可能让你出错,这是两个问题中唯一不会在你的账单中显示出来的一个。
6、当感觉不对劲时首先查看什么

不要首先尝试语义缓存。这是唯一一个可能让你的产品变差的层,而不仅仅是变慢或更贵。如果你使用托管 API,请从提示缓存开始。这是四种中工作量最小的,最坏的情况是浪费金钱,而不是错误答案。
7、今天检查什么
打开你的 API 使用情况,查看调用报告缓存读取而不是缓存写入的频率。如果该数字接近零,缓存并没有为你节省任何东西。你在支付溢价并称之为优化。
开头提到的那个支持机器人不需要更智能的模型。
它需要有人注意到它第四百次回答同一个问题,却从未因此获得过任何折扣。
原文链接:4 LLM Caches Every AI Developer Needs to Know Before Your Bill Explodes
汇智网翻译整理,转载请标明出处