为什么 AI 也会有缓存命中

很疑惑最近总是很困。比如昨天太困早睡了,睡眠时间达到了 9 个小时,但今天还是困。今天正好看到一篇文章说困可能是“输出”太少。想想挺有道理。最近每次骑完车虽然很累,但比出门骑车前精神要好。我猜这就是体力输出导致的结果。

最近实在太闲,本来事儿就少,还都用 AI 完成了,大脑自己的输出量极少。估计这就是最近精神状态不行的原因。所以得输出一些东西。但就像有句话说:“很多人是三十几岁就死了”,日复一日的循环似乎没什么好输出的。就强迫自己输出一些每日的小知识、小见闻吧。

今天我觉得值得输出的是关于 AI 缓存命中的问题。

自从大模型计费开始有“缓存命中”这个概念之后,我就有疑惑:大模型是实时计算的,怎么能像存储一样有缓存命中的概念呢?问了一些程序员,感觉他们也不清不楚。多次跟 AI 交互后,才明白其中的逻辑。至少我觉得我明白了。

AI 大模型的“缓存命中”,其实是“计算缓存”的命中。因为大模型的计算并不像我一开始想得那样是把输入作为一个整体进行计算,而是拆成一个一个的 Token,进行张量计算。说到这里,学过线性代数的应该都能理解了。

比如“我爱你妈”这个短句,假设被拆成“我”、“爱”、“你”、“妈”四个 Token:

因为有因果关系(可以理解为要按从前往后),也就是后面的 Token 可以参考前面的 Token,所以可以把模型在这四个位置分别看到的内容简化为:

  1. 我爱

  2. 我爱你

  3. 我爱你妈

第 4 项“我爱你妈”的计算结果是要基于前三项的计算结果的,所以如果我们之前输入过“我爱你”这个短句也得到了结果,那么前三项的结果之前已经计算过了,这时候就可以直接用计算过的结果来代入,也就是“缓存命中”。当然,这个解释比较粗暴也不那么准确,但是比较容易理解。更准确的说法应该是:

模型在计算过程中,会为每个 Token 产生一系列中间状态。缓存系统复用的,就是相同输入前缀对应的这些中间状态。技术上,通常可以将其理解为各层的 Key、Value 张量,也就是所谓的 KV Cache。

其中比较重要的还有顺序问题,因为张量计算顺序很重要。所以“我爱你妈”是无法命中“爱你妈”的缓存的,因为这两句话从第一个 Token 开始就不一样,每个位置的 Token 内容就完全变了。

尽管实际的计算会更复杂,涉及很多我不了解的细节,但简单来说就是这个原理。那根据这个原理可以得出什么结论呢?我觉得至少可以得出以下两个结论:

  1. 用 AI 大模型写代码,缓存命中率通常会很高。因为写代码基本都是多轮问答,后一次询问基本要把前一次的代码、结果全部代入。“上文”完全一致。

  2. 与上一条对应的,普通问答的缓存命中率通常会比较低,特别是只有一轮的简单问题。因为除了系统内置提示词之外,每一次问题本身几乎没有可用的缓存结果。

我是外行,线性代数也只学了一个学期,并且是考试前突击了几个晚上才考过的,所以理解的比较粗暴简单,但我觉得大概是这个原理。关于 AI 缓存命中问题,我与 ChatGPT 的对话在此:https://chatgpt.com/share/6a74a277-fa0c-83ea-a272-2fc52bd57da3