微信扫码
添加专属顾问
我要投稿
掌握Prompt Caching,高效降低AI模型延迟和成本。 核心内容: 1. Prompt Caching概念及必要性解析 2. Prompt Caching的工作机制和实现方法 3. 用户和开发者如何应用Prompt Caching以优化性能
⏰ Read: 25 + 30min
我第一次听到 prompt caching 可能是 DeepSeek 当时推出了缓存命中 0.1 元每百万 tokens(DeepSeek API 创新采用硬盘缓存,价格再降一个数量级[1]),随后各大厂商陆续推出了自己的 prompt caching 特性。
本文旨在回答四个问题:
我会基于 OpenAI 的博客[2],论文 Prompt Cache: Modular Attention Reuse for Low-Latency Inference[3] 和我自己检索的信息,带着上面这四个问题尽力构建一篇足够简洁的博客。
当然,对于用户,我们追求的可能只是如何高效地利用这个特性。如果把原理混杂在 best practice 中非常影响阅读的流畅性,因此我会分成如何使用和深入理解两个章节,力求一气呵成的阅读流畅性。水平有限,欢迎指正!
⏰ Read: 25min
Note
指令缓存 (prompt caching) 是一种用于降低延迟和成本的技术。
这句话介绍了 prompt caching 的具体作用。
model prompt = system prompt + user prompt
这是一个基本知识。通常情况下 model prompt 是包含许多重复内容的,例如 system prompt 和在 user prompt 中出现的常用指令(比如角色扮演的指令,数据分析的指令)。
因此,prompt caching 便是旨在 “存储”并“利用” 这些 model prompt 中的重复内容,来达到同时降低延迟和成本的好处。实现用户降低了成本,提升了速度;厂商减少了算力消耗,双赢的局面。
例如 OpenAI 会将 API 请求路由到最近处理过相同 prompt 的服务器,这比从头开始处理 prompt 更便宜、更快速。对于较长的 prompt,这可以将延迟降低高达 80%,并将成本降低 50%。prompt caching 会在你所有的 OpenAI API 请求中自动生效 (无需更改代码),并且不存在任何额外费用。
要理解这个优化效果,我们需要了解 LLM 响应中的一个重要概念:首 Token 延迟(TTFT, Time to Frsit Token)。这是从发送请求到收到模型第一个 token 响应所需的时间。
“在线服务场景中,如聊天机器人,大语言模型推理一般都采用流式输出(streaming)的形式,LLM 推理的 TTFT 就是用户感受到的 LLM 推理服务的响应时间,直接影响用户体验。”对于在线服务,为了提升用户体验,所以都希望 TTFT 要足够小,这也是我们为什么需要 prompt caching。
TTFT 和 prompt 的长度密切相关,对于长 prompt 来说,大部分延迟都发生在这个阶段,因为模型需要先处理完整个输入才能开始生成输出。 通过 prompt caching,模型可以直接利用已缓存的处理结果,显著减少这个首次等待时间。这就像是模型已经"预习"过这段内容,可以更快地开始响应(和 KV Cache 很像,可以思考下他们的不同之处,我会在后文给出我的思考)。特别是在处理包含大量重复内容(如系统提示词、固定指令等)的请求时,这个优势更为明显。
Tip
TTFT 的理解可能涉及到了小部分 LLM Inference 相关的知识,推荐阅读我的另一篇博客:Basic LLM Inference/Generation,一篇就够了。[4]
上面这一小段内容已经回答了问题1,已经了解到 prompt caching 是如此的 重要且实用,作为用户我们该如何高效的利用呢?
当前绝大部分的 LLM API,只有当两个请求的前缀内容相同时(从第 0 个 token 开始相同),才存在缓存命中。为了利用缓存的优势,请将静态内容 (例如说明和示例) 放在 prompt 的开头,并将可变内容 (例如用户特定的信息) 放在结尾。这也适用于图像和工具,它们在不同请求之间必须相同。
使用方法就是如此简单:“将需要缓存的内容放到 prompt 开头即可”。接下来,我综合了 OpenAI 和 Anthropic 的博客给出 best practices。
Tip
问题:为什么是 caching 是通过前缀匹配识别?必须使用前缀匹配吗?
思考: 前缀匹配的重要性在于其能够高效地识别出重复的 prompt 片段,进而实现缓存的复用。
为什么能高效地识别呢?从技术原理上讲,因为可以使用类似于计算机科学中的“字典树”(Trie) 数据结构。通过将 prompt 的前缀作为路径存储在树状结构中,系统可以快速地查找是否存在匹配的前缀。这种方式的优势在于查找速度快,时间复杂度通常为 ,其中 为前缀的长度。此外,前缀匹配也符合实际应用场景,因为大多数情况下, prompt 的变化主要集中在尾部,而开头部分往往是相对固定的。
那么必须是前缀匹配吗?在特定情况下我们可能只有中间某个位置不同,例如:
Original Prompt:
"你是一个专业的文章翻译助手。请将下面这篇关于人工智能的文章翻译成中文。
[文章内容...]
请保持专业术语的准确性。"
这一个 prompt 只是一个例子,但是我们发现,它只有中间会有变动,在这种情况下基于前缀匹配的 prompt caching 会无法 caching 后半部的静态内容。
Claude 支持的 cache_control
特性就更具灵活性,它可以分别 caching 不同的文本(因为我们可以把上面的 prompt 拆成三个部分,然后分别用 cache_control
修饰第一个和第三个部分) 。当然,后文中我们还会介绍另外一种方法, 但是我认为这种方法的缺陷是不够用户友好,前缀匹配是一个非常简洁,也在绝大部分情况下都奏效的匹配策略,这里的选择本质上是工程的 tradeoff。
cache_control
标识。因此,通过巧妙设置缓存断点,将不同的可缓存前缀部分加以区分。这样做既可以让缓存更有条理,又能提高缓存命中率。到这里,前三个问题我们都有了大致的回答。作为一个用户,我们知道了什么是 prompt caching 以及如何最佳的使用 prompt caching 了!接下来,我们尝试进一步的理解其背后的逻辑。
⏰ Read: 30min
这里引用 OpenAI 官方博客中的内容(Claude 会更复杂一些,感兴趣的推荐阅读:Build with Claude - Prompt caching[5])
对于长度为 1024 个 token 或更长的 prompts ,缓存会自动启用。当你发起 API 请求时,将执行以下步骤:
缓存的前缀通常在 5 到 10 分钟的不活动状态后失效。但是,在非高峰时段,缓存可能会持续长达一小时。
当然,具体较大家如何使用 API 不是我这篇博客的目的,我会在附录中 refer 上对应的 API 文档以及他们提供的常见用例,关于一些 FAQ 也可以直接参考对应的文档~
对于熟悉 KV Caching 的朋友,prompt caching 和它有诸多相似之处。它们都是避免计算重复的注意力 embedding,通过缓存手段加速推理过程。
这里简单的 review 下 KV Cache 在干什么。所谓自回归推理,就是每次都要基于之前的内容来预测(计算)下一个 token。如果没有任何优化手段,自回归中预测下一个 token 的计算量是递增的(因为某些 token 被重复计算了多次),所以 KV Cache 就出现了,也就是常用的“以空间复杂度换时间复杂度”的思路。引用我之前博客中的动图(由于公众号的限制,我转化为了视频),灰色的部分是被保留的 KV cache,我们可以在下次自回归计算时直接使用。
prompt caching 也是干这事的,“复用之前计算的结果”,那么他们的区别到底在哪呢?下图引用自“Prompt Cache:Modular Attention Reuse for Low-Latency Inference“ 论文。
我认为其区别在于:KV Cache 是 single session 的 cache,而 prompt cache 是支持 cross session 的 cache(也许这里用 sequence 而非 session 会更好)。我们来分析这张图:
attention states
的部分,这部分可以存储已经计算过的结果,再下一次自回归计算中复用,这大大降低了计算量。(至于为什么可以 KV cache,这是我很久之前挖的坑了,有机会补上后在此处更新引用)。所以回过来 prompt cache 和 kv cache 的区别在于: prompt cache 提供的是一个跨序列的 cache,它的效果也是作用于全局(多次)而非单次推理。
prompt cache 最大的问题就是如何维护与识别,区别于 kv cache 本质上是“一定”会被复用,prompt cache 可能会面临存储后无人问津的尴尬情况,并且如何识别也是影响缓存命中的关键因素。
在 如何使用 的 part 中,我们介绍的是最粗暴的前缀匹配(即 OpenAI 使用的)。同时,我们在思考环节遇到了一个问题:“如果我们只有中间某处 prompt text 不同怎么办呢?”进一步推广:“如果我们的 prompt 的存在一个范式,只在某些固定位置不同怎么办呢(例子可以参考 python 的 String Formatting)?
比如下图,两个 prompt 只有某个特定位置的 token 不同,这时候简单的前缀匹配就会失效。
因此,论文中提到了 Prompt Markup Language(PML),什么是 PML 呢?提示标记语言(PML)旨在以结构化的方式表示提示,特别是突出 prompt 中的不变 (固定) 部分和可变 (可更改) 部分。
正如我们在问题中提到的,当前缀匹配遇到只有中间某处不同的 prompt 时,它就失效了。而 PML 通过明确标记出这些可变部分,巧妙地解决了这个问题。我举一个简单的例子大家一看便知:
<item>
、<quantity>
和 <no>
是可变槽位,代表可以更改的部分。现在,即使两个顾客点了不同的菜品、数量和忌口,PML 都能识别出它们遵循相同的模板,并准确地识别出哪些部分是可变的。所以相较于粗暴的前缀匹配,PML 可以基于模版识别实现更准确的匹配, 并且得到更高效的缓存。
Important
我们还需要考虑一个问题:只有当一个文本片段在大型语言模型(LLM)输入中出现在相同位置时,其注意力状态才能被重用。 原因是,Transformer 将位置信息整合到了键(k)和值(v)注意力状态中。对于单个 prompt 的 KV cache 而言,这并不是问题,因为在所有步骤中,相同的 prompt 都位于相同的位置,即输入的开头。
那么如果我们使用非前缀匹配,就会遇到这个问题,即如何处理位置编码?共享的文本在不同 prompt 中可能出现在不同位置。为了实现跨 prompt (也就是不同位置)的注意力状态重用,cache system 必须解决两个问题。首先,尽管一个文本片段可能出现在不同 prompt 的不同位置,系统仍须支持其重用。其次,当系统接收到一个新的提示时,它必须能够高效地识别出其注意力状态可能已被缓存的文本片段,从而实现重用。
为解决这两个问题,论文结合了两种思路。首先,提出使用提示标记语言(PML)来明确提示的结构,将可重用文本片段明确表示为 module,即 prompt module。PML 很好的解决了上述的第二个问题(识别哪些是重复文本片段),还为解决第一个问题提供了可能,因为每个 prompt module 都可以被分配唯一的 Position IDs。其次,我们通过实验发现,LLM 可以处理带有不连续 Position IDs 的注意力状态。只要令牌间的相对位置保持不变,输出质量就不会受到影响。(Our second idea is our empirical finding that LLMs can operate on attention states with discontinuous position IDs. As long as the relative position of tokens is preserved, output quality is not affected.)这意味着,我们可以提取不同的注意力状态片段,并将它们拼接起来以构建新的语义。利用这一特性,用户可以根据自身需求选择提示模块,甚至在运行时替换某些含义。
那另一个问题是:由于位置的变化,即使相同的文本,在真正推理时也会是不同的 kv attention state。但是,此处,我们使用的是相同的 kv attention state,是否会影响输出质量呢?在论文 5.3 节中提到:在所有数据集中,使用 prompt cache 输出的准确性与 baseline 相当。(但是仍然会有细微差异,所以基于 PML 的 prompt cache 并不像 kv cache 一样是完美的替换。
当然,这里的解释还点模糊,我暂时留下一个坑,阅读完相关代码后我会在这里尝试进一步解释什么是:“LLM 可以处理带有不连续 position ids 的注意力状态“。
同时,如何前文所说:Claude 提供的 cache_control
特性某种程度上可以实现类 PML的效果。对比 OpenAI 和 Claude:
回答最后一个问题:“使用 prompt caching 时是否会反过来影响输出的质量呢?” KV cache 是不会影响推理的效果,因为它是等价替换。同理使用基于前缀匹配的 prompt cache 也不会影响推理的效果。但是,在上文分析中,我们发现虽然实验结论证明基于 PML 的 prompt cache 能和 baseline 得到接近的输出,但是它们之间还是存在不同,并不是完美的等价,所以在使用基于 PML 的 prompt cache 时应当考虑匹配机制对于输出质量的影响。
本篇到此完结,当前其实还有一些细节可以深入挖掘,但是我觉得我已经回答了文章开始处的四个问题。就像 OpenAI 一样,我这里就提供一个“简单粗暴”的概览,以供大家了解什么是 prompt caching 以及 prompt caching 的 best practice。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-03-28
他因选DeepSeek 70B 体验差,被开除
2025-03-28
AI训练平台终极构建指南:结合RoCE/IB网络、3FS存储与HAI平台
2025-03-28
微调篇「数据集构建」保姆级教程来了!
2025-03-27
olmOCR-7B:文档提取专用模型
2025-03-27
如何用 deepseek v3-0324 最新版,附常见问题和解决方案
2025-03-27
大模型微调数据生成工具Easy Dataset及KBLaM知识注入框架评析
2025-03-26
从SFT到RFT:AI模型训练的进化之路
2025-03-26
使用MCP Inspector调试MCP服务端
2025-02-04
2025-02-04
2024-09-18
2024-07-11
2024-07-09
2024-07-11
2024-07-26
2025-02-05
2025-01-27
2025-02-01
2025-03-20
2025-03-16
2025-03-16
2025-03-13
2025-03-13
2025-03-11
2025-03-07
2025-03-05