Following the Bottleneck: Optimizing MiniMax M3 on AMD Instinct MI355X

发表时间: 2026-09 · Blog post by AMD and Embedded LLM Teams (blog.vllm.ai)

原文: https://blog.vllm.ai/blog/2026-09-10-minimax-m3-mi355x

作者/机构:AMD and Embedded LLM Teams

速读

一句话结论
通过在 vLLM 中针对 AMD Instinct MI355X 硬件进行张量并行形状适配、算子融合、稀疏元数据复用以及预填充与解码分离调优,将 MiniMax M3 模型的推理吞吐量提升了 3 到 4 倍。

要解决什么问题
大模型推理的性能卡点并非静态,而是随着优化的深入在计算、访存和调度之间不断转移。在原有的基础实现中,系统面临四个具体的底层机制卡点。首先是局部矩阵形状失配:模型结构图上的全局维度在经过张量并行(TP)切分和注意力头复制后,实际分配到单张显卡上的局部维度(如局部列数变为 1536)会大幅缩小,导致原有的通用矩阵乘法(GEMM)分块策略在解码阶段(极小的行维度)无法提取足够的并行度。其次是内核启动开销与显存带宽浪费:在稀疏混合专家(MoE)架构中,每个词都需要同时经过路由专家和共享专家,原有做法将其作为独立的感知机分别计算,产生了大量中间激活张量的读写和内核启动延迟。第三是稀疏注意力的控制面开销:稀疏注意力虽然减少了计算量,但引入了计算得分、选择 Top-k 块以及映射物理页的元数据处理流程,且不同底层算子库对显存页大小的要求不同,导致频繁的元数据重算和键值(KV)缓存的物理拷贝。最后是系统级队列拥塞:在分离预填充与解码(P/D)进程时,由于层间 KV 内存布局不一致以及收发节点比例不匹配,导致传输完成后解码端无法正确解析,或者预填充算力不足引发请求队列无限积压。

怎么做的
核心思路是追踪瓶颈,通过批处理重复工作、预计算不变量以及消除不必要的数据搬运来逐层击破卡点。方法由四个关键设计构成。第一,动态形状感知调度。系统不再盲目使用预填充或解码的静态标签,而是根据实际运行的局部形状选择 GEMM 分块策略。对于解码阶段的小行数形状,采用更窄的列分块以暴露更多独立工作,并增大步长以减少循环次数。第二,共享专家与路由专家融合。系统将共享专家作为一个特殊的槽位追加到路由专家表中,使得所有被激活的专家可以通过同一个分组矩阵乘法联合执行。其计算逻辑可抽象为:

$$ Y = \sum_{i \in \text{routed}} E_i(X) + E_{\text{shared}}(X) $$

这一设计在不改变模型数学等价性的前提下,彻底消除了独立路径及其带来的中间显存流量。第三,元数据复用与零拷贝视图。针对稀疏注意力,系统观察到相邻层往往选择几乎相同的上下文块,因此允许后续层直接复用前一层的 Top-k 索引,并在融合投影算子中直接裁剪掉未使用的分支。当面临 MiniMax M3 的 128 词逻辑块与 AITER 算子库 16 词物理页的布局冲突时,系统不拷贝任何 KV 数据,而是将每个选中的逻辑块 ID 展开为 8 个页条目,构建一个紧凑的页表:

$$ \text{PageTable}[i \times 8 + j] = \text{PhysicalBlock}[i] \times 8 + j $$
AITER 通过该页表直接读取原有的 KV 显存分配。第四,异构 P/D 拓扑与流水线对齐。在预填充与解码分离架构中,系统首先推导出每一层精确的传输几何结构和字节偏移量,确保异构张量并行(如 TP4 预填充喂给 TP8 解码)下的确认机制正确运作。随后通过搜索收发比例,配置多个预填充工作节点对接单个解码节点,从而在保证解码生成速度的同时消化掉堆积的请求队列。

效果如何
实验在 AMD Instinct MI355X 硬件上进行,测试模型为 60 层解码器、包含稀疏 MoE 和稀疏注意力的 MiniMax M3,权重采用 MXFP8 和 MXFP4 格式。对比基线为该模型在 vLLM 上的 Day-0 初始实现(代表未经过形状适配、未融合专家且同步执行的朴素路线)。在 8K 输入、1K 输出的标准固定负载下,对于 MXFP8 权重(TP4/EP1 拓扑,并发度 32),优化后的系统实现了 342.4 tokens/s/GPU 的输出吞吐量,是基线的 3.14 倍,首字延迟中位数从 1.46 秒降至 0.67 秒。在并发度 128 时,结合 EAGLE3 投机解码技术,吞吐量达到 682.4 tokens/s/GPU。在 P/D 分离架构下(并发度 512,2 个 TP4 预填充节点对应 1 个 TP4 解码节点),系统总吞吐量达到 6370.5 tokens/s/GPU。作者也坦诚了当前方法的局限性:在 AgentX 智能体编程任务(长多轮对话、不规则输出)中,理论前缀缓存命中率与实际 GPU 缓存命中率存在 4.6% 的差距,且 GPU KV 缓存占用率高达 88.5%,这表明在真实复杂场景下,单纯的算子速度已不再是唯一瓶颈,系统的下一个卡点已经转移到了 KV 准入驱逐策略和调度机制上;此外,在极高并发测试中,系统曾因耗尽操作系统的文件描述符限制而导致 TCP 传输失败,证明了系统级限制同样会成为不可忽视的代价。

主要贡献

本文是针对在 AMD Instinct MI355X 上实现 MiniMax M3 初始(day-0)vLLM 部署后的后续优化工作报告。其核心问题在于,当模型成功运行后,随着优化的推进,系统瓶颈会不断转移,团队需要一种系统性的方法来决定下一步的优化方向。

本文的研究目标是通过一系列针对性的系统分析与优化手段(涵盖张量并行切分、计算内核融合、内存与元数据管理、投机解码以及多节点架构分离等),全面榨取 MI355X 硬件在运行 MiniMax M3 时的极限性能。其创新点在于提出了一种基于“五个关键问题”的动态瓶颈追踪方法论,不盲目追求单一内核的极限,而是通过系统级的剖析,在形状分布、重复计算、数据移动、执行契约以及队列调度等多个维度实现了深度的软硬件协同优化。

MiniMax M3 在 AMD Instinct MI355X 上的固定工作负载服务进展
MiniMax M3 在 AMD Instinct MI355X 上的固定工作负载服务进展

背景知识与设计原则

优化工作流的系统性建立。本文的优化工作遵循了一个熟悉的系统性流程:首先估计占据主导地位的成本,对其进行精确测量,接着对重复性的工作进行批处理,预计算系统中的不变量,最后当叶子节点(底层内核)的性能分析曲线趋于平缓时,将优化视角向上层系统栈移动。

MiniMax M3 的解码器层特性与成本放大效应。MiniMax M3 模型包含 60 个解码器层;其中 57 层使用了稀疏混合专家(MoE)和稀疏注意力机制。对于一个 1K token 的输出响应,一个微小的单层计算成本在一次请求的处理过程中可能会被重复成千上万次。这种极端的重复性要求对底层执行细节进行严格审查。

追踪瓶颈的五个核心问题。为了应对上述挑战,本文提出了五个在优化过程中极具指导意义的关键问题:1. 实际到达该硬件 rank 的局部矩阵形状是什么?2. 在每一层或每个 token 的处理中,哪些工作是重复发生的?3. 哪些字节在物理移动,是否可以用元数据的移动来替代数据拷贝?4. 预期的硬件快速路径是否真正被执行,且其数学计算是否完全正确?5. 当底层计算内核不再占据主导地位时,系统中哪个队列正在增长?

MiniMax M3 解码关键路径与 P/D 系统边界
MiniMax M3 解码关键路径与 P/D 系统边界

方法细节

1. 达到该 rank 的局部形状是什么?

局部维度的决定因素与 TP 切分影响。模型架构图通常展示的是全局维度,但底层计算内核实际上是在经过张量并行(TP)、注意力头复制、张量填充和 token 路由之后的局部 M、N 和 K 维度上运行的。在 TP8 配置下,MiniMax M3 的 64 个查询头(query heads)被分片到每个 rank 8 个,而其 4 个 KV 头和 4 个索引头(index heads)则被复制为每个 rank 1 个。因此,融合的 QKV 投影算子所看到的局部 N 维度实际上是 1536,而不是简单地将全局 N 除以 8。

Prefill 与 Decode 阶段的 M 维度差异化处理。Prefill(预填充)和 decode(解码)阶段到达内核时的 M 维度存在显著差异。Prefill 一次处理大量的 token;而 decode 通常只有几行数据。[vLLM #45725] 针对这一差异,将内核启动器(launcher)拆分为大 M 和小 M 两种执行机制,这一改动将 TP8 配置下 8K 输入/1K 输出的吞吐量提高了 7.8%–9.4%。

基于局部形状的细粒度分块策略。[vLLM #46117] 进一步从完整的局部形状中智能选择计算分块(tiles):更窄的 N 分块在 decode 阶段暴露了更多独立的工作以提升并行度,而更大的 K 步长则有效减少了循环迭代次数。相反,当 M 维度已经能够提供足够的并行性时,Prefill 阶段会使用更宽的分块。

TP 切分如何改变局部 GEMM 形状和分块计划
TP 切分如何改变局部 GEMM 形状和分块计划

分组 MoE 程序的重排序与缓存重用。同一个 PR 还对分组 MoE(grouped-MoE)程序进行了执行重排序,使得相邻的程序可以重用 GPU 缓存中的激活行和专家权重分块,从而避免了从 HBM(高带宽内存)中重复获取数据的开销。在其 TP4 端到端测试中,这些组合的更改产生了 1.08 倍–1.46 倍的性能增益。在低并发场景下,由于原始启动方式包含的并行工作最少,因此这种优化的收益最为显著。

局部形状对底层后端的硬性限制。局部形状同样决定了哪个计算后端是合法的。在最终的 MXFP8 优化配方中使用的 AITER 稀疏注意力路径,强制要求每个 TP rank 必须拥有一个 KV 头。TP4 配置恰好满足该条件。然而,TP2 配置则无法满足,必须使用 vLLM 的 Triton 回退(fallback)路径。因此,改变 TP 配置不仅改变了集合通信的数据大小,还可能彻底改变算子执行图(operator graph)。

后端的动态交叉点与自适应选择。此外,并不存在一种在所有场景下都普遍最快的后端。[InferenceX #2003] 最初为整个测试扫描选择了模拟的线性后端。但随后 [InferenceX #2187] 中的详细测量表明,原生的 MXFP8 线性后端在低并发和中等并发下速度更快,而模拟后端仅在长输入、高并发的运行场景下才能获胜。稀疏分页注意力(paged attention)也表现出类似的性能交叉点。最终的优化配方选择仅在并发达到 64 或更高且输入长度为 8K 时,才同时启用这两种后端。这是一个重要的可复用教训:必须针对实际运行的形状分布进行调优和分发,“Prefill”、“decode”或“TP4”等术语仅仅是一个标签,不能代表底层的真实负载。

2. 什么工作在重复?

启动开销的识别与图执行优化。第一个极易被忽视的重复成本是内核启动开销。在初始的 day-0 配方中,模型是采用急切模式(eagerly)运行的。[InferenceX #1754] 和 [#1755] 为标准服务和 EAGLE3 服务启用了图执行(graph execution)。这一根本性的变化被纳入了累积的优化历史中,尽管公布的最终结果并未将其增益单独孤立出来展示。

共享专家的结构性融合。更大的结构性胜利来自于对共享专家(shared expert)的处理。最初,每个稀疏 MoE 层都将共享专家作为一个完全独立的密集 MLP 来运行,这涉及:门控/向上投影、激活、向下投影、中间存储和加法操作。虽然这些数学计算是模型架构所必需的,但其独立的执行路径却是不必要的。

路由专家与共享专家的联合 GEMM 处理。[vLLM #46545] 通过将共享专家附加到路由专家表中,并强制为每个 token 选择该共享专家,解决了这一问题。随后,分组 GEMM 算子将路由专家和共享专家放在一起进行联合处理。这种设计在不减少模型 FLOPs 的前提下,彻底消除了独立的内核启动和中间数据流量。该优化使输出吞吐量在并发为 1 时大幅提高了 30.2%,在并发为 128 时提高了 5.6%。这种随并发增加而缩小的增益提供了一个有用的证据:这正是典型的启动开销摊销(launch amortization)所表现出的特征。

融合前后的 MiniMax M3 共享专家执行情况
融合前后的 MiniMax M3 共享专家执行情况

AITER 路径的融合与权重重排前置。AITER 路径在 [vLLM #46474] 中应用了完全相同的融合思想。此外,由 [AITER #3811] 提供底层支持的 [vLLM #46184],将 MXFP8 权重和尺度(scale)的重排工作提前移动到了模型加载阶段。AITER 预先携带了涵盖从 1 到 32,768 个 token 以及由 TP4 和 TP8 产生的局部中间宽度的调优 MoE 配置。因此,布局转换操作只需在加载时发生一次;服务循环阶段直接消耗已准备好的数据形式。

投机解码中的请求级批处理优化。投机解码(Speculative decoding)提供了一个关于如何批处理重复工作的清晰示例。最初的 MSA 索引器会为每一个投机 token 单独启动一个工作组(workgroup)。[vLLM #45743] 改进了这一机制,改为每个请求仅启动一个工作组,并将所有的草稿(draft)位置放在一起联合处理,从而实现了键(key)加载的重用。同时,它还移除了一个正分数缩放(positive score scale)操作,因为在注意力机制中只有 top-k 的相对顺序是重要的,将每个分数乘以相同的正数常数根本不会改变该最终顺序。

阿姆达尔定律的显现。经过上述优化,索引内核的性能提高了多达 48.9%,但在 PR 测试中,端到端服务仅提高了约 3.3%。这个巨大的差距正是阿姆达尔定律(Amdahl's law)发挥作用的体现:一个巨大的底层内核性能胜利是绝对真实的,但如果它不占据应用程序的整个关键路径,其对全局的提升就是有限的。

3. 哪些字节在移动?

稀疏注意力的控制平面开销。稀疏注意力虽然大幅减少了注意力矩阵的数学计算量,但它额外引入了一个复杂的控制平面:需要对块进行评分、选择 top-k、将逻辑块映射到物理页,最后将这些元数据传递给底层的注意力内核。

跨层的 Top-k 决策重用。[vLLM #47269] 观察到一个关键现象:相邻的稀疏层通常会选择几乎完全相同的块。基于此,在启用索引共享后,允许某一层计算 top-k 决策,而后续的层直接重用该决策结果。这一改动使平均 TPOT 在并发为 1 时下降了约 10%,在高并发时下降了约 4%。

编译器可见的决策重用与死代码消除。仅仅跳过选择器执行只是完成了一半的工作。原本的融合投影算子仍然会产生索引 Q/K 值,对其进行归一化,应用 RoPE,并写入索引缓存。[vLLM #47287] 通过将重用决策的状态对该融合内核设为可见,使得编译器能够在编译阶段将未使用的生产者分支直接移除(compiled away)。

零拷贝的页面视图适配。同一个 PR 还跨越了底层布局的不匹配,成功集成了 AITER 稀疏分页注意力。MiniMax M3 在逻辑上选择的是 128-token 的块;而 AITER 后端消耗的是 16-token 的页。vLLM 并没有选择进行昂贵的 KV 数据拷贝,而是将每个选定的块 ID 动态转换为八个页 ID,并以此构建一个紧凑的页表。在这个过程中,庞大的 KV 缓存数据保留在原处不动。这相当于在服务引擎中传递了一个轻量级的视图,而不是复制整个数据容器。

vLLM 如何在不复制 KV 数据的情况下使 MiniMax M3 稀疏块适应 AITER 页面
vLLM 如何在不复制 KV 数据的情况下使 MiniMax M3 稀疏块适应 AITER 页面

视图适配的性能收益与基准测试边界。在 TP4、并发 256 的配置下,该 PR 在其孤立的 A/B 测试中,使 MXFP4 的输出吞吐量提高了 6.93%,MXFP8 提高了 5.56%。这里必须声明一个重要的基准测试边界:InferenceX 固定的 8K/1K 审查策略严格排除了跨层索引重用,因为这会改变架构的实际工作量。因此,固定形状的配方仅使用了页面适配器,但并没有使用 top-k 重用。而 AgentX 则在其特定的工作负载规则下启用了重用。本文不会将固定契约曲线的性能归功于它实际并未运行的优化工作。

量化场景下的三平面分离原则。量化技术的引入使得“哪些字节在移动?”这个问题变得更加复杂和重要。将其分离为三个独立的平面极具指导意义:

  • 计算张量平面(Weights and activations):例如 MXFP8 或 MXFP4 的 GEMM/MoE 计算。需要证明和验证的内容包括数据打包格式、缩放比例(scales)、激活数学逻辑以及后端布局。
  • 持久状态平面(Persistent state):例如 FP8 的 KV 缓存和稀疏索引缓存。需要证明平台数据类型支持、页面布局以及读/写的几何形状。
  • 通信平面(Communication):例如量化的 all-reduce 或跨节点的 KV 传输。需要证明触发资格、选定的编解码器、数据所有权以及传输完成状态。
    这些平面具有完全独立的调度逻辑和正确性契约。“模型是 MXFP4 格式”这一单一陈述,并不能自动推断出 KV 的数据类型或集合通信的具体路径。

4. 预期的快速路径是否运行,且数学计算是否正确?

QuickReduce 资格阈值的审计与纠错。这种严格的审计改变了本文最初的一个主张。团队最初认为一个大约 1.5 MB 的 decode 集合通信使用了高效的 INT4 QuickReduce 路径。但现有的确凿证据并不能证明这一点。[InferenceX #2104] 确实配置了 INT4 和一个 256 KB 的编解码器(codec)阈值,但遗漏了 QuickReduce 独立的资格(eligibility)阈值。对于 TP4 下的 BF16 数据,代码中固定的内置表严格要求数据量达到 16 MB 时 INT4 才能生效。因此,这 1.5 MB 的集合通信根本没有达到编解码器的选择阶段;系统只有在 QuickReduce 符合整体资格后,才会去查询那个 256 KB 的阈值。

QuickReduce 配置、资格、编解码器选择和执行门控
QuickReduce 配置、资格、编解码器选择和执行门控

配置不等于执行的铁律。可用的日志仅仅证明了系统配置了 INT4,而不能证明 QuickReduce 内核实际运行了。因此,本文将 #2104 视为一个累积的镜像和配方检查点,并不将其性能曲线归因于 INT4 all-reduce。这个区别可以推广为一条铁律:配置 != 符合资格 != 执行。在将任何性能增益归因于某个特定后端之前,必须使用调度跟踪或分析器进行确证。

正确性契约的修复实例。正确性的保证需要同样的纪律。以下三个示例捕获了不同层面破坏契约的严重情况:

  • [vLLM #45794] 修正了内存映射,将打包的 MXFP4 Q/K/V 和门控/向上检查点张量精确映射到了正确的融合参数切片中,并成功将 MiniMax M3 的 SwiGLU-OAI 参数传递给 MoE。
  • [vLLM #45720] 修复了在 FNUZ ROCm 设备上的 FP8 KV 视图问题。在 MI300X 上,未打补丁的错误路径在 GSM8K 测试上的严格匹配得分仅为 0.0099(几乎完全错误);而打补丁后的路径得分恢复到了 0.9575。这是一个纯粹的正确性修复,而不是声称的 MI355X 性能加速。
  • [vLLM #47158] 修复了传递给 AITER 的专家并行掩码(mask)。存在 Bug 的路径计算出的余弦相似度仅为 0.527;修正后的路径达到了 1.0 的完美相似度,并完全恢复了 GSM8K 的准确性。
    最后两个示例并不能解释 TP4/EP1 优异的性能曲线;但它们暴露了其他配置必须严格满足的契约底线。对于性能优化工作而言,“通过”必须同时意味着三件事:输出结果绝对正确、预期的底层路径确实被执行,以及在保持相同契约的前提下端到端指标得到了实质性改善。

5. EAGLE3 引入的第二个解码循环

EAGLE3 的复杂性与缓存键修复。EAGLE3 引入了草稿模型、多 token 验证机制、接受行为逻辑以及第二组独立的注意力元数据。它绝对不能仅仅被视为标准服务曲线上的一面简单标志旗。[vLLM #45546] 首先将 AMD 模型成功连接到了 EAGLE3 的接口。随后,[vLLM #45564] 修复了一个非常微妙的缓存键(cache-key)Bug:由于目标模型和草稿模型使用了不同数量的查询头,因此它们绝对不能仅仅因为后端和 KV 类型匹配就错误地共享同一个注意力组构建器。这引出了一条通用的缓存规则:缓存键必须包含所有能够改变被缓存对象的内部不变量。

草稿模型的后端配置固定。在完成了上述请求级索引批处理之后,[InferenceX #2107] 发现目标模型的注意力后端设置并没有正确地配置给草稿模型。通过在投机配置中硬性固定 TRITON_ATTN,成功避免了草稿模型掉入较慢的回退路径。

AITER 在多 token 验证中的扩展。最后,[vLLM #47984] 将 AITER 稀疏分页注意力从单 token 解码无缝扩展到了多 token 验证阶段。它将每一行展平的查询精确映射回其所属的请求和局部投机位置,重用了现有的页表构建器,并完整保留了单 token 的快速路径。在 TP4 测试中,这一扩展使 MXFP4 的输出吞吐量提高了 8.32%,MXFP8 提高了 7.90%,且没有实质性地改变 token 的接受率。这些工作共同促成了在并发 128 下单独达到 682.4 output tok/s/GPU 的 EAGLE3 结果。

6. 哪个队列在增长?

P/D 分离架构与 KV 边界正确性验证。Prefill/decode(P/D)分离架构将系统的瓶颈从单节点内部提升到了跨进程层面。在开始调整工作节点(worker)的数量之前,必须确保跨进程的 KV 边界是绝对正确的。最初的 MoRIIO 路径错误地假设第一层的 KV 布局可以代表每一层。然而,MiniMax M3 具有分离的 K/V 张量、交错的 K/V 张量以及纯键(key-only)索引缓存。在错误假设下,虽然数据传输显示完成且吞吐量看起来很健康,但 GSM8K 的准确率暴跌至约 0.0008——实际上输出的完全是乱码(token salad)。

跨进程 KV 传输的三步修复法。该修复工作分三步严谨进行:

  • [vLLM #46039] 逐层精确推导了传输几何形状和字节偏移量。
  • [vLLM #46290] 准确计算了实际为每个请求调度的写入次数,在 forward 阶段之后将该计数密封,并且严格保证只有在所有这些写入操作彻底完成后才释放底层缓冲区。
  • [vLLM #46332] 创新性地添加了异构 TP rank 映射和确认扇入(fan-in)机制。在 prefill 为 TP4 而 decode 为 TP8 的复杂场景下,两个 decode rank 可能会同时消耗一个生产者 rank 的数据,因此必须确保两者都发送了确认信号后,生产者的数据块才能被重用。
    只有在跨界正确性得到绝对保障之后,工作节点的分配调优才具有实际意义。
两个独立调优的 MiniMax M3 P/D 系统配置文件
两个独立调优的 MiniMax M3 P/D 系统配置文件

系统配置演进与延迟目标的权衡。第一个公开的系统配置使用了一个 TP8 prefill 工作节点和一个 TP8 decode 工作节点。在并发 1024 时,它达到了惊人的 2,084.6 total tok/s/GPU,但其首字延迟(中位数 TTFT)高达 223.20 秒([InferenceX #1762])。这种极端的吞吐量数字并没有使该系统具备可用性;提示词队列的极度膨胀才是真实的信号。[InferenceX #2144] 随后将每个工作节点移动到 TP4 配置,使它们与更快的单节点配方保持同步,并深入搜索了最佳的 prefill/decode 比例。对于 8K/1K 负载,两个 TP4 prefill 工作节点馈送一个 TP4 decode 工作节点成为了最优解。在并发 512 时,该结果达到了 6,370.5 total tok/s/GPU,且中位数 TTFT 降至极具竞争力的 1.32 秒。
在此过程中,平均 TPOT 从 31.26 毫秒上升到了 54.60 毫秒。但这并非矛盾。增加的 prefill 容量迅速清除了准入队列(降低了 TTFT),但选定的 decode 工作点导致产生每个活动序列的速度相对变慢。P/D 架构至少具有两个相互制约的延迟目标,必须同时公布两者以反映全貌。

操作系统限制的触达。在一次极限的高并发运行中,系统甚至耗尽了容器的文件描述符限制。通过提高操作系统级别的 nofile 限制才修复了 TCP 故障。这表明,一旦优化配置文件向上层栈移动,操作系统的限制可能和底层的 GEMM 分块一样成为真实的物理瓶颈。

实验环境

  • 硬件配置:AMD Instinct MI355X GPU。
  • 软件配置:vLLM(包含图执行、AITER 稀疏注意力后端、Triton fallback 机制)、ROCm 平台、InferenceX 基准测试框架。
  • 模型架构:MiniMax M3 模型。该模型具有 60 个解码器层,其中 57 层使用稀疏 MoE 和稀疏注意力,包含共享专家和路由专家,支持多模态输入、推理和工具输出。模型权重支持 MXFP8 和 MXFP4 格式。
  • 数据集与工作负载:SemiAnalysis InferenceX 基准测试(采用固定的 8K 输入 / 1K 输出标准测试),以及 AgentX(针对 Agentic 编码场景的长文本、多轮追踪、不规则输出工作负载)。

实验结果

  • MXFP8 标准服务(TP4/EP1 配置):

    • 在并发 32 下,输出吞吐量从最初的 109.1 飙升至 342.4 output tokens/s/GPU(达到初始结果的 3.14 倍)。中位数 TTFT 从 1.46 秒大幅降至 0.67 秒,平均 TPOT 从 69.1 毫秒降至 22.1 毫秒。
    • 在并发 128 下,吞吐量从 297.8 提升至 623.7 output tokens/s/GPU(达到初始结果的 2.09 倍)。中位数 TTFT 从 3.53 秒降至 1.54 秒,平均 TPOT 从 100.7 毫秒降至 48.8 毫秒。
  • MXFP4 服务配置:

    • 在并发 128(TP4/EP1)下,吞吐量从 212.1 提升至 716.8 output tokens/s/GPU。
    • 后续采用更高部署密度的 TP2/EP1 配置,结果进一步达到 943.5 output tokens/s/GPU,比 TP4 检查点高出 31.6%,是初始单 GPU 结果的 4.45 倍。
  • EAGLE3 投机解码:

    • 在并发 128(TP4/EP1)下,单独达到了 682.4 output tokens/s/GPU。
  • P/D 分离(Prefill/Decode disaggregation):

    • 在重调预填充/解码拓扑(2个TP4 prefill 节点馈送 1个TP4 decode 节点)后,在并发 512 下达到了 6,370.5 total tokens/s/GPU,且中位数 TTFT 保持在 1.32 秒。

补充细节

AgentX 展示了下一个瓶颈

Agentic 工作负载的复杂性。固定的 8K/1K 形状非常适合进行受控的对照比较。然而,Agentic 编码绝不是固定形状的流量:它具有极长的多轮历史跟踪、高度可重用的前缀、极不规则的输出,以及明显的 KV 容量拐点。

AgentX 基准点配置与测试方法。[InferenceX #2487] 确立了 MI355X 上运行 MiniMax M3 AgentX 的第一个基准点。该配置综合使用了 MXFP4、EAGLE3-GQA、前缀缓存、可选的 TP 分片 LMCache,以及跨层索引重用技术。在测试方法上,吞吐量回放使用了预先提交的综合接受长度,以确保进行比较的各系统执行了完全相同的投机工作;而评估阶段则使用真实的目标验证。

服务指标与缓存容量分析。在一次成功的运行中,并发 28 下的 TP4 配置提供了 127.4 output tok/s/GPU,509.5 total output tok/s,0.582 mean QPS,645 ms p50 TTFT,以及 41.3 ms p50 TPOT。
深度服务指标使这不仅仅是另一个跑分数据:

  • 理论前缀缓存命中率:96.7%
  • 实际实现的 GPU 缓存命中率:92.1%
  • GPU KV 缓存使用率:88.5%
  • GPU KV 容量:6,264,960 tokens
    在这一极限点上,仅仅优化另一个 GEMM 算子已经不再自动成为最佳的下一个工程项目。理论与实际之间 4.6 个百分点的缓存实现差距,以及接近 90% 容量极限的工作点,将团队的注意力直接引向了前缀对齐、准入和驱逐策略、调度逻辑以及内存卸载(offload)。这些基于单次运行的深刻观察,将作为下一轮 Agentic 优化的坚实基准。

结论

MiniMax M3 在 AMD Instinct MI355X 上之所以能实现如此巨大的性能飞跃,根本原因在于优化团队没有局限于单一层面,而是不断改变提出问题的层级——从底层的计算分块(tiles),到架构的重复执行路径,再到稀疏元数据的管理,进而扩展到分布式状态的一致性,最终触及系统级的工作负载队列。

针对未来新模型的服务路径优化,本文总结了一份极具价值的检查清单:

  1. 记录切分后的局部形状直方图。必须包含复制的注意力头和实际路由的 token 数量。
  2. 准确估计重复工作。将单层的计算工作乘以总层数、输出 token 数以及活跃请求数。
  3. 严格分离字节平面:独立分析计算张量、持久状态和通信的移动。
  4. 对于每一条声称的快速路径,记录其触发的资格条件并严格验证其是否真实执行。
  5. 在每一个性能关卡(performance gate)旁边,必须强制设置一个正确性关卡(correctness gate)。
  6. 在取得每一次性能胜利后,重新进行全局性能分析。如果叶子节点的内核耗时趋于平缓,则立即检查队列、数据所有权、缓存容量和操作系统限制。

附录

重现固定形状结果

公开的 InferenceX 运行详细记录了容器镜像、命令行参数和输出工件。最终的 MXFP8 TP4 检查点使用了以下确切的环境与配置:

vllm/vllm-openai-rocm:nightly-9e57de7197f234f9d9187715d96e07e007048c0f


export VLLM_ENGINE_READY_TIMEOUT_S=3600
export VLLM_USE_BREAKABLE_CUDAGRAPH=0
export VLLM_ROCM_USE_AITER=1
export VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1
 
vllm serve MiniMaxAI/MiniMax-M3-MXFP8 \
  --tensor-parallel-size 4 \
  --block-size 128 \
  --no-enable-prefix-caching \
  --language-model-only \
  --moe-backend aiter \
  --max-model-len 10240 \
  --max-num-batched-tokens 32768 \
  --kv-cache-dtype fp8 \
  --attention-backend TRITON_ATTN \
  --tool-call-parser minimax_m3 \
  --reasoning-parser minimax_m3 \
  --enable-auto-tool-choice

对于图 1 中确切的高并发调度结果,请使用 [InferenceX #2187] 中带有门控限制的配方。对于 MXFP4 TP2 的结果,请使用 [#2446];对于 P/D 分离架构,请使用 [#2144]。需要特别注意的是,仅仅复制上述标志并不能重现不同的镜像、拓扑结构或工作负载。

并发 128 下的基准测试执行命令如下:

vllm bench serve \
  --backend vllm \
  --model MiniMaxAI/MiniMax-M3-MXFP8 \
  --dataset-name random \
  --random-input-len 8192 \
  --random-output-len 1024 \
  --random-range-ratio 0.8 \
  --num-prompts 1280 \
  --max-concurrency 128 \
  --request-rate inf \
  --ignore-eos \
  --num-warmups 256 \
  --percentile-metrics ttft,tpot,itl,e2el \
  --save-result