22

MLA——把 KV 压成 latent 再存

阅读约 5 分钟第 22/60 课

第 16 章节看到 KV cache 随序列长度线性增长,是推理的显存瓶颈。第 17 章节介绍了线性注意力——用固定大小的递推状态完全替代 KV cache。Sophia 的 28 层中有 21 层使用了线性注意力(KDA),但剩下的 7 层仍然需要标准注意力来做精确检索。

这 7 层使用的就是 MLA——Multi-head Latent Attention。它的核心思想是:不存储完整的 K 和 V,而是把它们压缩成一个更小的 latent 向量,只存这个压缩版。

标准多头注意力的存储问题

在标准多头注意力中,每个 token 每一层要存储的 KV cache 大小是:

16 个头 × (K 的 96 维 + V 的 96 维) = 3,072 维

如果有 7 层 MLA,4,096 个 token 的上下文:

7 × 4,096 × 3,072 × 2 字节(BF16)≈ 172 MB

虽然比 28 层全用标准注意力小很多(那会是 688 MB),但对一张消费级 GPU 来说,在同时服务多个用户时仍然可观。

MLA 的压缩思路

MLA 的核心观察是:16 个头的 K 和 V 之间存在大量冗余。 不同头的 K 向量和 V 向量虽然不同,但它们都是从同一个输入向量 x 通过不同的线性变换得到的。既然它们来自同一个源头,信息一定有重叠。

MLA 利用这个冗余来压缩。具体做法:

编码(压缩):把输入向量 x 通过一个降维矩阵,压缩成一个维度远小于 3,072 的 latent 向量 c。

c = x × W_compress     (1536 维 → 比如 512 维)

只存储这个 c,而不是完整的 K 和 V。

解码(恢复):需要计算注意力时,从 c 恢复出 K 和 V。

K = c × W_K_up     (512 维 → 1536 维,再拆成 16 个头各 96 维)
V = c × W_V_up     (512 维 → 1536 维,再拆成 16 个头各 96 维)

压缩比 = 3,072 / 512 = 6 倍。KV cache 的显存占用直接缩小到原来的六分之一。

有什么代价

压缩必然有信息损失——512 个数字不可能完美地恢复出 3,072 个数字。但关键在于:K 和 V 的 3,072 个数字中有大量冗余。如果冗余度足够高,512 维的 latent 就能捕捉其中绝大部分有效信息。

这就像 JPEG 图片压缩:原始图片可能有几百万像素,但 JPEG 能把它压缩到几十 KB 而人眼几乎看不出区别——因为相邻像素之间高度相关,信息冗余很大。

在实践中,MLA 的质量损失很小。DeepSeek 团队最先在 DeepSeek-V2 中验证了 MLA 的有效性,发现它在大幅减少 KV cache 的同时,模型质量几乎不受影响。Sophia 借鉴了这个设计。

额外的计算

压缩节省了存储,但增加了计算——因为每次需要 K 和 V 时,都要从 c 恢复(一次矩阵乘法)。

不过这个额外的计算量相对很小。恢复操作是一个 512 × 1,536 的矩阵乘法,比注意力本身的计算(涉及序列长度的平方)小得多。在显存是瓶颈(而非计算是瓶颈)的推理场景下,用少量额外计算换取大幅减少的显存是划算的。

Sophia 的混合设计总结

把 KDA 和 MLA 放在一起看 Sophia 的 28 层:

层 1-3:   KDA(线性注意力,固定大小的递推状态,不需要 KV cache)
层 4:     MLA(压缩的 KV cache)
层 5-7:   KDA
层 8:     MLA
...
层 25-27: KDA
层 28:    MLA

21 层 KDA + 7 层 MLA:

  • KDA 层:零 KV cache,但精确检索能力有限
  • MLA 层:少量压缩过的 KV cache,提供精确检索

这个混合设计让 Sophia 在有限的显存预算下兼顾了效率和能力。

下一章节来看 Sophia 架构中最后一个独特设计:Attention Residuals——让浅层的信息绕过中间层直达深层。