KV Cache:从原理到集群调度

你跟 AI 聊天,它一个字一个字蹦回答。但你有没有想过——它是怎么"记住"你说了什么的?答案藏在 GPU 里一个叫 KV Cache 的东西里。

一、KV Cache 是什么?

想象你是一个餐厅服务员,客人点了一桌菜,你要一道道端上去。

没有小本本的服务员 :每端一道新菜,都要从厨房跑回餐桌,把之前端过的所有菜再看一遍,确认没上错。菜越多,跑得越累。

有本本的服务员 :端过的菜记在本子上,每端新菜只看本子,不用跑回去。

KV Cache 就是 AI 的"小本本"。

本子上记了什么?

AI 的"脑子"里有一套叫 Attention 的机制,工作时有三样东西:

  • Query(问题) :客人现在问"这道鱼怎么做的?"
  • Key(标签) :每道菜的名字——"清蒸鲈鱼""红烧肉""蒜蓉西兰花"
  • Value(内容) :每道菜的具体做法和配料

AI 生成每个字时,都要拿当前的问题去和每道菜的"标签"比对,找到最相关的,然后从"内容"里提取信息。

KV Cache = 把之前所有菜的"标签"和"内容"抄在本子上。 下次客人问新问题,直接翻本子,不用跑回厨房重新看。

没有本子有多惨?

假设 AI 已经生成了 4 个字:"今天天气不错"。现在要生成第 5 个字:

生成第几个字 需要重新算的 token 浪费程度
第 1 个 今 1 次
第 2 个 今、天 今被算了第 2 次
第 3 个 今、天、天 今被算了第 3 次
第 4 个 今、天、天、气 今被算了第 4 次

"今"这个字被反复算了 4 次!而且每次算出来的结果一模一样,因为模型参数是固定的。

生成 n 个字的总计算量:1 + 2 + 3 +... + n = O(n²) 。写到第 1000 个字时,每步要重算前 999 个字。难怪没有 KV Cache 的时候,AI 说话慢到令人发指。

有了 KV Cache,计算量从 O(n²) 降到 O(n)。 这就是为什么你现在能和 AI 流畅聊天。

KV Cache 是什么:有无缓存对比

二、KV Cache 怎么产生的?

AI 回答你分两个阶段,像餐厅的 备菜 和 上菜 。

Prefill:备菜——一次性读完你的问题

你发了一句"帮我写一首关于春天的诗"。

AI 不会一个字一个字读,而是 一口气把所有字同时读进去 ,每个字都算好自己的 K(标签)和 V(内容),全部抄进小本本。

这就像厨师接到订单后,先把所有食材准备好、切好、配好料—— 一次性把活干完 。

这一步的特点是: 算力全开,GPU 忙得飞起 。耗时叫 TTFT (首字延迟)——你从发送消息到看到第一个字的时间。

KV Cache 怎么产生:Prefill 流程

Decode:上菜——一个字一个字蹦

备菜结束后,AI 开始一个字一个字地生成回答。

每生成一个字: 1. 拿这个新字的 Query,去翻小本本上 所有历史 Key → 找到最相关的 2. 用注意力分数对 所有历史 Value 加权求和 → 拼出答案 3. 把这个新字的 K 和 V 追加到本子上 ,供下一步使用

关键洞察 :每步只算 1 个字的 K/V,但要从本子上读所有历史。所以——

  • Prefill = 算力瓶颈 (手速不够快)
  • Decode = 搬运瓶颈 (翻本子翻不过来)
对比 Prefill(备菜) Decode(上菜)
做什么 一口气读完输入 逐字生成回答
瓶颈 算力(手速) 搬运(翻本子)
并行性 所有字同时算 每次只算 1 个字
GPU 利用率 高 不到 1%
指标 TTFT(等多久看到第一个字) TPOT(每个字间隔多久)

Decode 阶段:逐字生成复用缓存

三、KV Cache 的生命周期

每个请求的 KV Cache 都有完整的一生,像一颗 气球 :

吹气(诞生+生长) → 用户发消息,系统分配显存。Prefill 写入初始 KV,Decode 每生成一个字追加一条。气球越吹越大。

最大(峰值) → 对话结束,或达到上下文窗口上限(如 128K token)。气球吹到最大。

放气(消亡) → 请求结束,显存释放。气球瘪了。

这个气球到底有多大?

每个 token 的 KV = 2 × 层数 × KV头数 × 头维度 × 精度字节数

模型 每 token 4K 字 32K 字 128K 字
7B 小模型 128 KB 512 MB 4 GB 16 GB
70B 大模型 80 KB 320 MB 2.5 GB 10 GB

一个人聊天还好,人一多就炸了:

70B 模型 × 128K 上下文 × 64 人同时聊 = 640 GB 。8 张 H100 显卡的 640 GB 总显存,光装"小本本"就满了,模型本身的"大脑"还没地方放。

四、单节点内:瓶颈在"搬"

在 GPU 内部,KV Cache 的流动路径是:

HBM(显存仓库) → SRAM(工作台) → 计算单元(厨师的手) 80 GB, 3 TB/s 20 MB, 100 TB/s 每秒万亿次

打个比方:

  • HBM = 仓库,很大(80GB),但搬货慢(每秒 3TB)
  • SRAM = 工作台,很小(20MB),但拿东西极快(每秒 100TB)
  • 计算单元 = 厨师的手,快得飞起(每秒万亿次)

问题 :厨师的手一秒能切一万刀,但仓库每秒只能送 3000 斤菜过来。手再快也没用—— 菜送不过来 。

Decode 阶段每生成一个字,都要把整个 KV Cache 从仓库搬到工作台。70B 模型 32K 上下文时,每步要搬 2.5 GB。H100 带宽 3.35 TB/s,理论最低延迟 0.75 ms。加上模型权重等开销,实际更慢。

算得快,搬得慢 → 瓶颈在搬运(IO Bound)。

这就是 FlashAttention 的意义——它重新安排计算顺序,让厨师在工作台上一次多切几刀,减少往返仓库的次数。

GPU 内部 KV Cache 流转:HBM→SRAM→计算

五、集群中:KV Cache 是共享资源

一台机器搞不定 64 个人同时聊天的 KV Cache,那就多台机器组集群。这时 KV Cache 变成了可以 跨机器共享 的资源。

A. Prefix Cache — 共享系统 Prompt

大多数 AI 应用都有系统 Prompt("你是一个有帮助的助手..."),可能长达几千 token。

  • 第一个用户来了,系统 Prompt 的 KV Cache 算好,存下来
  • 第二个用户来了,同样的系统 Prompt? 直接复用,不算了
  • 第 100 个用户来了? 还是复用

就像餐厅的固定套餐——食材提前备好,谁来点直接出餐。

B. PD 分离 — 备菜和上菜分开做

Prefill(备菜)需要强算力,Decode(上菜)需要大显存。两种活对"厨房"的要求完全不同。

  • Prefill 节点 :配算力强的 GPU,专门负责"读输入、生成 KV Cache"
  • Decode 节点 :配显存大的 GPU,专门负责"翻本子、逐字生成"

Prefill 节点算完后,把 KV Cache 通过网络传给 Decode 节点。各干各的擅长的活。

C. 负载均衡 — 客人太多就换桌

某个节点快满了,把请求迁到空闲节点。KV Cache 跟着请求一起迁移,用户无感知,服务不中断。

就像餐厅满了,服务员带你去另一桌,菜继续上,你感觉不到换了位置。

集群中 KV Cache 的流转

总结

问题 答案
KV Cache 是什么? AI 的小本本,抄下读过的标签和内容
省了多少? 计算量从 O(n²) 降到 O(n)
怎么产生? Prefill 一口气读完,全部抄好
谁在用? Decode 逐字生成时翻本子
生命周期? 吹气→最大→放气
占多少显存? 70B×128K×64人 = 640 GB
单节点瓶颈? 厨师手快但仓库送菜慢(IO Bound)
集群怎么管? 共享套餐、分工备菜上菜、换桌

KV Cache 贯穿 AI 聊天的每一个环节。下次你和 AI 对话时,可以想象:有一个服务员,正在飞快地翻他的小本本。