4/15/2026

LLM缓存详解

 可以把“大模型缓存”理解成:把已经算过的结果(或中间结果)存下来,下次尽量复用。但这里面其实分几层,不只是简单的“问题→答案”缓存。


1️⃣ 常见的几种缓存类型

(1)KV Cache(推理内部缓存)

Transformer 在生成时,会把前面 token 的 Key/Value 向量缓存下来。

  • 本质:避免重复计算 attention

  • 作用:同一请求内部加速

  • 特点:
    👉 只对“同一上下文继续生成”有效
    👉 不跨用户、不跨请求

这类缓存是你体感“流式输出越来越快”的原因之一。


(2)Prompt Cache(提示词缓存)

缓存的是:

相同(或高度相似)的 prompt → 对应的中间表示 / 输出

典型场景:

  • 系统提示词(system prompt)很长

  • 多轮对话里前文基本不变

👉 这里能省掉前缀计算成本(prefill)


(3)Embedding / 语义缓存(Semantic Cache)

这个才是你问题的关键 👇

不是按“字符串完全一致”,而是:

把问题转成向量 → 找“语义相似”的历史问题 → 直接复用答案


2️⃣ 为什么命中缓存成本低很多?

因为大模型推理成本主要在两块:

(1)Prefill(吃 prompt)

  • 复杂度 ~ O(n²)

  • 很贵(尤其长 prompt)

(2)Decode(逐 token 生成)

  • 每个 token 都要算一遍模型


而缓存命中后:

  • KV cache:不用重复 attention

  • Prompt cache:不用重新 encode

  • 语义缓存:直接跳过模型推理

👉 相当于从:

几十~几百毫秒 + GPU算力

变成:

一次向量检索(毫秒级)+ 直接返回

所以成本差一个数量级是正常的。


3️⃣ “每个人问法不同,怎么命中缓存?”

这是核心难点,也是工程重点👇

❌ 不能靠字符串匹配

比如:

  • “今天天气怎么样”

  • “今天外面热不热”

字符串完全不同 → 必须 miss


✅ 用语义相似度(Embedding)

流程一般是:

  1. 把问题转 embedding(向量)

  2. 在向量数据库里找 TopK 相似问题

  3. 如果相似度 > 阈值(比如 0.9)

  4. 直接返回缓存答案


一个简单示意

Q1: 北京天气怎么样
→ embedding A

Q2: 北京今天热吗
→ embedding B

cosine(A, B) ≈ 0.95 ✅ 命中

4️⃣ 实际工程里会更复杂(关键细节)

(1)不仅缓存“问题”,还要缓存“上下文结构”

例如:

系统提示 + 用户问题

否则同一句话在不同系统角色下答案完全不同。


(2)要做归一化(Normalization)

比如:

  • 时间标准化(“今天”→具体日期)

  • 数字归一

  • 同义词处理


(3)分层缓存(很关键)

一般会这样设计:

L1:精确缓存(完全命中)
L2:语义缓存(embedding)
L3:模型推理

(4)风险控制(不能乱复用)

语义缓存有坑:

  • 用户问:“苹果股票能买吗”

  • 另一个问:“特斯拉股票能买吗”

embedding可能很接近 ❗

👉 但答案绝不能复用

所以需要:

  • 加实体识别(NER)

  • 加关键字段校验

  • 或直接限制只缓存低风险问题(FAQ类)


5️⃣ 为什么很多场景缓存命中率依然很高?

因为现实中:

👉 用户问题是“高度重复的”

典型场景:

  • 客服(退款、发票)

  • 编程问题(报错)

  • 搜索类问题

哪怕表达不同:

语义空间其实是“高度聚集”的


6️⃣ 一句话总结

大模型缓存本质是三层优化:

  • KV Cache → 避免重复算 attention(单请求内)

  • Prompt Cache → 复用前缀计算

  • Semantic Cache → 用 embedding 做“语义命中”

而你关心的“问法不同也能命中”,核心就是:

把“文本匹配”问题,变成“向量空间相似度”问题


LLM缓存详解

 可以把“大模型缓存”理解成: 把已经算过的结果(或中间结果)存下来,下次尽量复用 。但这里面其实分几层,不只是简单的“问题→答案”缓存。 1️⃣ 常见的几种缓存类型 (1)KV Cache(推理内部缓存) Transformer 在生成时,会把前面 token 的 Key/Va...