Skip to content

필사 모드: 用 Hybrid SWA 优化长上下文推理 — Xiaomi MiMo v2.5 实际做了什么

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

引言 — 同一个战场,不同的武器

上一篇量子化文章的最后结论是“下一个瓶颈是 KV 缓存”。长上下文中缓存会变得比权重更大,因此我写道:把缓存用更少比特存储的 KV 量子化就是下一个战场。这篇文章讲的是 从另一个轴攻击同一个战场。如果说量子化问的是“一个 KV 条目用几个比特来存”,那么今天的主题——混合 SWA——问的则是“一开始到底要保留多少个 KV 条目”。

起因是 Xiaomi 公开的 MiMo v2.5 推理优化文章。文章的第一句话精准地概括了问题意识——我们想要“既强大又对长上下文推理高效的模型”,但“这两个目标本质上处于紧张关系”。用架构来化解这种紧张的工具,就是混合 SWA。

什么是 Hybrid SWA — 局部窗口与全局视野

在标准注意力中,每个 token 都要看它前面的所有 token——对于序列长度 N,计算量是 N 的平方,KV 缓存则与 N 成正比地增长。 滑动窗口注意力(SWA) 把每个 token 限制为只看最近的 W 个 token。这样一来,单层的计算量就线性化为 N×W,KV 缓存的上限也不再取决于整个序列,而是由窗口大小 W 决定——序列越长,收益越大。

变好的有两件事,最好分开来看。KV 条目减少会让 内存 减少,从而能在同一块 GPU 上承载更多并发请求和更长的上下文(容量收益);而 decode 受限于内存带宽,所以每一步读取更小的缓存本身也意味着 速度(延迟收益)。这正是 MiMo 文章把 KV 压缩称为“容量层面(capacity-level)的收益”的原因——在长上下文里,更大的奖赏在于工作负载一开始能不能被装下。

问题在于,只靠 SWA 会丢失窗口之外的信息。那种需要在文档后文精确回指开头某个名字的任务(即所谓 needle-in-a-haystack),单靠局部窗口就会失效。因此最新的模型不会单独使用 SWA,而是 让大部分层用局部窗口(SWA),少数关键层用全局视野(全注意力) 混合起来。这就是混合 SWA,它始于 Mistral 的 SWA,并在 Gemma 3(提高局部/全局层的比例并保持窗口很短)、GPT-OSS 等模型中已经成为定型的设计。要点是“用局部性削减成本,同时用几个全局层抓住长距离依赖”。

为什么这件事现在变得重要?因为随着上下文被推到数十万乃至 100 万 token,全注意力的 KV 缓存已经成为服务成本中占主导地位的一项,也是瓶颈。如果说量子化是这个问题在“数值”轴上的答案,那么混合 SWA 就是“架构”轴上的答案。

MiMo v2.5 实际做了什么 — 架构

根据文章,MiMo-V2.5-Pro 是 70 层中仅 10 层为全注意力,其余 60 层为 SWA(只有约 1/7 是全局的)。滑动窗口大小为 128 token——比 Gemma 3 偏短窗口的基调还要激进。

全70层
├─ SWA 60层    (每个 token 仅看最近 128 token → KV 以窗口大小为上限)
└─ Full 10层   (全局视野·长距离回忆          → KV 随序列长度增长)
理论上限: 计算量 ≈ 1/7,  KV 缓存 ≈ 1/7  (约 7.0 倍)

在这一配置下,文章称总计算量是全注意力的“约 1/7”,KV 缓存内存也“接近 1/7”,各自削减 约 7.0 倍。不过要先把话说死:这个 7 倍是架构给出的上限(理论值),而不是实测的端到端速度提升。

关于这笔账,有一个诚实的注脚。10 个全注意力层仍然持有 O(N) 的缓存,所以整体 KV 大致是 (60·W + 10·N) / (70·N)。序列短的时候连 1/7 附近都够不上,只有当 N 变大、局部项被冲刷掉之后,比例才会逼近 10/70。这正是文章说“接近 1/7”并强调收益随序列长度一起增大的原因——7 倍不是常数,而是渐近线。

其余配置是当下服务模型的标准组合——稀疏 MoE(每层平均专家负载约 0.85)、加速解码的 3 层 MTP(Multi-Token Prediction)。MTP 下面还会再出现,这里只说一句:它是让模型在一步内预测并验证多个未来 token、当接受率高时用一次前向传播前进不止一个 token 的技术(内置于模型的投机解码类技巧)。总参数量并未公开。

把潜力落到生产 — KV 缓存重构与调度

这是全文最有价值的部分。有意思的不是架构本身(如今已经很常见),而是为了真正把这 7 倍“潜力”收回来所付出的工程。

  • 双池 KV 缓存 — 传统的单池会为所有层分配 O(N) 内存,无法发挥 SWA 的窗口稀疏性。于是把全注意力用的池和 SWA 用的池分开,SWA 池只按窗口大小分配,把存储强制为 O(W)。
  • SWA 感知的前缀缓存 — 前缀缓存以“相同 token 序列则相同 KV”为前提来复用,但在 SWA 中,即使是相同序列,KV 也可能只剩下尾部的一部分,甚至已被完全逐出。于是用一个会追究“尾部 W 个 token 在 SWA 池中是否拥有有效槽位”的 窗口安全长度(window-safe length) 来截断匹配长度。草率处理就会读到无效槽位,从而悄无声息地出错。
  • 分块预填充 — 把长预填充切成 16K token 的固定分块。文章诚实地承认前缀越长吞吐量下降得越厉害——从前缀几乎为零时的 1 倍,跌到 1M token 前缀时的约 0.12 倍。
  • PD 分离 + EP 缩减 — 把预填充与解码分离部署,又因为 SWA 让 KV 缓存变小,把专家并行(EP)的规模缩减了一半。文章报告仅凭这一点,端到端性能就 改善约 40%(自测数据)。
  • 预填充阶段的 MTP 支持 — 在预填充阶段不开启 MTP 时,最初 128 个解码 token 的预测接受率跌到谷底;修正之后,据称获得了 最初 0–128 token 2.3 倍、128–256 token 1.5 倍 的加速(自测数据)。
  • 长度分桶 + NUMA 调优 — 按长度把请求分入不同的桶(0–64K / 64K–256K / 256K–1M),并调整 NUMA 布局,从而让批次保持均质、把内存访问留在本地。

在生产指标上,文章披露服务器端 KV 缓存命中率平均 93%,重度用户在 95% 以上。这些都是厂商自报数据,并非可复现的公开基准。至于在 KV 缓存效率排名中自家模型仅次于 DeepSeek-V4 系列位列第 2 的说法,同样是自家排的榜。

结语 — 诚实地阅读

先说真正的优点。这篇文章的价值不在于“我们做得很快”的自夸,而在于 它揭示了把 SWA 放到生产环境时那些悄然崩坏的地方。尤其是前缀缓存在 SWA 中被失效的问题(窗口安全长度),是大多数宣传文章都会跳过、却对实务者真正有用的陷阱。架构收益(7 倍)离开系统工程就无法收回——这样的叙述也很诚实。

如果你要构建长上下文服务,该带走的教训不是模型,而是一份清单——分离 KV 池,把前缀缓存的匹配做成窗口感知的,把长预填充切成分块,并在预填充刚结束时重新测量初期 token 的 MTP 接受率。没有一条是 MiMo 专属的,它们全都是朴素的 SWA 部署会悄然丢失收益的地方。

缺失的东西也很明显。第一,质量的讨论整块缺席。 SWA 按定义会丢失窗口外的信息,混合方案正因此才存在——可是关于 10 个全局层能弥补多少损失、128 的窗口在 needle-in-a-haystack 或长距离回忆中能否撑住,一个数字都没有。128 是相当激进的窗口,所以更让人好奇。第二,头条数字大多是厂商自家的生产指标(93%、40%、2.3 倍),而不是可独立复现的基准。就连 7 倍也不是实测,而是上限。

公平地说,这是一份生产系统报告。所以像缓存命中率或端到端改善这类自家生产指标,本来也是与它的主张相匹配的那种数字——不是学术基准并不算缺点。真正的空白不在于系统数字,而在于对质量的沉默。

所以结论和上一篇量子化文章一样。量子化减少 KV 条目的 比特数,SWA 减少 KV 条目的 个数——两个正交的轴,因此也可以叠加使用(把用窗口收窄后的缓存再用 FP8 存储)。而且这两个轴上,纸面上的削减在你于自己任务的评测集上重新测量之前,都只是潜力而已。MiMo 文章的整个后半部分,恰恰就是“这 7 倍实际能拿回多少”的记录——这正是本文给出的最诚实的教训。

参考资料

현재 단락 (1/31)

[上一篇量子化文章](/blog/2026-07-08-llm-quantization-2026)的最后结论是“下一个瓶颈是 KV 缓存”。长上下文中缓存会变得比权重更大,因此我写道:把缓存用更少比...

작성 글자: 0원문 글자: 3,693작성 단락: 0/31