Prhub

#36142 [AMD][CI] Add MiniMax-M3-MXFP8 MI35x nightly perf benchmark

原始 PR 作者 michaelzhang-ai 合并时间 2026-08-26 05:05 文件变更 2 提交数 10 评论 0 代码增减 +164 / -47

执行摘要

为 M3 新增 MI35x 夜间性能基准,替换 M2.5 槽位

PR body 指出 MiniMax-M3-MXFP8 在 ROCm 7.2 nightly 的 MI35x 上已有精度覆盖(#30613、#33402),但缺少性能覆盖;M2.5 作为第二个 4-GPU MI35x MiniMax job 占用槽位,而 gfx950 原生支持 M3 的 MXFP8 MoE 权重,因此 M3 更值得该槽位。该 PR 将 M2.5 的槽位让给 M3,将释放的时间用于性能基准,且针对推理模型大部分 token 位于 的特点,选择 decode 加权的 1K/1K 形状。

值得关注的是其 CI 门控与资源配置设计:精度与性能共用 job、复用已验证 recipe、perf 步骤容错运行,这种模式适合在资源受限的 nightly 矩阵中扩展覆盖。对于关注 AMD 或 MiniMax-M 系列的工程师可精读测试文件与 workflow 变更;对一般开发者,可作为 CI 基准组织方式的参考。

讨论亮点

该 PR 没有留下 review 评论,HaiShaw 直接批准。有价值的讨论体现在提交历史的演进决策中:一是作者最初在分支中加入了 MI30x nightly job 和 gfx942 MXFP8 MoE runner 修复,随后以 Revert the MI300X leg and the gfx942 MoE fix; keep the PR to MI35x 回退,明确将 PR 聚焦到 MI35x 槽位替换;二是最后一个提交针对 warmup 注释做了修正,澄清 bench_one_batch_server 本身会预热每个 batch,重复的 leading 1 实际提供的是被报告 helper 丢弃的全长度 decode,而非通常理解的 warmup。

实现拆解

  1. 新增性能基准套件test/registered/amd/perf/mi35x/test_minimax_m3_perf_mi35x.py):定义 TestNightlyMiniMaxM3PerformanceMI35x,通过 register_amd_ci 注册到 nightly-perf-4-gpu-mi35x-minimax-m3 套件。setUpClass 中构造 model_config,完整复用精度测试的 TP=4 recipe:--quantization mxfp8、aiter 注意力、fp8_e4m3 KV、关闭 radix cache、block-fp8 线性路径(#32036)与 quick INT4 all-reduce(#32230),另加多线程权重加载和 --cuda-graph-max-bs-decode 64,避免把捕获开销花在扫描外的 batch 上。batch 扫描为 [1, 1, 8, 16, 64],其中重复的 leading 1 提供一次全长度 decode 作为“丢弃行”,用于规避首次长输出的冷启动。

  2. 改造 ROCm 7.2 nightly 工作流.github/workflows/nightly-test-amd-rocm720.yml):将原 nightly-4-gpu-mi35x-minimax-m25-rocm720 job 替换为 nightly-4-gpu-mi35x-minimax-m3-rocm720,并新增 Performance Test MI35x ROCm 7.2 (4-GPU MiniMax-M3 MXFP8) 步骤,紧随精度步骤之后,且 continue-on-error: true。精度失败即 job 失败,因此不会在错误构建上测吞吐;同时删除了 M2.5 的 job_select 下拉项和 check-all-jobsneeds 引用。

  3. 资源与门控设计:精度与性能共享同一个 job、同一个已缓存 checkpoint 和同一个 MI35x runner 槽位,步骤顺序天然形成门控;性能步骤容错运行,吞吐偶发波动不会拖垮精度已通过的 job,这是 GLM-5.2-FP8、GLM-5-MXFP4、Kimi-K3、M2.7 等 job 已有的排列方式。

  4. 配套验证与演进约束:在 rocm720 与 rocm724 两个镜像的 MI35x 硬件上实际运行,四个步骤全部通过,两镜像各指标差异在 2% 内;M2.5 的 4-GPU MI35x 精度 job 保留在 ROCm 7.0 nightly(nightly-test-amd.yml),因此其测试文件继续使用,无运行中覆盖丢失。提交历史显示作者曾推入 MI30x 腿和 gfx942 MoE runner 修复,后主动 revert,将 PR 范围收敛到 MI35x。

文件 模块 状态 重要度
test/registered/amd/perf/mi35x/test_minimax_m3_perf_mi35x.py 性能基准 added 7.07
.github/workflows/nightly-test-amd-rocm720.yml 工作流 modified 4.56

关键符号

TestNightlyMiniMaxM3PerformanceMI35x setUpClass test_bench_minimax_m3

关键源码片段

test/registered/amd/perf/mi35x/test_minimax_m3_perf_mi35x.py test-coverage

PR 的核心产物:新增 MI35x nightly 性能基准套件,复用精度测试的 TP=4 recipe,避免吞吐回归被配置差异混淆。

"""MI35x nightly performance benchmark for MiniMax-M3-MXFP8 (4-GPU, TP=4)."""import os
import unittestfrom sglang.test.ci.ci_register import register_amd_ci
from sglang.test.nightly_bench_utils import generate_simple_markdown_report
from sglang.test.nightly_utils import NightlyBenchmarkRunner
from sglang.test.test_utils import DEFAULT_URL_FOR_TEST, _parse_int_list_env# 注册为 nightly-perf-4-gpu-mi35x-minimax-m3 套件,预计耗时 5400 秒
register_amd_ci(
    est_time=5400,
    suite="nightly-perf-4-gpu-mi35x-minimax-m3",
    nightly=True,
)MINIMAX_M3_MODEL_PATH = os.environ.get(
    "MINIMAX_M3_MODEL_PATH", "MiniMaxAI/MiniMax-M3-MXFP8"
)
RESULT_DIR = "performance_results_minimax_m3_mi35x"
MAX_BATCH_SIZE = 64
​
​
class TestNightlyMiniMaxM3PerformanceMI35x(unittest.TestCase):
    """MiniMax-M3-MXFP8 TP=4 在 AMD MI35x 上的吞吐测试。"""
​
    @classmethod
    def setUpClass(cls):
        cls.base_url = DEFAULT_URL_FOR_TEST
        # 重复的 leading 1 提供一条全长度 decode 作为“丢弃行”,
        # 报告 helper 会将其滤除,避免首次长输出污染计时。
        cls.batch_sizes = [1, 1, 8, 16, MAX_BATCH_SIZE]
        cls.input_lens = tuple(_parse_int_list_env("NIGHTLY_INPUT_LENS", "1024"))
        cls.output_lens = tuple(_parse_int_list_env("NIGHTLY_OUTPUT_LENS", "1024"))
​
        cls.model_config = {
            "name": "TP4+MXFP8+aiterAttn+fp8KV+blockFP8+quickAR",
            "model_path": MINIMAX_M3_MODEL_PATH,
            # 与精度测试 test_minimax_m3_tp4_eval_mi35x.py 的 recipe 保持一致,
            # 额外开启多线程加载,并将 decode graph 上限设为扫描的最大 batch。
            "other_args": [
                "--quantization", "mxfp8",
                "--dtype", "bfloat16",
                "--trust-remote-code",
                "--tp", "4",
                "--attention-backend", "aiter",
                "--kv-cache-dtype", "fp8_e4m3",
                "--disable-radix-cache",
                "--chunked-prefill-size", "8192",
                "--mem-fraction-static", "0.80",
                "--cuda-graph-max-bs-decode", str(MAX_BATCH_SIZE),
                "--max-running-requests", str(MAX_BATCH_SIZE),
                "--model-loader-extra-config",
                '{"enable_multithread_load": true}',
                "--watchdog-timeout", "1200",
            ],
            # block-fp8 线性路径与 quick INT4 all-reduce 在 gfx950 上均为可选,
            # 这些环境变量保证 perf 与精度测试走同一执行路径。
            "env_vars": {
                "SGLANG_USE_AITER": "1",
                "SGLANG_OPT_USE_BF16_ROUTER_GEMM": "0",
                "SGLANG_FORCE_MXFP8_BLOCK_CONVERT": "1",
                "SGLANG_M3_ALLOW_CUSTOM_AR": "1",
                "ROCM_QUICK_REDUCE_QUANTIZATION": "INT4",
                "ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16": "1",
            },
        }
​
        cls.runner = NightlyBenchmarkRunner(RESULT_DIR, cls.__name__, cls.base_url)
        cls.runner.setup_result_directory()
        cls.runner.full_report = f"## {cls.__name__}\n"
​
    def test_bench_minimax_m3(self):
        """运行 MiniMax-M3-MXFP8 的 batch 扫描。"""
        old_env = {}
        # ...(循环扫描 batch_sizes,调用 bench_one_batch_server 并汇总报告)

评论区精华

PR 范围收敛:回退 MI30x 腿与 gfx942 修复 设计

提交历史显示作者最初在分支中加入了 MI30x nightly job 和 gfx942 MXFP8 MoE runner 修复,随后以独立提交整体回退,保留 PR 仅处理 MI35x。

结论:PR 聚焦到 MI35x 槽位替换与性能基准,MI30x 相关改动另行处理。 · 已解决

warmup 注释语义修正 documentation

最后一次提交修正了测试中的 warmup 注释:`bench_one_batch_server` 已预热每个 batch,重复的 leading 1 实际提供的是被报告 helper 丢弃的全长度 decode。

结论:注释已更正,避免后续维护者误解。 · 已解决

风险与影响

主要风险集中在 CI 资源重分配和基准可复现性:一是 ROCm 7.2 下 M2.5 的 4-GPU MI35x job 被移除,虽然 M2.5 精度仍在 ROCm 7.0 覆盖,但 M2.5 在 rocm720/rocm724 上的夜间回归能力被有意让出;二是 perf 测试依赖 #32036(block-fp8 线性路径)和 #32230(quick INT4 all-reduce)这类可选路径及一组环境变量(如 SGLANG_FORCE_MXFP8_BLOCK_CONVERTROCM_QUICK_REDUCE_QUANTIZATION),这些路径后续若被改动或默认值变化,可能使基准结果漂移或报错;三是测试使用 bench_one_batch_server 且 TP=4,与 cookbook 发布的 tp8 bench_serving 行不具备直接可比性,文档注释已说明应视为形状参考;四是 continue-on-error: true 意味着 perf 步骤失败不会暴露 job 失败,需要人工关注日志。

影响限于 AMD nightly CI:M3 的 MI35x 性能从此有持续回归监控,M2.5 在 ROCm 7.2 的 4-GPU 槽位让给 M3,净 runner 成本基本不变;对用户无直接可见影响,但有助于在发布前捕获 M3 在 gfx950 上的吞吐回归。团队侧需要留意 perf 步骤的失败日志由于 continue-on-error 不会红 job,且 M2.5 的 ROCm 7.2 覆盖缺失需依赖 7.0。

CI 资源重分配 M2.5 的 ROCm 7.2 覆盖移除 基准依赖可选路径 continue-on-error 可能掩盖 perf 失败 数值与 cookbook 形状不可直接对比

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论