# 大语言模型中的提示缓存:优化 KV 缓存以降低成本和延迟
提示缓存可以将 LLM 输入令牌成本降低 10 倍,对于长提示可以将延迟降低高达 85%。OpenAI 和 Anthropic 不会缓存响应;它们缓存 transformer 注意机制中的中间计算——具体来说是 KV 缓存。这种缓存存储重复提示前缀的键值对,从而加速推理过程,同时不牺牲生成质量。
这项技术非常适合具有重复上下文的任务:RAG、带有对话历史的聊天机器人、多步骤流水线。在 API 提供商上的测试显示,充分利用缓存可以显著提升首个令牌的速度。
LLM 架构与注意力的作用
LLM 是一系列 transformer 模块的序列,每个模块以嵌入作为输入并输出更新后的表示。推理过程以循环方式运行:提示被令牌化,嵌入通过注意力和前馈层,生成下一个令牌,并将其添加到上下文中。
prompt = "What is the meaning of life?";
tokens = tokenizer(prompt);
while (true) {
embeddings = embed(tokens);
for ([attention, feedforward] of transformers) {
embeddings = attention(embeddings);
embeddings = feedforward(embeddings);
}
output_token = output(embeddings);
if (output_token === END_TOKEN) {
break;
}
tokens.push(output_token);
}
print(decode(tokens));
缓存发生在注意力机制中。自注意力为每个令牌基于查询(当前令牌)与键(先前令牌)之间的相似度计算先前令牌的加权和。对于 query_i:attention(Q_i, K, V) = softmax(Q_i K^T / sqrt(d)) V。
在生成每个新令牌时,所有先前令牌的 KV 缓存会扩展,导致相对于序列长度的二次复杂度 O(n^2)。
令牌化与嵌入
令牌化器将文本分解为子词单元并分配 ID。GPT 的示例:“Check out ngrok.ai” → [4383, 842, 1657, 17690, 75584]。它是确定性的、区分大小写的,并使用类似 BPE 的算法。
嵌入将令牌转换为 n 维向量(大型模型中 n > 10k)。嵌入矩阵在训练后固定不变:
function embed(tokens) {
return tokens.map((token, i) => {
const embeddings = EMBEDDINGS[token];
return encodePosition(embeddings, i);
});
}
位置编码添加了关于顺序的信息。更多维度能更好地捕捉语义:语气、风格、相似度。
注意机制与 KV 缓存
在多头注意力中:
- 投影:Q = X W_Q, K = X W_K, V = X * W_V(X 为嵌入矩阵)。
- 分数:attention_scores = Q * K^T / sqrt(d_k)。
- Softmax 和加权和:attention_output = softmax(scores) * V。
对于长度为 n 的序列,KV 缓存由大小为 [n, d_model] 的 K 和 V 张量组成。在生成第 t 个令牌时,注意力使用整个过去的缓存加上当前的一个。
提示缓存会在 API 调用之间保存提示前缀的 KV 缓存。如果新提示以缓存前缀开头(命中),则跳过这些令牌的注意力计算——直接使用现成的 KV。成本下降是因为长上下文的计算量约 90% 被跳过。
- 缓存命中:前缀 > 1024 个令牌(Anthropic),成本 /10。
- 缓存未命中:完全重新计算。
- TTL:缓存存活约 5-10 分钟,取决于提供商。
优势与局限性
延迟提升:对于 10k+ 令牌的提示,TTFB 降低 50-85%。
节省:缓存输入令牌 — $0.0001/1k vs $0.001/1k(大约)。
局限性:
- 仅前缀匹配(非任意子串)。
- 不缓存输出嵌入或 logits。
- 取决于提供商的令牌化器。
在生产环境中:适用于历史重复的基于会话的聊天。
关键要点
- 提示缓存为前缀缓存注意力 KV 对,对于长上下文将计算量削减 90%+。
- 首个令牌时间降低高达 85%,输入成本 /10。
- 需要精确前缀匹配和兼容的令牌化器。
- 完美适用于 RAG、聊天历史、多迭代任务。
- 不影响质量:生成保持随机性。
— Editorial Team
暂无评论。