土法炼钢兴趣小组的算法知识备份

【Transformer 与注意力机制】49|KV Cache:推理为什么是 O(n) 不是 O(n²)

文章导航

分类入口
transformer
标签入口
#transformer#kv-cache#inference#prefill-decode#gqa-mla#pagedattention#kv-cache-quantization

Transformer系列导航

按系列顺序继续阅读,而不是停在单篇。

系列目录上一篇:【Transformer 与注意力机制】48|从 logits 到文本:解码策略是决策层,不是收尾细节下一篇:【Transformer 与注意力机制】50|Speculative Decoding:用小模型加速大模型

目录

训练一个 Decoder-only Transformer 时,给它一整段 token,模型可以并行算出每个位置的 logits——causal mask 保证第 \(i\) 个位置看不到未来,但所有位置的计算仍然能塞进同一个大矩阵。推理不是这样。模型必须先生成第一个 token,才能把它放回上下文,再生成下一个。如果每生成一个新 token 就把整个前缀重新跑一遍网络,生成第 1000 个 token 时要重算前 999 个 token 的所有中间表示,生成第 1001 个又要重算一遍前 1000 个——绝大多数计算花在了根本没有变化的历史上。

KV Cache 解决的正是这件事,但把它讲清楚需要回答几个只有上过推理服务才会问的问题:历史 token 的 K 和 V 凭什么可以缓存,同样是矩阵乘出来的 Q 凭什么不行?prefill 和 decode 用的是同一套权重,为什么工程上要分两套路径优化?一份 KV Cache 占多少显存,这个数字怎么把”长上下文”从一句产品宣传变成一道显存约束题?MQA/GQA、PagedAttention、cache 量化这三个经常被一起提起的名词,到底各自在动公式里的哪一项——是不是随便叠加就能把显存问题一次性解决?

本篇能让你学会四件事:

  1. K/V 为什么可以缓存、Q 为什么不能——一个可以自己核对的归纳证明,而不是”Q 还没生成”这种似是而非的说法;
  2. prefill 与 decode 为什么是两种计算形态,这个差异如何决定了后续所有推理优化的分工;
  3. KV Cache 的显存公式,以及它如何在长上下文场景里把”服务能撑多少并发”变成一道硬约束;
  4. MQA/GQA/MLA、PagedAttention、cache 量化、驱逐类方法各自在压缩公式的哪一项,为什么它们正交、可以叠加,又在哪里出现了尚无定论的争议。

一、自回归推理里,历史到底有没有变

假设模型已经看到前缀 The cat sat on the,现在要预测下一个 token。朴素做法是把五个 token 全部送进模型,取最后一个位置的 logits,采样出 mat。下一步上下文变成 The cat sat on the mat,如果继续朴素做法,就把六个 token 全部重新送进模型——前五个 token 的每一层中间表示都被重复算了一遍。

但从 causal mask 的角度看,前五个 token 的表示不会因为后面多生成了 mat 而改变:历史不能看未来,这是自回归模型的基本约束。真正需要新增计算的,只是新 token 在每一层产生的 Query、Key、Value,以及它对历史 K/V 的 attention。这句话听起来是常识,但下一节要把它变成一个可以逐步核对的证明,而不是停留在直觉层面——因为这个证明会直接回答”K/V 能缓存、Q 不能”这个问题,而且答案和大多数教程给出的解释不完全一样。


二、K/V 为什么可以缓存,Q 为什么不能——一个可以自己核对的证明

多数教程对这个问题的解释是”新 token 的 Query 依赖当前隐藏状态,而当前 token 刚生成,还不知道,所以不能提前缓存”。这个说法只说对了一半——它解释了为什么不能提前算出未来的 K/V/Q,却没解释为什么算出来之后,K/V 值得缓存而 Q 不值得。这是两个不同的问题,后一个才是本节要回答的。

先把不变量写成可以核对的归纳证明。记第 \(l\) 层、位置 \(i\) 的隐藏状态为 \(h_i^{(l)}\)\(h_i^{(0)}\) 是 token embedding 加位置编码。每一层的计算是:

\[ Q_i^{(l)} = h_i^{(l-1)} W_Q^{(l)}, \quad K_i^{(l)} = h_i^{(l-1)} W_K^{(l)}, \quad V_i^{(l)} = h_i^{(l-1)} W_V^{(l)} \]

\[ o_i^{(l)} = \sum_{j\le i} \mathrm{softmax}_j\!\left(\frac{Q_i^{(l)} {K_j^{(l)}}^\top}{\sqrt{d}}\right) V_j^{(l)}, \qquad h_i^{(l)} = g\big(o_i^{(l)}, h_i^{(l-1)}\big) \]

其中 \(g\) 代表残差连接加 FFN 的组合。causal mask 把求和范围限制在 \(j\le i\)17|Causal Mask 已经证明过这一点,这里直接沿用。

命题:对任意层 \(l\)\(h_i^{(l)}\) 只依赖 \(x_1,\dots,x_i\),与 \(x_{i+1},x_{i+2},\dots\) 无关。

证明(对 \(l\) 归纳):\(l=0\)\(h_i^{(0)}\) 只是 \(x_i\) 和位置 \(i\) 的函数,命题成立。假设对所有 \(j\)\(h_j^{(l-1)}\) 只依赖 \(x_1,\dots,x_j\)。那么 \(K_j^{(l)}, V_j^{(l)}\) 作为 \(h_j^{(l-1)}\) 的线性变换,也只依赖 \(x_1,\dots,x_j\)\(o_i^{(l)}\) 的求和范围是 \(j\le i\),涉及的 \(K_j^{(l)}, V_j^{(l)}\)\(j\le i\))都只依赖各自的前缀 \(x_1,\dots,x_j \subseteq x_1,\dots,x_i\),涉及的 \(Q_i^{(l)}\) 由归纳假设只依赖 \(x_1,\dots,x_i\)。所以 \(o_i^{(l)}\)、进而 \(h_i^{(l)}=g(o_i^{(l)},h_i^{(l-1)})\) 只依赖 \(x_1,\dots,x_i\)。证毕。

这个证明的推论是:只要前缀 \(x_1,\dots,x_i\) 不变,\(K_i^{(l)}, V_i^{(l)}\) 就永远不变——生成 \(x_{i+1}, x_{i+2},\dots\) 都不会追溯修改它们。这是缓存合法性的来源,也是”历史 K/V 一算出来就可以存进 cache、之后只读不写”的根据。

但注意证明里的对称性:\(Q_i^{(l)}\) 同样只依赖 \(x_1,\dots,x_i\),和 \(K_i^{(l)}, V_i^{(l)}\) 一样”前缀不变就不变”。数学上 Q 并不比 K/V 更易变,真正的区别在读取模式,不在数值稳定性

所以”K/V 可缓存、Q 不可缓存”更准确的表述是:缓存的价值来自被复用的次数,K/V 被未来所有 decode 步复用,Q 的复用次数恒为零——不是”Q 还没算出来”,Q 和 K/V 是在同一时刻、用同样的方式算出来的。

还有一点容易被忽略:证明里的 \(h_j^{(l-1)}\) 逐层不同,所以每一层的 \(K^{(l)}, V^{(l)}\) 都是独立的值,不能跨层共用同一份 cache(第六节要讲的跨层共享方案是有意打破这条独立性来换显存,那是后话)。多层 Transformer 的 cache 规模因此随层数线性增长,这一点会直接进入下一节的显存公式。


三、prefill 与 decode:一次算完 vs 一步一个 token

LLM 推理分两阶段。prefill 处理用户输入的完整 prompt:\(n\) 个 token 一次性通过网络,每层同时产出这 \(n\) 个位置的 \(K,V\) 并写入 cache,causal mask 保证内部因果关系正确。decode 阶段每步只处理 1 个新 token:它的 Q 和 cache 里所有历史 K/V 做 attention,产出下一个 logits,新产出的 K/V 追加进 cache。

这不只是”批大小不同”,是两种完全不同的计算特性。用算术强度(arithmetic intensity,每字节访存对应多少次浮点运算)衡量:一次 Linear 层 \(y=xW\)\(x\) 形状 \([B,d_{in}]\),算术强度近似等于有效 batch \(B\)。prefill 阶段的有效 batch 是 \(\mathrm{batch}\times n\)(prompt 长度直接乘进了算术强度),算术强度通常远高于硬件的 compute/bandwidth 拐点,落在 compute-bound 区间;decode 阶段每步只新增 1 个 token,有效 batch 就是请求数本身,算术强度低得多,落在 memory-bound 区间——真正卡住 decode 的不是算力,是把权重和 KV Cache 从显存搬到计算单元的带宽。这套 roofline 推导与 A100/H100 的具体拐点数字见 llm-infra/11 §3.2,本文不重复推导,只钉住结论:prefill 吃算力,decode 吃带宽,这个差异是后面所有推理优化技术分工的起点——本篇要讲的显存压缩解决的是 decode 一侧”带宽要搬多少字节”这件事;decode 被压到极限之后还能不能再快,是 50|Speculative Decoding 要回答的问题。

常有一种说法是”KV Cache 让推理从 \(O(n^2)\) 变成 \(O(n)\)“,更准确的说法是:在逐 token decode 阶段,每新增一个 token 不再重算整条前缀,而是对已有历史做一次增量 attention——单步开销仍随当前历史长度增长,只是避免了”每步重跑全部前缀”这个更差的基线。对生成长度 \(T\)、上下文长度 \(S\) 的整段 decode 而言,总 attention 计算量是 \(O(S\cdot T)\) 量级,比朴素重算的 \(O(S\cdot T^2)\) 好得多,但既不是常数,也不严格线性于 \(T\)(因为 \(S\) 本身会随生成增长)。


四、显存公式:用计算换显存的账本

KV Cache 不消灭计算量,它把”每步重算历史”的计算成本,换成了”把历史 K/V 长期占在显存里”的存储成本。每一层、每个请求、每个 token 都要留下两份数据(K 和 V),公式是:

\[ \mathrm{CacheBytes} = 2 \times L \times B \times S \times H_{kv} \times D_h \times \mathrm{bytes} \]

\(L\) 是层数,\(B\) 是 batch size,\(S\) 是已缓存序列长度,\(H_{kv}\) 是 KV head 数(标准 MHA 下等于 query head 数 \(H\);第六节要讲的 MQA/GQA/MLA 都在动这一项),\(D_h\) 是每个 head 的维度,\(\mathrm{bytes}\) 是精度对应的字节数(FP16/BF16 通常是 2,量化后可以更小)。这几个乘数因子里,\(S\) 由用户输入决定、\(B\) 由并发决定,剩下的由模型架构决定——第六节的三条压缩路线,本质上是在这几个乘数里各自动一个不同的因子,这一点先记住,后面会反复用到。

单看每 token、每层的字节数:\(2\times H_{kv}\times D_h\times\mathrm{bytes}\)。以 LLaMA-2 70B(GQA,8 个 KV head,\(D_h=128\),FP16)为例,单层单 token 是 \(2\times8\times128\times2=4~\mathrm{KB}\),80 层合计 320 KB/token;4096 token 的上下文,单条序列的 KV 就要 \(320\,\mathrm{KB}\times4096\approx1.3~\mathrm{GB}\)——完整的推导表格见 llm-infra/11 §4.1,这里不重复。要强调的是:这是单条请求的数字,乘上并发数才是真实压力,这正是下一节要算的账。


五、长上下文如何把 cache 逼到墙角

“上下文变长”在产品文案里是一句好话,在显存账本上是一条线性增长的负债:每多 1K token,每条在线请求的 KV Cache 就多几百 KB 到几 MB(取决于模型),而且这份负债在整段对话存续期间持续占着显存,不会像激活值一样算完就释放。

把这条负债摆到一台真实的卡上算总账:以 LLaMA-3-70B(FP16,TP=4)部署在 H100 80GB 为例,权重加 activation 之后留给 KV 的显存大约每卡 40 GB、4 卡合计 160 GB,按 GQA 8 head 的 320 KB/token 换算,能同时”活跃”的 token 总量在 50 万 token 量级。这 50 万 token 一旦按并发请求摊开,数字缩水得很快:4K 上下文能撑约 125 个并发请求,16K 上下文降到约 30 个,128K 上下文只剩 3 到 4 个——完整推导与 PagedAttention 碎片率修正见 llm-infra/11 §4.6

这解释了一个经常被误读的现象:长上下文模型”能看多少 token”和”服务能撑多少并发”是两个独立的数字,前者由模型架构和训练决定,后者由这张显存账本决定。多轮对话和 Agent 场景会让这张账本更难看——每一轮新增的消息、工具调用结果、检索片段都会追加进同一条会话的 KV Cache,会话越长、越活跃,负债增长越快,而且大多数团队会选择让活跃会话的 KV 整段保留(避免每轮从头 prefill),这意味着长会话的显存占用不会随时间摊薄,只会累积。


六、三条正交的压缩路线,各解决哪一环

第四节的公式里有几个乘数:\(L, B, S, H_{kv}, D_h, \mathrm{bytes}\)。业界针对这张账本,事实上分了三条互不替代的正交路线,外加一条愿意用信息换显存的有损路线。搞混它们,会导致”我已经上了 PagedAttention,为什么显存还是不够”这类真实的排障困惑——它们动的是完全不同的乘数。

路线 动的是哪个因子 代表 work 是否有损 典型收益(引用数据,量级参考)
结构性压缩 \(H_{kv}\)(或引入跨层共享,等效动 \(L\) MQA、GQA、MLA、CLA/YOCO 训练阶段选定架构,近似无损 4–8× 甚至更高,依方案
内存管理 有效利用率(不动公式任何一项,动”浪费掉多少”) PagedAttention 无损 利用率从 20–40% 提到接近 100%
数值精度 \(\mathrm{bytes}\) KV 量化(KIVI 等) 近似无损到需校准 INT8 几乎无损;2bit 峰值内存降 2.6×
驱逐 / 稀疏 \(S\)(丢弃部分历史,是删除不是压缩) StreamingLLM、H2O 有损,丢弃的历史信息不可恢复 支持无限长流式,但改变模型可访问信息

6.1 结构性压缩:动 \(H_{kv}\),这条谱系怎么走过来的

标准 Multi-Head Attention(Vaswani et al., NeurIPS 2017)里 \(H_{kv}=H\),每个 query head 配一组独立的 K/V head。Shazeer(arXiv:1911.02150, 2019)提出 Multi-Query Attention(MQA):所有 query head 共享同一组 K/V,\(H_{kv}=1\),cache 直接除以 \(H\),但精度损失明显,训练也更难收敛。Ainslie 等人(EMNLP 2023)的 Grouped-Query Attention(GQA)取折中:\(Q\)\(H\) 组,KV 分 \(g\) 组(\(g\ll H\),常见 8),每组 KV 被多个 Q 共享——这是目前 LLaMA-2/3、Qwen2/2.5、Mistral 等主流开源模型的默认选择。

DeepSeek-V2(DeepSeek-AI, arXiv:2405.04434, 2024)的 Multi-head Latent Attention(MLA)走了一条不同的路:不减少 head 数,而是把 K、V 联合压缩进一个低维 latent 向量缓存,推理时用矩阵吸收技巧把 latent 展开回等效的多头 K/V,不需要真的物化高维 K/V。论文报告相对 DeepSeek 67B(MHA 基线)KV Cache 降低 93.3%、最大生成吞吐提升 5.76 倍。这套压缩依赖两个工程技巧——权重吸收(weight absorption)和 RoPE 解耦(decoupled RoPE),否则旋转位置编码没法直接套在压缩后的 latent 上;完整推导见 llm-infra/11 §4.3,本文不重复。

再往后是把”层”也纳入压缩维度:Brandon 等人的 Cross-Layer Attention(CLA, arXiv:2405.12981, NeurIPS 2024)让相邻若干层共享同一组 K/V,在 1B、3B 规模的从零训练实验中,叠加在 MQA 之上再省 2 倍 cache、困惑度几乎不变;Sun 等人的 YOCO(arXiv:2405.05254, NeurIPS 2024 oral)用 decoder-decoder 架构让全模型只在中间层物化一次 KV,后半部分层通过 cross-attention 复用同一份 cache。这两个方向和头数压缩(MQA/GQA)、latent 压缩(MLA)是正交的——它们动的是 \(L\),不是 \(H_{kv}\),理论上可以叠加,但目前的验证规模远小于生产模型(见第七节)。

6.2 内存管理:PagedAttention 动的不是字节总量,是浪费率

前面的结构性压缩改变的是公式里 \(H_{kv}\) 这个因子的取值——它们决定了理论上最少要存多少字节。PagedAttention(Kwon et al., SOSP 2023)解决的是另一个问题:实际分配出去的显存里,有多少字节真的被有效利用。传统实现给每条请求按 max_seq_len 连续预分配,vLLM 论文实测这种做法的 KV 显存实际利用率只有 20–40%——剩下的是内部碎片(预留但没用到)和外部碎片(请求下架后留下、放不进新请求的窟窿)。PagedAttention 把 KV Cache 切成固定大小的 block,用类似 OS 虚拟内存的页表做逻辑到物理的映射,让物理显存不必连续,利用率因此顶到接近 100%。它不会让 320 KB/token 的理论数字变小,但会让”实际能服务多少并发”逼近这个理论数字——具体数据结构、block size 取舍、COW 与抢占策略见 llm-infra/12,本文不重写这套机制。

6.3 数值精度:量化动的是 \(\mathrm{bytes}\)

KV 量化把公式里的 \(\mathrm{bytes}\) 项从 FP16 的 2 压到更低。INT8 通常几乎无损,因为 attention 的 K/V 数值分布相对温和;更激进的 2bit 需要专门设计。Liu 等人的 KIVI(ICML 2024)对 KV Cache 元素分布做了实测分析,发现 Key 应该按 channel 量化、Value 应该按 token 量化——这个非对称策略是从数据分布里”测出来的”,套用权重量化(通常按 tensor 或按行/列)的方案在 KV 上效果并不好。KIVI 在 Llama-2/Falcon/Mistral 上做到 2bit KV,峰值内存降 2.6 倍(含权重),支持 4 倍大的 batch,吞吐提升 2.35 到 3.47 倍(论文自测数据)。量化动的是”每个数存几个字节”,和结构性压缩”存几个数”是两个独立的乘数,理论上可以叠加——MLA 之上继续做 KV 量化,或者 GQA 之上做 KV 量化,都是主流引擎(vLLM、TensorRT-LLM)已经支持的组合。

6.4 驱逐与稀疏:唯一一条有损的路线,动的是 \(S\)

前三条路线共同的前提是”不丢历史信息,只是换一种更省空间的方式存”。驱逐类方法不一样,它们是真的丢弃部分历史 token 的 K/V。Xiao 等人的 StreamingLLM(ICLR 2024, arXiv:2309.17453)发现一个现象:序列开头几个 token 会吸收不成比例的注意力权重,不管它们语义上是否重要(“attention sink”);只要保留这几个 sink token 加一个滑动窗口的最近历史,模型就能在理论上无限长的流式输入下保持稳定,而单纯的滑动窗口(不保留 sink)会在窗口滑出后迅速崩溃。Zhang 等人的 H2O(NeurIPS 2023)把驱逐建模成动态子模最大化问题,保留累计注意力权重最高的”heavy hitter” token 加最近窗口,在 OPT/LLaMA/GPT-NeoX 上验证了这套策略在多数任务上损失可控。

这条路线和前三条本质不同:前三条无论怎么压,理论上都保留了全部历史信息(latent 压缩、量化、分页都是可逆或近似无损的编码方式),驱逐类方法丢掉的信息拿不回来。省了多少显存,就要承担多少”这段历史万一后面被问到怎么办”的风险——这个风险在闲聊场景通常可以接受,在需要精确记住中段某个细节的检索密集型任务上没有普适保证,这一点会在第七节的开放问题里继续展开。


七、争论与开放问题

7.1 争论:结构性压缩是不是已经到头了

第六节按时间顺序排出的谱系——MHA → MQA → GQA → MLA/CLA——容易让人觉得这是一条单向改进的技术进步史,后一个必然比前一个更好。真实情况有一处明确的分歧。

DeepSeek-V2 论文报告 MLA 相对 MHA 基线(DeepSeek 67B)“达到比 MHA 更好的性能,同时需要的 KV Cache 明显更小”——这个比较对象是 MHA,不是已经压过一轮的 GQA。但从 2023 年 GQA 论文发表至今,公开披露架构的主流开源模型——LLaMA-2/3、Qwen2/2.5、Mistral、Gemma——绝大多数选择 GQA 而不是 MLA 作为默认方案,目前只有 DeepSeek 系列在生产模型里全系坚持使用 MLA。这是可以核实的工业选择事实,不是编造的对立观点。

分歧点在于:是 MLA 额外的工程复杂度——权重吸收技巧、RoPE 解耦、和现有 GQA 生态(kernel、量化工具链)的兼容成本——让大多数团队在”够用”和”理论最优”之间选择了更简单的 GQA,还是 MLA 相对 GQA(而不是相对 MHA)的真实收益需要更大模型规模或更长上下文才能显现,目前没有一篇公开的、在同一算力和精度预算下把 GQA 和 MLA 做严格 Pareto 对比的第三方复现研究来回答这个问题——已有的 MLA 数据几乎都来自 DeepSeek 自己的论文,比较基线是 MHA。CLA 和 YOCO 代表继续沿”跨层”这个新维度压缩的探索,但目前的实验规模停留在 1B、3B,能不能在 70B 以上量级保持同等比例的收益,也还没有看到公开复现。

7.2 开放问题一:驱逐类方法的”安全边界”缺乏可验证的理论

StreamingLLM 的 attention sink 现象和 H2O 的 heavy hitter 假设都是从实测中总结出来的规律,不是可以事先证明”这些 token 一定可以丢”的定理——H2O 论文本身把驱逐建模成子模最大化问题并给出了近似最优的理论保证,但那是”给定要丢多少、丢得尽量不错”的保证,不是”哪些内容可以放心丢”的保证。对需要精确记住中段某个细节的检索密集型任务(长文档问答、多跳推理),驱逐策略的失效边界目前主要靠逐个 benchmark 去测,没有一个通用的、给定任务类型就能预测”丢多少、丢哪里会出问题”的判据。这个问题重要,因为它直接决定了驱逐类方法能不能在生产环境里默认打开,还是只能用在”闲聊、不追溯细节”这类低风险场景。可读入口是这两篇原始论文各自的局限性讨论:StreamingLLM 明确承认窗口外的中间 token 一旦丢弃就完全不可恢复,H2O 的子模保证只覆盖”选择质量”,不覆盖”下游任务精度”。

7.3 开放问题二:四条压缩路线能叠加到什么程度,没有统一的成本模型

结构性压缩(动 \(H_{kv}\))、跨层共享(动 \(L\))、数值量化(动 bytes)、驱逐(动 \(S\))理论上互相正交,可以同时使用——比如在 MLA 的 latent 向量上继续做量化,或者在 GQA 之上叠 KV 驱逐。CLA 论文验证过”跨层共享叠加在 MQA 之上”这一组两维组合,但目前公开文献里没有看到三条以上路线联合叠加、并给出统一误差界的系统性研究。工程实践里,这些组合主要靠逐一实验验证效果,没有一个类似 llm-infra/11 §4.6 那样把单条路线的收益量化到 token 级别的框架,能预测”叠三条路线之后误差会不会超出可接受范围”。这个问题会随着模型和场景组合数增加变得更迫切。


八、关键概念回顾


九、常见误解

9.1 “Q 也应该缓存起来,反正也是矩阵乘出来的”

不对。第二节的证明说明 Q 和 K/V 在数学性质上是对称的,区别只在读取模式:K/V 被未来所有 decode 步复用,Q 只在当前这一步被读一次,之后再没有任何位置会用到它。缓存一个只读一次的值不会省计算,只会占显存。

9.2 “KV Cache 让 attention 不再依赖上下文长度”

不对。decode 每一步仍然要让当前 token attend 到全部历史 K/V,第三节已经说明这一步的开销随历史长度增长。KV Cache 避免的是反复重算历史 K/V,不是让历史长度免费。

9.3 “PagedAttention 能减少 KV Cache 的总字节数”

不对。PagedAttention 动的是第六节表格里的”利用率”,不是 \(H_{kv}\)\(D_h\)\(\mathrm{bytes}\) 中任何一个因子。它能把实际可用显存逼近理论值,但理论值本身要靠结构性压缩或量化去降。把这两件事混在一起,是”上了 PagedAttention 显存还是不够”这类排障困惑的常见根源。

9.4 “KV 量化可以直接套用权重量化的方案”

不对。KIVI 的实测发现 Key 和 Value 的最优量化粒度不同(按 channel vs 按 token),这和权重量化常用的按 tensor/按行列方案不是一回事,直接套用效果会打折扣。

9.5 “cache 越大越好”

更大的 cache 能保留更多上下文,但会占用显存、降低并发、增加带宽压力。第五节的账本说明长上下文和高并发在同一张显存表里互相争抢,系统必须在能力、成本和延迟之间权衡,不存在”越大越好”的默认答案。


十、下一步

KV Cache 把”每步重算历史”换成了”把历史长期占在显存里”,第四到第六节的账本说明了这笔交易的成本,以及三条正交的省钱路线。但账本压到最省之后,decode 循环本身没有变——它仍然是一步产出一个 token 的串行过程,而且第三节已经说明这一步大部分时间花在把权重和(压缩后的)KV 从显存搬到计算单元,不是花在算力上。下一篇 50|Speculative Decoding 问的是另一个问题:如果这一步大部分时间算力都在闲置,能不能让一个小模型先猜出几个候选 token,大模型一次 forward 并行验证,在严格保持目标分布不变的前提下把这部分闲置算力换成更快的生成速度。


十一、参考文献

核心论文

  1. Vaswani, A. et al. “Attention Is All You Need.” NeurIPS 2017. Transformer self-attention、causal mask 与标准 MHA 的原始定义。
  2. Shazeer, N. “Fast Transformer Decoding: One Write-Head is All You Need.” arXiv:1911.02150, 2019. Multi-Query Attention(MQA)。
  3. Ainslie, J. et al. “GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints.” EMNLP 2023. Grouped-Query Attention(GQA)。
  4. Kwon, W. et al. “Efficient Memory Management for Large Language Model Serving with PagedAttention.” SOSP 2023. vLLM / PagedAttention 原始论文,KV 利用率 20–40% 的实测来源。
  5. DeepSeek-AI. “DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model.” arXiv:2405.04434, 2024. Multi-head Latent Attention(MLA),KV Cache 降低 93.3%、吞吐提升 5.76 倍的自报告数字。
  6. Brandon, W. et al. “Reducing Transformer Key-Value Cache Size with Cross-Layer Attention.” arXiv:2405.12981, NeurIPS 2024. Cross-Layer Attention(CLA),叠加在 MQA 之上的跨层 KV 共享。
  7. Sun, Y. et al. “You Only Cache Once: Decoder-Decoder Architectures for Language Models.” arXiv:2405.05254, NeurIPS 2024(Oral). YOCO,decoder-decoder 架构下的单次 KV 物化。
  8. Liu, Z. et al. “KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache.” ICML 2024. KV Cache 2bit 量化,Key 按 channel、Value 按 token 的非对称策略。
  9. Xiao, G. et al. “Efficient Streaming Language Models with Attention Sinks.” ICLR 2024(同 arXiv:2309.17453). StreamingLLM,attention sink 现象。
  10. Zhang, Z. et al. “H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models.” NeurIPS 2023. KV 驱逐的动态子模建模。

站内交叉阅读


← 上一篇:48|从 logits 到文本 | 下一篇:50|Speculative Decoding

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-08-08 · transformer

【Transformer 与注意力机制】55|Transformer 的根本局限:为什么 O(n²) 是终极瓶颈

FlashAttention 能把 attention 的 I/O 推到理论下界,却动不了 FLOPs;SETH 复杂度理论进一步证明标准 attention 在多数参数区间没有亚二次算法。本文区分工程瓶颈与架构瓶颈,用 RULER、Lost in the Middle 和数据受限 scaling law 说明长上下文非长期记忆、数据效率有硬约束,并给出新架构必须同时赢下的质量/成本/稳定/生态四条战线。

2026-08-08 · transformer

【Transformer 与注意力机制】59|推理退化:乱码、死循环与无意义文本为何不是同一种 bug

推理退化不是单一故障。死循环、乱码/控制字符、无意义数字串各自踩中注意力正反馈、数值溢出与词表边缘的不同路径。本文分清三种形态的触发条件与可观察信号,钉住 Softmax 马太效应、Attention Sink、Causal Mask 退路切断、FP16/量化与 KV Cache 污染,并给出架构到运行时的分层防线、争论与开放问题。


By .