近年来,大型语言模型(LLMs,Large Language Models)在自然语言处理领域取得了显著的进展。然而,这些模型通常具有庞大的参数量和计算复杂度,导致推理过程(即根据输入生成输出的过程)耗时且昂贵。缓存是一种常见的计算机技术,其核心思想是将计算结果或数据临时存储起来,以便后续重复使用,从而避免重复计算或数据访问,提高效率。在大模型中,缓存的原理也类似,只不过存储的内容和应用场景更加复杂。
在大型语言模型中提到的缓存(Caching),并不是直接缓存 system_prompt
或 user_prompt
的文本内容,而是缓存模型在计算过程中生成的中间计算结果,尤其是 Transformer 模型中的 键值向量(Key-Value Vectors,KV Cache)。不过,当输入的文本有相同前缀时,可以利用缓存避免重复计算。
1. 缓存的核心:键值向量(KV Cache)
在 Transformer 的自注意力机制中,每个词元(Token)会生成一对向量:
- Key(K):用于计算其他词元对它的关注程度。
- Value(V):存储该词元的语义信息。
缓存的作用:
在生成文本时(例如逐词生成回答),模型会将已生成词元的 K
和 V
向量存储下来。当生成下一个词元时,直接复用这些历史向量,避免重新计算。
2. 前缀匹配与缓存复用
当用户输入的提示(Prompt)有相同的前缀时,模型可以利用缓存快速处理。
例如:
用户输入1:
"法国的首都是哪里?法国的美食有哪些?"
用户输入2:
"法国的首都是哪里?德国的首都是哪里?"
假设模型已经处理过 用户输入1
的前缀 "法国的首都是哪里?"
,那么处理 用户输入2
时:
- 发现前缀
"法国的首都是哪里?"
和之前相同。 - 直接复用此前缀对应的 KV 缓存,无需重新计算这一部分的
K
和V
向量。 - 只需计算新增部分
"德国的首都是哪里?"
的向量。
3. 具体例子
假设用户连续两次提问:
第一次提问:
System Prompt: "你是一个百科全书助手。"
User Prompt: "爱因斯坦提出了什么理论?"
模型行为:
计算System Prompt
和User Prompt
的所有词元,生成对应的K
和V
向量,并缓存。第二次提问:
System Prompt: "你是一个百科全书助手。"
User Prompt: "爱因斯坦提出了什么理论?他的国籍是?"
模型行为:- 发现
System Prompt
和User Prompt
的前半部分("爱因斯坦提出了什么理论?"
)与第一次提问相同。 - 直接复用缓存的 K/V 向量,无需重新计算。
- 仅需为新增的
"他的国籍是?"
生成新的 K/V 向量。
- 发现
4. 技术细节
(1)前缀匹配的条件
- 完全相同的词元序列:前缀必须逐词一致(包括标点、空格),否则缓存失效。
- 模型上下文长度限制:如果两次输入的上下文总长度超过模型限制(如 4096 tokens),缓存会被截断。
(2)System Prompt 的缓存
- 如果
System Prompt
在多次请求中保持不变(例如聊天机器人固定的角色设定),其对应的 K/V 向量可以被缓存复用。 - 例如,在 API 服务中,如果多个用户请求使用相同的
System Prompt
,服务端可预先缓存其 K/V 向量,提升吞吐量。
(3)实际应用场景
- 长对话系统:在多轮对话中,缓存历史对话的 K/V 向量,避免每一轮都重新计算整个上下文。
- 批量推理优化:当批量处理多个相似前缀的请求时,复用公共前缀的缓存(如 vLLM 框架的优化)。
总结
大模型的缓存机制通过复用相同前缀对应的 K/V 向量,显著减少重复计算。例如:
- 若多个问题以相同的问题开头(如
"法国的首都是哪里?..."
),模型只需计算新增部分。 System Prompt
若固定不变,其缓存可长期复用,提升效率。
提示缓存(Prompt Caching)不会影响输出令牌的生成或 API 提供的最终响应。无论是否使用缓存,生成的输出都将相同。这是因为只有提示本身被缓存,而实际响应每次都会根据缓存的提示重新计算。