Skip to Content
AI 时代✏️ LLM 定价的数学原理 04:拆开 KV cache

✏️ LLM 定价的数学原理 04:拆开 KV cache 这个「反派」

📖

到目前为止,KV cache 一直以 L(上下文长度)和 b(每 token 字节数)两个符号出现在咱们的方程里。咱们说过它「摊不掉」,但还没真正打开看里面是什么。这一篇咱们正面把它拆开:每 token 那几十 KB 字节到底装的是什么、GQA / MLA / 跨层共享这些技术分别在解决什么问题、以及最有意思的——从 Gemini 公开的长上下文定价反推它的内部架构。最后咱们退一步,把「算得快 vs 经济学优化 vs 硬件常数」这套三分框架交给你,让你能给任何架构创新分类。

🧭

前情提要:上一篇 从推理耗时到推理成本 咱们换到运营方视角,看清了同一套方程在 Y 轴换成「每 token 成本」后能讲什么故事。但 KV cache 这个反派一直只以符号出现,没真正拆开看——这一篇咱们补上。

一、KV cache 里到底装了什么?

回想第一篇的比喻:KV cache 是模型「对已读 token 做的笔记」。但具体每条笔记长什么样?这一节咱们打开看。

模型怎么「看」历史

Transformer 的核心是 attention(注意力机制)。每一个被喂进模型的 token 都要拿自己的 Q(Query,查询向量) 去 attend 前文——跟历史 token 的 K 做相似度匹配,按相似度加权融合它们的 V,得到自己位置的一份 hidden state,用来预测再下一个 token。

⚠️

一个容易绕晕的点:每个 token 都是先被预测出来下一轮被喂回模型时才算自己的 Q/K/V。真实流程是:

  1. 把所有上下文输入模型 → 计算出最后一个位置的 hidden state
  2. 通过 hidden state 预测出新 token
  3. 此时新 token 只是一个刚被采样出来的 id——还没有自己的 Q/K/V
  4. 下一轮计算,新 token 作为输入被喂回模型,才会算它的 Q/K/V:把 K/V 写入 cache,把 Q 拿去 attend 前面所有 K,得到下一个 hidden state,预测再下一个 token

配一个完整时间线——假设 prompt 是「我 喜欢 吃 苹果」,模型最终生成「, 尤其 甜 的」:

prefill: 输入:我 喜欢 吃 苹果 生成 cache:我/喜欢/吃/苹果 的 K/V 计算“苹果”位置的 Q,得到 hidden state,输出预测:, ⬇️ decode step 1: 输入:, 生成 cache:, 的 K/V 计算“,”位置的 Q,得到 hidden state,输出预测:尤其 ⬇️ decode step 2: 输入:尤其 生成 cache:尤其 的 K/V 计算“尤其”位置的 Q,得到 hidden state,输出预测:甜 ⬇️ decode step 3: 输入:甜 生成 cache:甜 的 K/V 计算“甜”位置的 Q,得到 hidden state,输出预测:的

每一步同一个 pattern:当前输入 token → 算它的 Q/K/V → K/V 写进 cache → 用 Q 拉前文得到 hidden state → 预测下一个 token

🔑 K 和 V 是 token 的两个会被长期保存的角色——K 是「让未来 token 检索我时用的指纹」,V 是「被检索到时取出的内容」。Q 是每步当场算、用过即弃。这就是为什么叫 KV cache——只缓存 K 和 V。

K 和 V 里装着什么?

K 和 V 都不是文字标签,而是几百维的数字向量——每个维度记录 token 在某种语义特征上的取值(「它是不是名词」「跟时间相关吗」「能不能被评价」⋯⋯)。下面用中文描述每份向量「装着什么」,只是帮你抓住直觉,真实运算是数字之间的点积。

模型生成「今天天气真 ___」的下一个字时,cache 里大致存着:

  • 「天气」
    • K(被检索的”指纹”)= 「我是名词 / 可以被评价 / 跟季节、室外相关 / 有时序属性」
    • V(取出的”内容”)= 「冷热好坏可以形容我 / 跟心情和环境挂钩 / 有具体语义概念」
  • 「今天」
    • K = 「我是时间副词 / 定位『何时』」
    • V = 「我指代当下这个具体时间」
  • 「真」
    • K = 「我是副词 / 表强调」
    • V = 「我在强调评价的真实性」

轮到**最后一个已有 token「真」**做 attention。它算出自己的 Q(大致是「我是评价副词,前面哪个对象是被我评价的?」),然后两步:

  1. 「真」的 Q 跟每个 K 做点积:跟「天气」K 匹配最高,跟「今天」/「真」自己相对弱
  2. 按相似度加权融合所有 V:「天气」的 V 拉得最重

得到「真」位置的 hidden state → 模型用它预测下一个字(「好」/「热」/「冷」之类)。

🔑 整个过程里在工作的是**「真」的 Q**,不是新字「好」的 Q——「好」此时还没出生。这正是上面 ⚠️ Callout 流程的具体演示。

一条「笔记」有多重?

注意:不是简单的一组 K/V。模型有多个层(layers),每层都有自己的 attention 机制;每层里还有多个注意力头(heads)。所以一个 token 的 KV cache 实际是:

每 token KV 字节数 = 层数 × KV head 数 × 每个 head 的维度 × 2(K 和 V 各一份) × 精度字节数

代入 Llama 3 70B 的典型数字:

  • 80 层
  • 8 个 KV head(GQA 后)
  • 每个 head 128 维
  • FP8 = 1 字节
b=80×8×128×2×1=163,840 字节160 KBb = 80 \times 8 \times 128 \times 2 \times 1 = 163{,}840 \text{ 字节} \approx 160 \text{ KB}

🔑 每个 token 的笔记是 160 KB 这个量级。100K 上下文 = 16 GB 的 KV。这是个庞然大物

这就是为什么上一篇咱们说「KV 主导成本」——它不是抽象的「摊不掉」,而是字面意义上的几十 GB 数据要每生成一个 token 都从显存搬运一遍


二、降 KV 成本的四条路

公式回顾:

b = 层数 × KV head 数 × head 维度 × 2 × 精度字节数

这五个变量里,每一个都被研究过怎么降。咱们看四条最主流的路。

路 1:减少 KV head 数(GQA)

最早大家用 MHA(Multi-Head Attention,多头注意力):有多少个 Q head 就有多少个 K head 和 V head,每个 head 一份独立的 K/V。

后来发现一个浪费:多个 Q head 其实可以共享一份 K/V。这叫 GQA(Grouped Query Attention,分组查询注意力)

比如 Llama 3:32 个 Q head 但只有 8 个 KV head——每 4 个 Q head 共用一组 K/V。KV 大小直接降 4 倍,质量损失几乎没有。

🔑 GQA 已经是现在所有主流模型的标配——Llama、Mistral、Qwen、Claude 全都在用。

路 2:跨层共享 KV(Character.AI / Gemma 风格)

更激进的想法:不同层之间共享 KV

比如 80 层里,每两层共享一组 KV → 等效层数变 40 → KV 大小再降 2 倍。

🔑 Character.AI 把这种思路推到极致——「global context」在所有层共享一份 KV(只在某些「local」层用独立 KV)。他们之所以做这种激进设计,是因为 chatbot 场景下用户经常有超长对话历史,必须把 KV 压到极致才能保住经济学。

路 3:MLA(Multi-head Latent Attention,DeepSeek 的招)

DeepSeek 的创新。不直接存 K 和 V,而是存一个压缩过的潜在向量,用的时候再解压。

类比:别存原图,存 JPEG;用的时候再解码。

🔑 MLA 把 KV 大小降到 GQA 的 1/4 左右,而且质量几乎没损失。这是 DeepSeek V3 能用极小 KV 跑超长上下文的关键。

路 4:稀疏 attention(只看一部分历史)

前面三条都在压「每个 token 的 KV 大小」。稀疏 attention 走的是另一条路:新 token 不去看所有历史 token,只看一个子集

如果稀疏模式选得好,KV 搬运成本能从 O(L) 降到 O(√L)

🔑 代价:模型可能漏掉远处的关键信息。所以质量上是有损的,只能在「大部分长程信息不重要」的场景用。

四条路对比

技术KV 降幅质量损失现实使用
GQA4-8×几乎无几乎所有主流模型
跨层共享2-N×小到中等Character.AI、Gemma
MLA几乎无DeepSeek 系列
稀疏 attention√L 改进中等少数实验性部署

三、从 API 定价反推架构——最漂亮的一段

现在你已经有了反推的全部前置知识。咱们就拿 Gemini 做案例。

已知线索

历史上 Gemini 1.5 Pro 在长上下文阈值(128K / 200K 这一档)之后用过阶梯定价(典型做法是单价翻倍)。

为什么定价要分档? Gemini 的运营方想保证:无论上下文多长,每段都不亏本。在两个区域(KV 主导 vs 算力主导)成本结构不同,所以定价也得分两档。

🔑 阶梯拐点的位置直接暴露了底层成本曲线的形状——它就是 KV 项追上算力项的瞬间。咱们能用这一点反推架构。

找拐点条件

在拐点处,KV 搬运时间正好等于算力时间(假设 Batch 已经足够大,参数项可忽略):

L×bBW=NactiveC\frac{L \times b}{BW} = \frac{N_{active}}{C}

解 b

b=NactiveL×BWC=NactiveL×1300b = \frac{N_{active}}{L} \times \frac{BW}{C} = \frac{N_{active}}{L} \times \frac{1}{300}

代入 L = 200K(拐点位置),N_active 估计 100B(对 Gemini 这个量级模型的合理猜测):

b100×109200×103×1300=500,0003001,667 字节2 KB / tokenb \approx \frac{100 \times 10^9}{200 \times 10^3} \times \frac{1}{300} = \frac{500{,}000}{300} \approx 1{,}667 \text{ 字节} \approx 2 \text{ KB / token}

🔑 得到 ~2 KB / token——这就是 Gemini 这个模型每个 token 的 KV 字节数。

这个 2 KB 意味着什么?

用第二节「四条路」的知识反推它的架构:

b = 层数 × KV head 数 × head 维度 × 2 × 精度字节数 2000 ≈ 层数 × 8 × 128 × 2 × 1

解出:等效层数 ≈ 1

🔑 这意味着 Gemini 极有可能用了跨层共享 KV(类似 Character.AI 风格)——所有层共享一组 KV,所以「等效层数」被压到 1。

咱们刚才做了什么?

🔑 仅凭 Google 公开的 API 定价(200K 阶梯),咱们反推出了 Gemini 内部架构使用了跨层共享 KV。这就是这套工具的核心威力——任何 AI 公司的定价文档,都是关于他们内部架构的间接情报


四、再来一次:从输入/输出价差反推 decode 瓶颈

另一个反推:很多 provider 的输出 token 比输入 token 贵约 5×。这告诉咱们什么?

区分 prefill 和 decode

  • Prefill(处理输入):一次性吃进 N 个 token,并行计算所有它们的 KV
  • Decode(生成输出):一次只生成 1 个 token,但每次都要把所有历史 KV 读一遍

关键差异:

阶段计算量内存读取量
Prefill 处理 N tokensN × N_active搬 1 次参数
Decode 生成 N tokensN × N_active搬 N 次参数 + 搬 N 次 KV

计算量是一样的,但内存读取 decode 是 prefill 的 N 倍以上。

平均到每 token 的成本

  • Prefill:成本被 N 个 token 一起摊销(一次搬运服务 N 个 token)
  • Decode:每个 token 都要单独搬一次

🔑 Prefill 是 compute-bound,Decode 是 memory-bound。同一个硬件、同一个模型,只是 workload 形态不同,经济学完全不同。

5× 价差意味着什么?

如果一家 provider 的 input/output 价差是 5×,那意味着:decode 的实际成本约是 prefill 的 5×

回到 roofline 分析:两阶段花的时间比例约 5:1。也就是:

🔑 Decode 阶段,内存时间是计算时间的约 5 倍——也就是 GPU 工人 80% 时间在闲着等数据。

这就是「decode 严重 memory-bound」的精确含义——不是泛泛说「内存慢」,而是具体到 5 倍这个倍数

把每个定价数字当 X 光片读

有了这两段反推训练,你现在能从任何 provider 的定价表读出几件事:

  1. 有没有 long-context 阶梯定价?
    • 有 → provider 用了某种长上下文优化(GQA / 跨层共享 / MLA),且拐点位置暴露了 b 的大小
    • 无 → 要么 provider 不在乎长上下文成本(可能是离线 batch 服务),要么用了极致压缩让拐点不存在
  2. Input/Output 价差多大?
    • 5-10× → 标准 decode-bound 情况
    • 价差很小(< 2×)→ 可能这家走 prefill-heavy workload(比如批量文档分析)
    • 价差很大(> 10×)→ 可能用了非常激进的 decode 优化(MLA、speculative decoding),或者硬件 C/BW 比值偏高
  3. Cache hit 折扣多少?
    • 5-10× 便宜 → 把高频前缀放在 HBM
    • 几十× 便宜 → 放在 DDR / Flash(更慢但更便宜的存储层)

🔑 每个定价数字背后,都是 provider 内部架构选择的具体后果


五、退一步:架构创新到底在改什么?

讲到这里你可能注意到一个事实:前面提到的所有创新最终都在「降成本」——GQA、MLA、跨层共享、稀疏 attention、MoE、量化⋯⋯全是。

那它们之间有什么本质区别?为什么有的叫「算得快」,有的叫「经济学优化」?

咱们退一步,给所有 AI 架构创新做一个统一分类。回到核心公式:

T=max(NtotalBW+B×L×bBW内存项, B×NactiveC算力项)T = \max\left(\underbrace{\frac{N_{total}}{BW} + \frac{B \times L \times b}{BW}}_{\text{内存项}},\ \underbrace{\frac{B \times N_{active}}{C}}_{\text{算力项}}\right)

任何创新最终都在改这个公式里的某个量。但改不同的量,带来的成本下降方式根本不同——这就是分类的基础。

路径 1:改「工作量」——直接降算力时间

典型代表:更稀疏的 MoE、剪枝、量化、speculative decoding。

机制:让 N_active 变小,或让等效计算量变小。

几何效果T_compute 那条线整体下移,甜蜜点位置也跟着移。

特点

  • 成本下降在所有 Batch、所有上下文长度下都成立
  • 通常伴随质量损失(剪掉的、量化掉的、跳过的,都是模型本来该做的工作)
  • 是「算得快」型——你确实减少了机器要做的工作

🔑 判别信号有质量代价,且代价随激进程度增长。

路径 2:改「摊销结构」——让 Batch 经济学不崩

典型代表:GQA、MLA、跨层共享 KV。

机制:让 b(KV bytes / token)变小。

几何效果不改变甜蜜点位置,但改变「长上下文下能否到达甜蜜点」。

特点

  • 短上下文下,这些创新几乎看不出效果(因为 KV 项本来就被算力项盖住了)
  • 长上下文下效果显著放大
  • 通常质量损失极小(只是改了 KV 的表示方式,不是改了模型在做什么)

🔑 判别信号质量代价极小,但只在特定 workload(长上下文)下才显出价值

路径 3:改「硬件常数」——让物理墙整体后退

典型代表:更大的 scale-up domain、更快的 HBM、FP8 / FP4、更多 GPU 互联。

机制:让 C 变大,或 BW 变大。

几何效果:整张图横纵双向缩放——甜蜜点移动、成本下界下降、延迟下界下降,全都改。

特点

  • 没有质量代价(纯硬件)
  • 但需要重做硬件(贵、慢、需要供应链配合)

🔑 判别信号完全没质量代价,但成本和时间巨大

把过去几年的创新放进这个表

创新改的是路径判别证据
MoE(稀疏 expert)N_active 变小1:算得快整体算力下降,有轻微质量代价
GQAb 变小2:经济学优化短上下文几乎无感,长上下文显效
MLAb 变小2:经济学优化同上
跨层共享 KVb 变小2:经济学优化同上
稀疏 attention等效 L 变小(√L)1 + 2:双重收益有中等质量代价
FP8 / FP4 量化等效 BW 变大3:硬件常数整张图缩放,可能微小质量代价
Speculative decoding等效 N_active 变小1:算得快加速 decode,无质量代价但有失败率
Flash Attention优化中间张量读写接近 3:硬件常数内存读取顺序改善,大幅省 HBM 带宽
Blackwell 大 scale-upBW 变大3:硬件常数整张图缩放,无质量代价

🔑 真实创新经常是几条路径的组合,这个三分法不是死框架,是个分析角度

这个区分有什么用?

回到一开始的疑问:「既然都是降成本,为什么要区分?」

🔑 因为不同路径的创新,适用场景和组合方式完全不同

场景 1:你想在长上下文 agent 场景下省钱

  • ✅ 路径 2(MLA、GQA)→ 直接救你的命
  • ⚠️ 路径 1(MoE)→ 有帮助,但不能替代路径 2(MoE 不解决 KV 项)
  • ⚠️ 路径 3(换 Blackwell)→ 有效但贵

场景 2:你想压低简单 chatbot 的成本

  • ⚠️ 路径 2 → 几乎没用(短上下文 KV 不主导)
  • ✅ 路径 1(MoE、量化)→ 直接降本
  • ✅ 路径 3 → 有效

场景 3:你在评估一家 provider 的可持续性

  • 看它定价的形状(有无 long-context 拐点、input/output 价差)
  • 形状告诉你它用了哪些路径的创新
  • 路径决定了它的可持续性——纯靠路径 1(激进量化)的 provider,在质量竞争激烈时可能扛不住

一个更深的洞察

你可能会问:「为什么过去几年所有创新都好像围着成本转?」

🔑 AI 推理领域已经过了「求速度」的阶段,进入了「求经济学」的阶段

GPT-2 时代,大家在乎「模型能不能跑」;GPT-3 时代,在乎「跑得快不快」;GPT-4 之后,所有玩家都在乎「每百万 token 多少钱才能盈利」。

所以你看到的「所有创新都在降成本」不是错觉——这是当前阶段的事实。区分类型不是为了否定这个事实,是为了在这个事实里看清楚「谁在用哪条路径」。


六、一段话总结

🗺️

KV cache 一句话:每 token 几十到几百 KB 的笔记,跟着 batch 和上下文长度线性放大,没办法被 Batch 摊销。

降本四条路:GQA / 跨层共享 / MLA / 稀疏 attention。

反推核心招:定价形状(拐点位置、价差大小)是内部架构的间接情报。

架构创新三分法

  • 「算得快」型 = 改公式里的「工作量」变量
  • 「经济学优化」型 = 改公式里的「摊销结构」,让某项不至于失控
  • 「硬件常数」型 = 让物理墙整体后退

三者最终都降成本,但通过完全不同的几何路径。能区分这三类是真·工程师品味。


七、留几个可以自己想的问题

  1. 某 provider 报价:输入 $0.5 / 1M tokens、输出 $5.0 / 1M tokens(10× 差距)、无 long-context 阶梯定价。从这三个数字能推出关于这家 provider 内部 workload 和硬件配置的什么信息?它适合什么类型的应用?
  2. MLA 大幅压缩了 b(每 token KV 字节数)。回到第二篇的甜蜜点公式 B = 300 × (N_total / N_active)MLA 会影响这个甜蜜点的位置吗?为什么? 进一步:如果 MLA 不影响甜蜜点,它的真正价值到底在哪里?
  3. 两家 provider 用 70B 模型,整体定价相近,但其中一家的输入/输出价差是 3×,另一家是 8×。它们用的可能是同一个模型吗?如果是,它们的硬件配置(C/BW 比值)差异如何?
  4. Flash Attention 严格说不属于上面三条路径里的任何一种(它优化的是中间张量读写顺序)。如果你要把它归类,会归到哪条路径?理由是什么?

🚀

下一篇预告:到目前为止,咱们都还在「一台 GPU 内部」看问题。下一篇咱们走出这一台机器,进入多 GPU 集群的世界——三种并行(expert / pipeline / tensor)分别在切什么、NVLink 比 InfiniBand 快 8 倍意味着什么、为什么 MoE 强烈偏好「一个机柜内」、为什么 Blackwell 把 scale-up 从 8 推到 72,以及最关键的——「为什么模型规模卡在 1T 这么多年才动起来」的答案。

最后更新于: