AI 技术AI 推理 · 10/10
#MLA#KV Cache#DeepSeek#低秩压缩#FlashMLA#LLM 推理

AI 推理系列(十):MLA 如何用低秩压缩重构 KV Cache:从 DeepSeek-V2 到 FlashMLA

围绕长上下文推理中的 KV Cache 容量与带宽瓶颈,解释 Multi-head Latent Attention 如何通过低秩 KV 联合压缩只缓存潜在表示,并分析 Decoupled RoPE、GQA/量化差异、Kernel 融合以及训练与推理路径中的工程权衡。

在长上下文在线推理里,KV Cache 往往同时占据两种稀缺资源:一是显存容量,二是 Decode 阶段持续读取历史状态时的显存带宽。前面的 GQA、KV Cache 量化和 PagedAttention 都在解决这个问题,但它们默认了一个共同前提:历史状态最终仍以某种 Key/Value 形式存在,只是数量更少、精度更低或管理方式更高效。

Multi-head Latent Attention,简称 MLA,进一步改变了这个前提。它不把“完整 K/V”视为唯一必须长期保存的推理状态,而是在模型结构中引入一个更低维的 latent 表示。每个 Token 经过低秩压缩后,只把这份压缩状态和少量位置相关信息写入缓存;需要执行 Attention 时,再利用模型投影参数恢复计算所需的表示。这样,模型把一部分存储成本转换成了额外投影计算,并让缓存规模不再直接跟完整多头 K/V 维度绑定。

KV Cache 为什么不仅是显存容量问题

标准自回归 Attention 在 Prefill 阶段为输入序列建立各层 K/V,进入 Decode 后,每生成一个新 Token,都要让新的 Query 与历史 Key 发生交互,再对历史 Value 做加权聚合。历史 Token 本身不需要重新经过完整 Transformer,但对应的 K/V 必须持续可访问。

如果模型使用普通 Multi-Head Attention,每个 KV Head 都有自己的 Key 和 Value 表示。序列越长、层数越深、KV Head 越多,每个请求需要保留的历史状态就越大。单请求还能容纳时,高并发会进一步把问题放大,因为每条活跃会话都拥有独立的缓存生命周期。

容量只是第一层压力。Decode 每轮还要读取历史 K/V,因此缓存越大,访问的数据量也越大。当服务进入 memory-bound 区域时,GPU 并不是缺少乘法能力,而是需要不断把大量历史状态搬到计算单元附近。于是同一个 KV Cache 同时决定“能放多少请求”和“每轮 Decode 要搬多少数据”。

这也是为什么降低 KV Cache 成本经常能同时影响最大上下文长度、并发容量和每 Token 延迟,但三者不会按同一比例改善。显存下降可以直接释放容量,带宽收益则还取决于 Kernel 是否真正减少了 HBM 读取,以及新增的投影计算有没有抵消这部分收益。

GQA 是少保存几组 K/V,MLA 是改变缓存对象

GQA 的路径比较直接:Query Head 数量可以保持较多,但让多个 Query Head 共享较少的 KV Head。假设模型有 32 个 Query Head,只保留 8 个 KV Head,那么长期缓存的 K/V 组数就随之下降。MQA 则把这种共享推到极端,让所有 Query Head 共用很少的 KV 表示。

MLA 的切入点不同。它不是先生成完整多头 K/V,再决定哪些 Head 共享,而是在生成 K/V 之前先把 Hidden State 映射到较低维的 KV latent。后续 Key 和 Value 所需的信息都从这份 latent 中投影得到。

技术改变什么长期缓存的核心对象主要收益主要代价
MHA每个 Head 独立 K/V完整多头 K/V表达路径直接,生态成熟KV Cache 最大
GQA减少 KV Head 数较少组完整 K/V显著减少缓存,同时保持多 Query HeadHead 共享程度需要模型设计权衡
KV Cache 量化降低 K/V 数值位宽低 Bit K/V不必改变 Attention 主结构量化误差、量化/反量化和 Kernel 成本
MLA用低秩 latent 表示 K/V 信息压缩 latent + 少量位置状态从架构层降低缓存状态维度投影路径和 Kernel 更复杂
PagedAttention改变缓存分配方式原有缓存内容减少碎片并改善动态管理不直接降低每个 Token 的状态维度

因此,“MLA 比 GQA 更高级”并不是一个有意义的结论。两者使用不同方式控制缓存成本:GQA 减少要保存的 KV Head 数量,MLA 则重新定义历史状态以什么形式保存。选择哪种结构取决于模型训练方案、推理 Kernel、硬件目标和质量约束,而不是只比较缓存压缩比例。

低秩 KV 联合压缩到底发生了什么

MLA 的关键不是对已经生成的 K/V 做通用压缩,而是让模型从训练阶段就学习一条低维信息通道。可以把某层 Token 的 Hidden State 记作高维输入,它先通过一个 down projection 进入较小的 latent 空间;Key 和 Value 的内容表示再分别通过后续投影从这个 latent 中形成。

flowchart TD
  A[Token Hidden State] --> B[KV 下投影]
  B --> C[压缩 KV Latent]
  C --> D[写入长期缓存]
  C --> E[Key 内容投影]
  C --> F[Value 投影]
  A --> G[位置分支]
  G --> H[RoPE Key 状态]
  H --> I[写入位置缓存]
  E --> J[Attention 计算]
  F --> J
  I --> J
  J --> K[当前层输出]

这个数据流里最重要的边界是:长期缓存的是 C 和少量 H,而不是把 E、F 对应的完整多头表示全部物化后再永久保存。于是缓存尺寸可以跟 latent 维度关联,而不是直接跟所有 Head 展开后的 K/V 维度关联。

低秩假设提供了这种结构的可能性:高维表示中的有效信息不一定要求用同等规模的独立维度长期保存。模型通过端到端训练学习如何把后续 Attention 所需信息压进更小的状态空间,再通过上投影使用它。这里的“压缩”是参数化表示学习的一部分,不等同于 ZIP、稀疏文件压缩,也不等同于把 FP16 数值直接量化为 INT4。

这同时解释了为什么 MLA 原生更适合从模型设计阶段引入。压缩空间的维度、投影矩阵和 Attention 结构都会影响模型训练。后续 MHA2MLA 一类工作尝试把已有 MHA 模型转换到 MLA 风格,说明迁移并非完全不可能,但这种转换仍然需要结构变更与恢复训练,不能通过 Serving 配置开关瞬间完成。

Decoupled RoPE 为什么是 MLA 中不可忽略的一部分

如果只考虑内容表示,低秩压缩后再投影 K/V 看起来已经足够。但现代大语言模型通常还需要在 Query 和 Key 上编码位置。RoPE 的旋转角度与 Token 位置相关,这会让“先把所有线性投影合并掉”变得不再简单,因为位置相关变换不能无条件被吸收到固定权重矩阵中。

DeepSeek-V2 的 MLA 因此把内容和位置路径解耦。可以把 Query 和 Key 理解为同时包含内容分量与位置分量:内容部分使用低秩压缩和投影,位置相关部分则走单独的 RoPE 路径。推理缓存因此除了压缩 KV latent,还需要保存必要的 RoPE Key 状态。

这项设计的意义不只是“让 RoPE 兼容 MLA”。它实际上决定了后续 Kernel 能否避免完整重建传统 K/V。若位置编码和内容投影彼此缠绕,推理引擎可能不得不生成更大的临时中间状态;解耦以后,系统更容易围绕 latent 直接设计 Attention 数据流。

工程上需要特别区分“数学上能够从 latent 恢复 K/V”和“实际 Kernel 是否真的把完整 K/V 写回 HBM”。前者只是模型定义,后者才决定带宽收益。一个低效实现若每轮先把 latent 展开成完整 K/V、写入显存,再调用传统 Attention Kernel,缓存虽然长期变小,但大量临时数据搬运可能重新成为瓶颈。

Decode 阶段为什么特别能体现缓存状态压缩的价值

长 Prompt Prefill 会处理大量 Token,主要成本通常集中在矩阵计算、Attention 和中间激活。Decode 则不同:每个请求每轮只增加少量新 Token,却要读取越来越长的历史状态。随着序列增长,历史 KV 的读带宽逐渐成为重要成本。

MLA 的潜在系统价值因此不仅是“同一张卡能塞下更长上下文”。如果 Attention Kernel 能直接消费压缩 latent,并通过合适的矩阵变换避免完整 K/V 物化,那么每轮从 HBM 读取的历史状态也可以明显减少。这对高并发 Decode 尤其重要,因为大量请求会同时争夺内存带宽。

但不能只根据缓存字节数推导端到端 speedup。MLA 引入额外的投影关系,而且实际模型还包含 Attention 之外的 MLP、MoE、通信、采样和调度成本。DeepSeek-V2 材料中报告的 KV Cache 降低和整体吞吐提升是该模型完整设计与特定系统环境下的结果,不能把吞吐倍数全部归因于 MLA,也不能直接复制到其他模型。

更可靠的部署验证应分别测量 KV Cache bytes/token、最大并发、Decode 阶段 HBM 流量、Attention Kernel 时间、TPOT 和端到端吞吐。如果缓存明显变小但 TPOT 没有改善,可能说明瓶颈已经转移到权重读取、专家通信或其他层;如果 Kernel 为 latent 重建付出大量额外代价,也可能抵消带宽节省。

FlashMLA 说明模型结构正在和 Kernel 一起设计

传统 MHA 和 GQA 已经拥有非常成熟的 Attention Kernel 生态,很多 GPU 路径直接以 Q/K/V 张量为输入。MLA 改变了长期缓存结构后,沿用完全相同的接口未必是最优方案。真正高效的实现应该围绕压缩状态组织数据流,让恢复、位置处理和 Attention 尽可能融合,而不是在多个 Kernel 之间反复物化中间表示。

FlashMLA 体现的就是这种联合设计方向:模型架构规定了 latent、位置分量和 Attention 的数学关系,Kernel 则决定这些对象如何在 HBM、片上存储和矩阵计算单元之间移动。只有两部分配合,架构层节省的缓存字节才有机会转换成真实的服务收益。

这与 FlashAttention 的经验类似。一个数学上正确的 Attention 可以有很多执行方式,而 GPU 性能高度依赖数据是否需要反复写回 HBM、矩阵形状是否适合硬件、不同阶段是否可以融合。MLA 更进一步,因为模型本身就是为了改变历史状态的表示而设计,Kernel 如果仍坚持把它还原成传统执行形式,就会损失一部分结构优势。

生产环境因此不应该只检查“模型是不是 MLA”。还要确认当前 Serving Runtime 是否走 MLA 专用路径、Prefill 和 Decode 是否使用匹配的 Kernel、当前 head dimension 和数据类型是否触发 fallback,以及 tensor/expert/sequence parallel 组合后有没有引入新的通信开销。

训练路径和推理路径不能简单使用同一种吸收方式

推理优化中常见的一种思路,是把部分线性投影通过代数重排“吸收”进其他计算,从而避免显式恢复完整 K/V。对 Decode 来说,这类变换有机会减少历史状态展开和读取成本。但一个在推理阶段高效的等价计算形式,不代表在训练阶段也拥有相同内存性质。

用户提供的 2026 年 LAGA 研究正是围绕这一边界展开:某些适合 MLA Decode 的吸收式计算如果直接搬到 Sequence Parallelism 训练路径,会改变中间激活和通信形态,可能增加 Activation Memory。这个例子说明,评价 MLA 时必须区分“长期 KV Cache”“训练激活”“通信 Buffer”三类完全不同的内存对象。

阶段主要状态MLA 关注点可能出现的新瓶颈
训练前向/反向激活、梯度、参数和通信状态低秩结构是否可高效反传Activation Memory、Sequence Parallel 通信
Prefill大批 Prompt Token 的中间计算与 KV 建立快速生成压缩缓存Attention 计算、矩阵形状、写缓存吞吐
Decode历史状态读取与少量新 Token 计算尽量直接使用 latent,减少 HBM 流量投影开销、Kernel fallback、并发调度
多卡推理缓存、权重和跨卡通信与 TP/EP 等并行方式协同通信可能盖过缓存带宽收益

因此,MLA 不能被简化成“多做一点计算,少存一点显存”这么单一的交换。不同阶段的计算重排会影响完全不同的数据生命周期,而高效实现往往需要分别设计训练、Prefill 和 Decode 路径。

MLA、GQA、量化和缓存管理可以形成多层优化

长上下文推理很少由单一技术解决。MLA 位于模型架构层,它减少长期保存状态的维度;KV Cache 量化位于数据表示层,可以进一步降低 latent 或其他缓存对象的位宽;PagedAttention 位于内存管理层,负责把实际缓存块高效分配给动态请求;Prefix Caching 则进一步尝试复用已经计算过的历史状态。

这些技术的组合顺序可以理解为:先决定“模型产生什么状态”,再决定“状态用多少 Bit 保存”,随后决定“这些状态放在哪里、怎样分配”,最后决定“哪些状态可以跨请求复用”。每一层都可能继续减少成本,但也都可能引入额外元数据、Kernel 和调度复杂度。

MHA2MLA 一类工作还提出了另一个值得关注的问题:如果已有大量 MHA 权重,是否可以通过结构转换和有限恢复训练获得 MLA 的缓存优势。用户提供的论文材料报告了较大的 KV Cache 压缩比例和较小的任务性能下降,但这些数字属于具体模型、训练方案和评测集,不能当作任意 MHA 模型转换后的固定结果。

对工程团队来说,更有价值的判断不是“MLA 是否先进”,而是当前成本是否真的由 KV Cache 容量和带宽主导。如果服务是短 Prompt、低并发,或者主要瓶颈位于 MoE All-to-All、跨机通信和模型权重读取,那么引入专用 MLA Runtime 的复杂度未必值得。相反,长上下文、高并发、Decode 带宽受限的服务更有理由认真评估这种结构。

如何验证 MLA 的收益没有停留在架构图上

第一组指标应该直接验证缓存是否按预期缩小。可以记录每层每 Token 的缓存字节数、不同上下文长度下的 KV Cache 总量、单卡可容纳的活跃 Token 数和最大并发。这里最好与同等模型规模下的 MHA/GQA 基线做对比,而不是只看绝对显存占用。

第二组指标关注执行路径。Profiler 应确认 Decode Attention 是否直接消费 MLA 缓存,是否出现完整 K/V 临时物化,Kernel 是否发生 fallback,以及 HBM read bytes 是否随缓存压缩真正下降。仅仅看到显存监控变小,不能证明带宽路径已经优化。

第三组指标才是用户可见结果,包括 TTFT、TPOT、吞吐和尾延迟。Prefill 与 Decode 应分开观察,因为 MLA 对两者的收益来源不同。高并发测试也不可省略:单请求可能没有明显带宽压力,只有大量活跃序列同时读取历史状态时,缓存压缩的系统价值才会充分暴露。

最后还必须验证模型质量。MLA 是模型结构,不是无损文件编码;低秩维度、位置路径和训练策略都会影响表示能力。对于从 MHA 转换而来的模型,还要单独评估恢复训练后的短上下文能力、长上下文任务以及与原模型的一致性。任何缓存收益都不能用“结构上能压缩”替代任务级质量验证。

MLA 最值得关注的地方,不是给 Attention 增加了一个新缩写,而是重新提出了“历史状态应该保存什么”的问题。传统 MHA 把完整 K/V 当成自然的缓存单位,GQA 减少这些单位的数量,量化降低每个单位的位宽;MLA 则把长期状态前移到一个学习得到的低维 latent 空间。

当模型、Kernel 和 Serving Runtime 能围绕这份压缩状态共同设计时,长上下文推理的容量与带宽成本就不再只能通过“少几个 Head”或“少几个 Bit”来降低。真正的工程判断仍然要回到端到端数据流:每个历史 Token 到底需要保存多少字节,这些字节每轮被搬运多少次,恢复计算需要付出什么代价,以及最终是否让真实请求在目标质量和 SLO 下承载更多并发。

资料来源

  1. DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
  2. Towards Economical Inference: Enabling DeepSeek's Multi-Head Latent Attention in Any Transformer-based LLMs
  3. FlashMLA: Efficient Multi-head Latent Attention Kernels
  4. A Training-Memory Regression in MLA Sequence Parallelism: Why Megatron-Core Forbids Absorption, and LAGA -- a Communication-Efficient Fix