KV Cache:为什么大模型第一个字慢,后面却飞快?

本文整理自 Avi Chawla 的 X Article《KV Caching in LLMs, Clearly Explained》

你在使用 ChatGPT、Claude 或任何流式大模型时,应该都见过这个现象:第一个 token 往往等得更久,但一旦开始输出,后面的 token 会像流水一样连续冒出来。

这不是魔法,也不是 UI 动画。背后是一个非常关键的推理工程设计:KV Cache。它的目标很直接:减少自回归生成里的重复计算,让 LLM inference 更快。

先看一张直观对比:没有 KV Cache 时,模型每一步都在重复算历史 token;有 KV Cache 后,历史 token 的 Key/Value 会被存起来,新一步只处理最新 token。

有无 KV Cache 的推理路径对比:核心差异是历史 K/V 是否被复用。 (原文为动态演示,可查看原动画。)

下面从第一性原理拆开看。

1. LLM 是怎么一个 token 一个 token 生成的?

Transformer 会处理输入序列里的所有 token,并为每个 token 生成 hidden state。随后 hidden state 被投影到词表空间,得到 logits,也就是"下一个词可能是什么"的分数。

但这里有一个关键点:真正用于采样下一个 token 的,只有最后一个 token 对应的 logits。

Transformer 会为每个位置产生 logits,但生成下一步时只使用最后一个位置。 (原文为动态演示,可查看原动画。)

模型从最后一个位置的 logits 里采样出下一个 token,把它追加到输入序列末尾,然后重复同样过程。

采样、追加、再推理:自回归生成就是这样一步步滚动起来的。 (原文为动态演示,可查看原动画。)

所以第一条关键洞察是:为了生成下一个 token,我们只需要最新位置的 hidden state;其他位置的 hidden state 主要是中间产物。

2. Attention 实际上在算什么?

在 Transformer 的每一层里,每个 token 都会被投影成三组向量:

  • Query(Q):我在找什么;
  • Key(K):我提供什么索引;
  • Value(V):我真正携带的信息。

Attention 会用 Query 和 Key 做相似度计算,得到注意力分数,然后用这些分数去加权 Value。

Attention 的核心:Q 与 K 计算权重,再加权 V 得到输出。 (原文为动态演示,可查看原动画。)

现在只盯住最后一个 token。因为我们只需要最后一个位置的 hidden state,所以在注意力矩阵里,我们真正关心的是最后一行。

最后一个 token 的注意力行:它的 Query 要和所有历史 Key 交互。 (原文为动态演示,可查看原动画。)

最后一行的计算需要:

  • 最新 token 的 Query
  • 序列里所有 token 的 Key
  • 序列里所有 token 的 Value

也就是说:每一层为了算最新 token,都需要"最新 Q + 全量 K/V"。

3. 冗余到底在哪里?

假设正在生成第 50 个 token,模型需要 token 1 到 50 的 K/V。

下一步生成第 51 个 token 时,模型需要 token 1 到 51 的 K/V。

问题来了:**token 1 到 49 的 K/V 早就算过,而且不会变。**同样的输入、同样的权重、同样的输出。没有缓存时,模型每一步却都把它们重新计算一遍。

相邻生成步骤中,大量历史 K/V 完全相同,却会被重复计算。

这就是浪费:每一步都有 O(n) 的重复工作,整段生成累计下来就是 O(n²) 级别的冗余计算。

4. KV Cache 怎么修?

修法很朴素:既然历史 K/V 不变,那就存起来。

每生成一个新 token:

  1. 只为最新 token 计算 Q、K、V;
  2. 把新的 K/V 追加进 cache;
  3. 从 cache 里取出所有历史 K/V;
  4. 用最新 Q 去 attend 完整的 K/V cache。

KV Cache 的工作流:新 token 只新增一份 K/V,历史 K/V 直接从缓存读取。 (原文为动态演示,可查看原动画。)

这就是 KV Cache:每层、每步只新增一个 token 的 K/V,其余全部从显存里读。

注意,Attention 本身仍然要看完整上下文,因此它依然随序列长度增长;但昂贵的 K/V 投影不再被重复计算。换句话说,KV Cache 不是让上下文"免费",而是消掉了最不该重复的那部分计算。

5. 为什么第一个 token 慢?TTFT 的来源

现在就能解释开头那个现象了。

当你发送 prompt 时,模型要先完整处理整个输入,把每个 prompt token 在每一层里的 K/V 都算出来并写入 cache。这个阶段叫 prefill

prefill 是一次请求里最重的计算阶段,所以你会感到第一个 token 出来前有明显等待。等 cache 建好后,后续每个 token 只需要处理最新位置,进入 decode 阶段,速度就会快很多。

TTFT 来自 prefill:先构建整段 prompt 的 KV Cache,之后 decode 才能快速流式输出。

这段首 token 延迟就是 Time-to-First-Token(TTFT)。prompt 越长,prefill 越重,TTFT 通常越高。

优化 TTFT 本身又是一大块工程:chunked prefill、speculative decoding、prompt caching 等技术都围绕这个问题展开。但底层动态始终一样:建 cache 贵,读 cache 便宜。

6. 代价:用显存换计算

KV Cache 的交易很清楚:用 GPU memory 换 compute。

每一层都要为每个 token 存 K 和 V。对于大模型和长上下文,这个 cache 会很夸张。原文举了 Qwen 2.5 72B 的例子:80 层、32K context、hidden dim 8192,单个请求的 KV Cache 就可能吃掉数 GB 显存。

如果同时服务几百个请求,KV Cache 的显存占用甚至可能超过模型权重本身。

这也是为什么很多推理优化技术都围绕 KV Cache 展开:

  • GQA(Grouped-Query Attention):多个 Query head 共享更少的 Key/Value head;
  • MQA(Multi-Query Attention):进一步让多个 Query head 共用同一组 K/V;
  • PagedAttention:像操作系统分页一样管理 KV Cache,降低碎片和浪费;
  • Prompt caching:复用相同 prompt 前缀对应的 cache,减少重复 prefill。

上下文长度翻倍不是简单把窗口开大。因为窗口越长,单请求 KV Cache 越大,同一张 GPU 上能并发服务的用户就越少。

tl;dr

KV Cache 的本质是:自回归生成中,历史 token 的 K/V 不会改变,所以不要每一步重算;算一次,存起来,后续复用。

每个新 token 只需要自己的 Q/K/V,然后用最新 Q 去 attend 完整的 K/V cache。

KV Cache 的结果:实践中可带来显著加速,但显存成为新的瓶颈。 (原文为动态演示,可查看原动画。)

工程上,KV Cache 是现代 LLM serving 的地基之一。vLLM、TGI、TensorRT-LLM 等推理栈都建立在这类思想之上。

一句话总结:**KV Cache 让 LLM 少做蠢事;但它把"算力瓶颈"换成了"显存瓶颈"。**这就是推理系统设计最经典的 trade-off。

原文链接:x.com/_avichawla/...

相关推荐
摄影图2 小时前
蓝色光效科技背景图片素材 多场景设计
人工智能·科技·aigc·贴图·插画
Wanderer X3 小时前
【AIGC】Wan 系列介绍
aigc
Wanderer X3 小时前
【AIGC】VAE 3D-VAE
aigc
小江的记录本4 小时前
【AI大模型选型指南】《2026年5月(最新版)国内外主流AI大模型选型指南》(个人版)
前端·人工智能·后端·ai·aigc·ai编程·ai写作
科智咨询5 小时前
2026 AI智能体落地纪实:谁在用?用在哪?
大数据·人工智能·科技·aigc
小溪彼岸5 小时前
初识OpenSpec
aigc
Autumn_ing6 小时前
2026实测:这5款AI生成UI工具支持Shadcn UI/Ant Design组件库
人工智能·ui·设计模式·aigc·设计规范
小江的记录本7 小时前
【AI大模型选型指南】《2026年5月(最新版)国内外主流AI大模型选型指南》(企业版)
前端·人工智能·后端·ai作画·aigc·ai编程·ai写作
weixin_373470697 小时前
coze实战:用工作流搭建美食地图
ai·aigc·ai编程·美食