大模型对话里的 KV 缓存,存的是每个已处理位置的键值对,也就是注意力机制要用的中间表示。复用它,意味着新一轮对话不必把历史内容重新算一遍,只算新增的部分,这是多轮对话保持流畅、成本可控的关键设计。
KV 缓存记的是什么
注意力机制在计算时要为每个位置生成键和值,用来衡量该关注哪些内容、关注多少。这些键值对在预填充阶段算好后就被存起来,构成 KV 缓存的主体,一层一层地累积。
可以把它理解成模型的读书笔记:全文读完后,笔记留下了每个位置该记住的要点,后面引用时翻笔记就行,不用把书重读。笔记越厚,翻查的成本越高,这就是缓存的另一面。
显存里的账可以这样粗算:键值对的总量随层数、每层注意力头数与上下文长度一起放大,模型规格相同,上下文翻一倍,这份笔记的体积就翻一倍。长对话用户感觉不到这份开销,服务端却要为每一轮持续腾地方,用户多聊一句,显存多压一分。这也解释了为什么同类模型的长上下文版本通常按量另计费用。
多轮对话为什么不重算
第一轮结束后,输入与输出已经全部进过缓存。第二轮用户追加一句新话,系统只需要给这个新位置算一份键值对,接在缓存末尾,前面的内容原样躺着,随叫随取。
这就是为什么多轮对话到后面,单轮的计算量并没有跟着轮数暴涨,涨的只是缓存占用的空间。轮数增加的是记忆负担,不是思考负担,这个区分很重要。由此也能解释一个现象:长对话到后期,回答变慢但并不变笨,慢在翻笔记和管理缓存,笨与不笨取决于模型本身,两件事别混在一起评价。
复用要付出的代价
省下计算的代价是空间。缓存要一直留在显存里,长度越长、层数越多、隐藏维度越大,占用的显存就越大。这也是长上下文服务显存吃紧的直接原因,钱花在内存上。
另一个代价是管理复杂度。多个请求同时进行时,谁的缓存先留着、谁该腾地方、什么时候淘汰,需要调度策略参与决策。复用不是无成本的免费午餐,是一笔明码标价的交易。服务方常见的折中是限制单会话的最大长度或轮数,超出就提示开新会话,这并非产品刁难,而是为所有用户保住响应速度。理解了这一点,遇到会话长度上限的提示就不必意外。
什么时候缓存会失效
上下文窗口写满、会话结束、或者用户主动清空历史,缓存都会被释放重来。某些实现里,系统为了腾显存也会提前淘汰冷门的缓存,被淘汰的部分再想用就只能重算。对用户来说,重要的长对话别依赖无限续聊,关键结论及时导出保存,会话一清就什么都找不回来了。
四种释放缓存的情形,处理方式与后果各不相同。
| 触发情形 | 谁触发 | 缓存的下场 | 用户应对 |
|---|---|---|---|
| 上下文窗口写满 | 会话长度到顶 | 释放重来 | 重要长对话别依赖无限续聊 |
| 会话结束 | 用户关闭 | 释放重来 | 关键结论及时导出保存 |
| 主动清空历史 | 用户操作 | 释放重来 | 会话一清就什么都找不回来 |
| 缓存冷门、显存吃紧 | 系统提前淘汰 | 被淘汰的部分再想用只能重算 | 关键结论及时导出保存 |
在 Kimi、腾讯元宝等产品的长对话场景中,缓存策略直接影响长对话的响应表现和稳定性。想了解缓存管理的更多细节,可以读预填充的计算、连续批处理调度和长上下文的显存。
速查表:
- 记的是什么?每个位置的键值对,注意力的中间表示
- 换来什么?多轮对话只算新增,不重算历史
- 付出什么?显存占用随长度持续增长
- 何时失效?窗口写满、会话结束、主动清空或被淘汰
聊聊KV 缓存的常见疑问
- 缓存是不是越大越好?:不是,它占显存,超了会拖垮整个服务,长度与资源要一起规划,留出安全余量。
- 清空对话记录是清缓存吗?:产品层面是开新会话,服务层面对应的就是释放这份缓存重来,历史越长释放越彻底。
- 为什么长对话后期响应变慢?:缓存变长后管理成本上升,叠加显存压力,调度也会变得更谨慎,波动随之而来。


