系统工程 · MLA 压缩
学习舱 / 系统工程 / MLA 压缩

MLA 的 KV 压缩为什么省显存

整理中 深度 · 应用 更新 2026-09-09

前置 推理优化、Attention、RoPE

MLA 的 KV 压缩为什么省显存

一句话定位:MLA(多头潜在注意力)是 DeepSeek 提出的 KV 压缩方案——推理时不缓存完整的 K、V,只缓存一个低秩「潜向量」,用的时候靠矩阵吸收把注意力分数原样算出来。前置:推理优化——KV Cache 的显存账公式在那篇建立;Attention 与 Transformer——GQA 的分组共享是 MLA 要对比的谱系起点;位置编码:RoPE——解耦位置键是本篇的关键配角。

先看一个两难:共用够省,但够好吗

推理优化篇算过:KV Cache 是推理时必须吃的显存,长上下文下能吃掉几十 GiB(长上下文篇的「键值显存墙」)。压缩的第一招是让头与头共用 K、V——MQA 让所有头共用一份(省得最狠、质量损失大),GQA 让分组共用(折中,多数开源模型用它)。

但「共用」的天花板很明显:不管怎么分组,每个头看到的 K、V 都是别人的副本——模型越大、头越多,共用的信息损失越容易被放大。DeepSeek 做 V2 时面临的选择:继续加大共享力度,还是换一条根本不同的路?

能不能既不共用、又不逐头全量存,把缓存压到 MQA 的量级而质量不掉?

他们选了后者:MLA 不共用、也不每个头单独存,而是把所有头的 K、V 压缩成一个低秩潜向量(用一个更小的向量装下所有头的公共信息)存进缓存——用时再把注意力分数原样算出来。论文口径:相比其前代 DeepSeek 67B(GQA 架构),KV 缓存减少 93.3%、最大生成吞吐提升 5.76 倍。

先给两个口径注记:93.3% 是对 67B 整模型的实测;本篇后面的教学账会用「128 头全量 MHA」做假想基线逐层对比——多头注意力(MHA,每头各存一份 K、V)是压缩前的起点,两者基准不同,数字不可互相换算。先看全景:

MLA:存的是压缩包,算的时候不用解压 缓存侧(每 token 每层) 潜向量 512 维 全部头的 K、V 压在这 位置键 64 维 解耦 RoPE 专用 共 576 个数/层,MHA 同口径是 32768 个 计算侧(两条等价路线) 路线 A:潜向量 → 恢复矩阵 → 完整 K → 打分 路线 B:恢复矩阵吸收进查询 → 潜向量直接打分 两条路线分数完全一致(本篇动手实测) 推理走 B:完整 K 根本不用算出来 代价一:位置旋转(RoPE)依赖位置值,静态矩阵吸收不了 → 位置信息拆出来单独存(那 64 维) 代价二:吸收后的计算形状特殊,需要专门优化内核(DeepSeek 开源了 FlashMLA) 谱系一句话:MHA 全量存 → MQA 一份共享 → GQA 分组共享 → MLA 低秩压缩(压缩近 MQA、质量近 MHA) 读法:左边是「存什么」,右边是「怎么用」——压缩包不解压也能算分数,这是 MLA 的独门处

图:MLA 全景——缓存侧只存潜向量与位置键共 576 个数,计算侧走吸收路线连完整 K 都不用恢复;代价是位置键单独缓存与专用内核

渐进拆解:压缩、吸收、让路

低秩联合压缩:一个潜向量装下所有头

MLA 的第一步是给每个 token 的 K、V 拍一卷「微缩胶片」:用一个向下的投影矩阵(一次压缩变换),把这一层所有头要用的键值信息压进一个 512 维的潜向量(DeepSeek-V2 配置口径,下同)。每个注意力头不再有自己的 K、V——需要时用一个向上的投影矩阵从潜向量「恢复」出头专属的那份。

数学上这就是低秩分解:与其存 128 个头各一份完整 K、V,不如存它们共同的那份低维「底稿」——好比 128 个人要看的资料各不相同,但全部源自同一卷微缩胶片,档案室只存胶片,谁的资料都能投影出来。「低秩为什么敢信」也在这:不同头的 K、V 高度相关(大家都在看同一段上下文,只是视角不同),信息天然冗余——这正是低秩压缩的用武之地,潜向量装的是「公共内容」,各头的「视角差异」由恢复矩阵承载。

这条「压进去——按头恢复」的通路画成图:

低秩联合压缩:各头的 K、V,只存一份公共底稿 头 1 的 K、V 头 2 的 K、V 头 3 的 K、V ⋯ 头 128 的 K、V 向下投影(一次压缩变换) 潜向量:512 维 缓存里只存这一份 恢复 用时:向上投影恢复 每头用各自的恢复矩阵取回 不再逐头各存一份副本 不同头的 K、V 高度相关、信息天然冗余:公共内容进潜向量,各头「视角差异」由恢复矩阵承载

图:低秩联合压缩——128 个头的 K、V 经向下投影压进一份潜向量,缓存只存底稿;各头用向上投影矩阵恢复自己的那份

缓存侧的账立刻变小,具体账本(每 token 每层压到 576 个数)见下面谱系图与动手实算;其中 64 个是位置键,来历见下文。

权重吸收:解压这一步可以省掉

如果 MLA 只是「存压缩包、用时解压」,那省了显存却多算了账。真正的妙处是:恢复矩阵可以吸收进查询那一侧——「用恢复矩阵把潜向量升维成 K,再与查询点积」在数学上完全等价于「先用恢复矩阵的转置把查询变换一下,再直接与潜向量点积」。变换后的查询直接吃压缩形式,完整 K 从头到尾不必算出来(本篇动手段用具体数字实算了这条等式)。代价是恢复后的 K 形状不规则,标准注意力内核(GPU 上执行注意力计算的优化程序)不认,需要专门优化的内核——DeepSeek 为此开源了 FlashMLA。

「先恢复再打分」与「先变换查询再打分」为什么完全等价?把两条通路画成图:

权重吸收:同一条等式的两条走法 路线 A:先恢复再打分 用 W 把潜向量 c 升维成 K 再与查询点积 q · (W·c) 注意力分数 路线 B:先吸收再打分 用 Wᵀ 先把查询 q 变换 再与潜向量点积 (Wᵀq) · c 同一个分数 推理走路线 B 完整 K 从头到尾 不必算出来 代价:内核要特制 等式 q·(W·c) = (Wᵀq)·c 对任意矩阵 W 成立——吸收不是近似,是精确等式(动手实测两条路线 10 位小数一致)

图:权重吸收——先恢复完整 K 再打分,与把 Wᵀ 折进查询后直接用潜向量打分,是同一条等式;推理走路线 B,完整 K 不必算出

RoPE 让路:位置信息要单独存放

吸收有一个例外:RoPE(旋转位置编码,负责告诉模型词序)与具体 token 的位置有关,而吸收矩阵是静态权重——「位置相关的旋转」没法折进「位置无关的矩阵」里。MLA 的解法是解耦:把位置信息拆出来,用额外的 64 维小键单独承载并单独缓存;潜向量主体保持位置无关,安心被吸收。这就是全景图里那 64 维「位置键」的来历——它是吸收路线为 RoPE 让出的通道。

MHA → MQA → GQA → MLA 的谱系

四种方案是「缓存怎么省」的四级演化,各方案的缓存数、质量与代表模型的完整对照见下图。以 128 头 ×128 维的模型为例(GQA 取 8 组的教学假设,Llama 70B 级配置;注意力篇里 Qwen2-7B 的 28 头 4 组是另一个常见档位,组数不同比例不同)把账排在一张图里:

四代方案:缓存怎么省,代价是什么(每 token 每层的数) 方案 (128 头 ×128 维) 缓存怎么省 数 = K、V 合计维度 质量 (MHA 为基准) 代表 (公开口径) MHA 每头各存一份 32768 个 (基准) 基准 早期大模型 MQA 全体共用一份 256 个 (省 99.2%) 损失明显 渐被 GQA 取代 GQA 分组共用一份 2048 个 (8 组,省 93.8%) 接近基准 Llama 3 · Qwen 等 MLA 低秩压缩一份 576 个 (省 98.2%) 不输基准 DeepSeek 系

图:四代方案对照——缓存从 MHA 的 32768 个数/层压到 MLA 的 576 个,MLA 与 MQA 同档压缩但质量不输基准;GQA 靠分组拿到了「接近基准」的折中位

这个排序有个数学背书:TransMLA 论文证明 GQA 能表达的注意力结构是 MLA 的真子集(MLA 表达力覆盖 GQA)——任何 GQA 模型都能转换成同等 KV 缓存开销的 MLA,转换只需加一个投影矩阵,但要少量微调恢复性能,反向转换则不总是可行。

代价层面 MLA 也不是免费:潜向量在计算侧要被每个头反复使用,计算路径比 GQA 绕,通用内核跑不快,需要 FlashMLA 这类专用实现——「省显存、费内核」是 MLA 与 GQA 分工的分水岭。

大白话:GQA 是「一个办公室四个人合用一台打印机」——省是省了,打印要排队,且只能打共享的那几种格式;MLA 是「把所有人的文档做成一卷微缩胶片」——档案架(显存)只放胶片,谁的资料都能从胶片投影出来(吸收),只是投影仪(内核)得特制。

技术定义:MLA(Multi-Head Latent Attention,多头潜在注意力)将每层每个 token 的键值经向下投影压缩为低秩潜向量(DeepSeek-V2 为 512 维)缓存,各头以向上投影矩阵从潜向量恢复键值;由于恢复矩阵可与查询侧及输出投影静态合并(权重吸收),推理时无需显式恢复完整 K、V。RoPE 因依赖 token 位置而不可吸收,由 64 维解耦位置键单独承载与缓存;表达力覆盖 GQA(TransMLA 证明的真子集关系)。

动手:亲手验证「吸收」是一条等式

吸收不是近似,是精确的数学等式。用随机小矩阵实算两条路线(完整代码可复跑):

import numpy as np
rng = np.random.default_rng(0)
c = rng.normal(size=8)            # 缓存里的潜向量(示意 8 维)
W_UK = rng.normal(size=(16, 8))   # 某头的恢复矩阵(8 维 → 16 维)
q = rng.normal(size=16)           # 查询向量

score_a = q @ (W_UK @ c)          # 路线 A:恢复完整 K,再打分
q_absorbed = W_UK.T @ q           # 吸收:把恢复矩阵折进查询侧
score_b = q_absorbed @ c          # 路线 B:直接与潜向量点积
print(f"{score_a:.10f} vs {score_b:.10f}")   # 实算:8.4495273986 vs 8.4495273986

两次打分打印出的 10 位小数完全一致(浮点内部差仅约 1e-15)——这就是「推理时不用恢复完整 K」的全部依据:等式 q·(W·c) = (Wᵀq)·c 对任意矩阵 W 成立,MLA 把每个头的恢复矩阵都折进了查询侧。再算缓存账(DeepSeek-V2 维度口径):

mha = 2 * 128 * 128        # MHA:K、V 各 128 头 ×128 维
mla = 512 + 64             # MLA:潜向量 512 + 解耦 RoPE 键 64
print(f"每 token 每层:{mha} 个数 → {mla} 个数(约 {mla/mha:.1%})")
# 实算输出:每 token 每层:32768 个数 → 576 个数(约 1.8%)

账本读法:缓存压到约 1.8%、吸收保分数不变——「省显存不省质量」的机制基础就在这两行实算里。注意这条路对 RoPE 走不通:旋转矩阵随位置变,折不进静态权重,所以才有那 64 维单独缓存的位置键——把这段代码里加一个「随位置变化的旋转」再试吸收,等式立刻不成立,这也是理解解耦设计的最快方式。

边界与取舍

什么时候 MLA 是对的选择? 判据是「显存瓶颈有多硬、内核生态有多深」。长上下文、大并发、自建推理栈(内核可控、能吃 FlashMLA 的优化)→ MLA 的显存收益直接变成并发与成本优势;模型不大、上下文不长、依赖通用推理框架的成熟路径 → GQA 的兼容性与简单性仍然占优。V2 论文自己也给了旁证:5.76 倍的生成吞吐提升——显存省下来直接兑换成了服务能力。

MLA 的代价清单。 三笔代价:

  1. 内核门槛:吸收后的计算形状非标准,通用注意力内核吃不到优化,专用内核(FlashMLA 等)成为必需品——这是「省显存、费内核」。
  2. 位置编码绑死解耦设计:模型从设计起就要按 MLA 组织注意力,存量 GQA 模型只能靠转换工具迁移。
  3. 潜向量维度是超参:压得越狠显存越省、表达力越受限,512 是 V2 选定的工程值(论文未公布该维度的消融)。

坏味道预警:把 MLA 与 GQA 的对比说成「有损 vs 无损」。 GQA 的共用是信息的硬共享(组内头看到的完全相同),MLA 的压缩在信息论意义上也有损(512 维装不下 32768 维的一切)——它的优势是「有损得更聪明」,实测质量不掉。真实的对比口径是「同压缩率下谁的质量高」与「同质量下谁更省」,而不是「谁无损」。

自测

合上文章先自己答,再展开对照:

MLA 推理时怎么把压缩的 KV「吸收」回来?代价是什么?

吸收的机制:注意力分数只需要「查询点乘键」,而 MLA 的键是「恢复矩阵 × 潜向量」——代入后就是「(恢复矩阵转置 × 查询)点乘潜向量」,即把恢复矩阵预先折进查询侧(静态权重可以合并),之后每步直接用潜向量打分,完整 K 从头到尾不必恢复。本篇动手段的实算验证了两条路线打分 10 位小数完全一致(等式 q·(W·c) = (Wᵀq)·c 对任意 W 成立,差值仅浮点误差)。代价有三:① RoPE 位置旋转依赖具体位置,静态矩阵吸收不了——位置信息拆成 64 维解耦键单独承载与缓存;② 吸收后的计算形状非标准,通用内核不认,必须配 FlashMLA 这类专用内核(省显存、费内核);③ 潜向量维度(512)是压缩率与表达力的平衡超参,模型设计期就要定死。

MQA、GQA、MLA 三代压缩方案的本质区别是什么?

区别在「怎么省」:MQA 是所有头共用同一份 K、V(硬共享,缓存最小、质量损失最大);GQA 是分组共用(组内头看完全相同的 K、V,折中方案,Llama 2 后多数开源模型采用);MLA 是低秩压缩——不是谁跟谁共用,而是把所有头的键值信息压进一个 512 维潜向量,各头用各自的恢复矩阵从潜向量取信息,且吸收机制让推理时连恢复都不用做。质量排序上 MLA 不输 MHA,缓存接近 MQA 量级;数学背书是 TransMLA 证明 GQA 能表达的结构是 MLA 的真子集(MLA 表达力覆盖 GQA)。四代演化的主线:从「共用的艺术」走到「压缩的科学」。

参考与延伸

  • DeepSeek-AI《DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model》(2024):MLA 的提出处(93.3% 缓存削减与 5.76 倍吞吐口径出处) — arxiv.org/abs/2405.04434
  • Meng 等《TransMLA: Multi-Head Latent Attention Is All You Need》(2025):GQA 表达力是 MLA 真子集的证明与 GQA→MLA 转换 — arxiv.org/abs/2502.07864
  • DeepSeek《FlashMLA》(开源仓库,2025):MLA 专用推理内核 — github.com/deepseek-ai/FlashMLA
  • 《Understanding Multi-Head Latent Attention》(2025):吸收机制与 RoPE 冲突的逐步推导 — planetbanatt.net/articles/mla.html
  • Ji 等《Towards Economical Inference: Enabling DeepSeek’s Multi-Head Latent Attention in Any Transformer-based LLMs》(MHA2MLA,ACL 2025):存量 MHA 模型迁移 MLA 的微调方法 — aclanthology.org/2025.acl-long.1597

下一站:并行训练:DP / ZeRO / FSDP / TP / PP——MLA 省的是推理显存;训练侧显存更挤,答案是另一族技术:把模型切开分给一群显卡。

本节点大纲与自测题(3 个子点 · 2 问)

大纲

  • MLA 低秩联合压缩 KV
  • 压缩后的吸收(恢复完整 KV)机制
  • 与 GQA / MQA 的谱系对比

自测——答不上来就是缺口

  • MLA 推理时怎么把压缩的 KV「吸收」回来?代价是什么?
  • MQA、GQA、MLA 三代压缩方案的本质区别是什么?