Prompt Caching
缓存是什么意思
大模型的接口服务商,有的会提供缓存功能,用于存储用户请求的上下文信息,以便在后续的请求中复用。这样可以减少模型计算量(省钱),提高响应速度,同时也可以提高模型的可用性和稳定性,这是什么意思?
- 当你发送一个超长的 messages 列表时,API 服务商(如 Anthropic 或 OpenAI)并不会直接把它丢给模型,而是先对你的输入进行 哈希(Hash)计算。
Prefix Matching(前缀匹配): 如果你这次发送的 5000 个 Token 中,前 4500 个和 5 分钟前发送的那一轮完全一模一样,后端服务器就会发现:“嘿,这部分我刚才计算过(计算过 KV Cache)!”- 重用计算结果: 服务器直接从内存里调出这 4500 个 Token 产生的中间状态(KV Cache),只对新增加的 500 个 Token 进行推理。
在 API 商的视角里,Token 的成本分为两部分:
- 计算成本(最贵): 模型要把文本转化成数学向量并进行复杂的矩阵运算。
- 存储/读取成本(较便宜): 只是把已经算好的数据从内存里读出来。
与消息压缩有什么区别
本质区别:压缩是丢弃信息来省钱(你能记住大意,但一定丢掉了细节,比如变量名);缓存是利用重复信息来省钱。
- 缓存(
Prompt Caching):“无损的瞬间移动” 缓存是基于 Prefix(前缀) 的键值对存储。它的逻辑是:
- 精细度:它是 Token 级别的。只要前 个 Token 没变,它就直接复用。
- 原始数据:完全保留。模型依然能看到每一个原始字符,没有任何信息丢失。
- 本质:它压缩的是“计算量”和“金钱成本”,而不是信息本身。
- 局限性:缓存有“物理极限”。如果对话真的达到了 200k 甚至 1M Token,即便有缓存,模型处理起来也会变慢,且容易在长距离推理中产生“迷路”(
Lost in the Middle)。
- 消息压缩(
Context Compression):“有损的记忆提炼” 当缓存也救不了(比如上下文快爆了,或者成本太高)时,上下文压缩 才会上场。
- 精细度:它是 语义级别的。它会把原始的 1000 行 ls 结果,替换成一句 [此处省略了 xx 目录下的文件列表,包含 main.py 等]。
- 原始数据:永久丢失。一旦压缩完成,原始的细节就再也找不回来了。
- 本质:它模拟的是人类的“长期记忆提炼”。你记得昨天吃了一顿大餐(压缩后的信息),但你可能忘了那盘菜里有几颗葱花(丢失的原始数据)。
缓存是让服务器“记住”它刚才算出来的 KV Cache(中间数学状态),这是一种物理意义上的保留。消息压缩是让 AI 或程序员通过逻辑“总结”出 核心意义(Summary)。这是一种语义意义上的保留。
什么是中间数学状态
缓存存的不是“理解后的文字总结”(那就成压缩了),而是矩阵运算的中间数值。
在大模型中,第 个 Token 的计算,只取决于它前面的 个 Token。计算过程:当模型处理第 500 个 Token 时,它的注意力机制(Attention)只会向后看(Look-back)前 499 个 Token 的向量。单向依赖:第 501 个 Token 的出现,完全不会影响前 500 个 Token 已经计算出来的隐藏层状态(Hidden States)。换句话说: 在 Transformer 的自注意力层中,每一个 Token 的 K(Key) 和 V(Value) 向量一旦算出来,只要前面的输入不变,这些向量就永远不会变。这就是所谓的 KV Cache。
重特性:幂等性 这也就是为什么它能省钱: 因为服务器省下了前 500 个 Token 那些昂贵的矩阵乘法( 映射)。
只要你改动了前缀里的任何一个字符(哪怕是一个空格),数学上的等价性就瞬间崩塌:
- 因为
Transformer的位置编码(Positional Encoding)会变。 - 注意力权重会因为那个微小的改动而重新分配。
- 此时,旧的
KV Cache全都作废,必须全额付费重新计算。
这就是为什么我们要反复强调要保护前缀的稳定性
Temp=0还是注意力锚点
在 时,数学确定性 = 语义唯一性。在前缀完全一致且 的前提下:“从第 1 个 Token 重新生成”与“从第 501 个 Token 开始续写”,在数学和语义上会得到完全、彻底、逐字一致的结果。
不存在“重新跑一遍可能会选另一个近义词”的情况,因为模型在那个时间点看到的概率分布是由前面的 Token 矩阵决定的,而矩阵运算在同样的硬件环境下是幂等的(结果一致)。
所以对于编程和 Agent 这种任务,通常会将 Temperature 设为 0(或者极低)。
这里应该是讲偏了,temp影响的是“生成”,历史消息一旦产生,就从“生成”的输出变成“输入”了,输入的语义不会因为temp而改变。
所以缓存真正的作用是固化一些隐形约束/前提/人格/设定,因为这些不会因为你后续的多轮对话而改变,而且不需要反复把它投入计算。其它作用真不是为了怕重新计算一次会偏移,而是为了节省计算资源。当然客观上也避免了模糊注意力,所以“对注意力的影响”是远大于temp的影响的。
由于没有物理层面的“存档”,模型每次都要试图在巨大的矩阵中重新寻找“重点”。随着轮次增加,原始指令(System Prompt)的权重在 softmax 归一化过程中会被海量的历史报错和中间过程“摊薄”。
大模型工程最核心的“第一性原理”:缓存(Prompt Caching)在本质上并不是一个存储工具,而是一个“注意力锚点(Attention Anchor)
怎么缓存
对输入按一定大小进行切片,比如1024,然后对切片进行哈希,作为key,值是从第一个chunk起到这一个chunk为止计算的kv矩阵,这是啥?
在 Transformer 的注意力机制 中,、、 分别是 Query、Key 和 Value 向量。这个计算过程是相对耗时的,因此可以通过缓存来加速。
上面说的“数学中间态”就是这个kv矩阵,新的token从这个chunk开始,一直取到最后,进行prefill,生成新的kv矩阵拼接在缓存矩阵后面,此时才开始Decoding,预测下一个token
直到此时,temp的影响才开始出现,但它影响的可能只是行文风格,语气什么的了。
总之,缓存的意思是(从头开始)到哪个位置可以不去计算,然后拼上后面的(新)内容接着计算。