Prhub

#45896 [feature] MiniMax-M3-MXFP4 support added

原始 PR 作者 qli88 合并时间 2026-06-18 02:50 文件变更 4 提交数 2 评论 6 代码增减 +44 / -3

执行摘要

支持 MiniMax-M3-MXFP4 模型,更新 ROCm MoE 后端

基于 PR #45794 的工作,本 PR 旨在扩展 unfused_triton MoE 后端以支持 MiniMax-M3-MXFP4 模型,使 ROCm 平台能够加载和运行该量化模型。PR body 提供了 tp4/tp8 下的 gsm8k 准确率测试结果,确认功能正确。

值得精读,设计决策(为特定模型直接修改平台后端选择)需谨慎。建议关注后续修复 PR(由 qli88 承诺),确保 fallback 行为有适当日志和激活量化检查。阅读重点:select_mxfp4_moe_backend 的分支调整和 SWIGLUOAI_UNINTERLEAVE 激活的实现。

讨论亮点

核心讨论集中在 mxfp4.py 中 ROCm 后端选择的变化。BowenBao 指出直接 fallback 到 TRITON_UNFUSED 可能静默改变输入量化规格,建议添加警告。fxmarty-amd 补充说明该变更会破坏一些使用激活量化的 MXFP4 测试,因为 TRITON_UNFUSED 后端不支持激活量化。作者 qli88 表示将在另一个 PR 中处理此问题。最终 PR 仍被合并,但该风险未在当前 PR 中解决。

实现拆解

变更涉及四个文件,具体步骤:

  1. 添加新激活函数支持:在 gpt_oss_triton_kernels_moe.py_supports_activation 中添加 SWIGLUOAI_UNINTERLEAVE,并在 activation 方法中实现该激活的分支,调用 torch.ops._C.silu_and_mul_with_clamp
  2. 调整 ROCm 后端选择:在 mxfp4.pyselect_mxfp4_moe_backend 中,将 ROCm 与 CUDA 平台分开处理,对 ROCm 直接返回 Mxfp4MoeBackend.TRITON_UNFUSED,不再抛出未实现异常。
  3. 补充模型定义:在 minimax_m3/amd/model.py 中为 MiniMaxM3SparseForCausalLMMiniMaxM3SparseForConditionalGeneration 添加 packed_modules_mapping,并修正 hf_to_vllm_mapper 中前缀替换的精确匹配(移除尾随点号)。
  4. 扩展量化配置:在 quark_moe.pyget_fused_moe_quant_config 中增加 gemm1_alphagemm1_betaswiglu_limit 的传递,使 SWIGLU 激活参数能正确传入 MoE 量化配置。
文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/experts/gpt_oss_triton_kernels_moe.py MoE 专家 modified 6.37
vllm/model_executor/layers/fused_moe/oracle/mxfp4.py 后端选择 modified 6.35
vllm/models/minimax_m3/amd/model.py 模型定义 modified 5.66
vllm/model_executor/layers/quantization/quark/quark_moe.py 量化配置 modified 5.4

关键符号

select_mxfp4_moe_backend get_fused_moe_quant_config activation _supports_activation

关键源码片段

vllm/model_executor/layers/fused_moe/experts/gpt_oss_triton_kernels_moe.py core-logic

核心变更:添加 SWIGLUOAI_UNINTERLEAVE 激活支持,使 unfused Triton MoE 专家内核能处理 MiniMax-M3-MXFP4 的激活函数。

# activation 方法(UnfusedOAITritonExperts 类)
def activation(self, activation: MoEActivation, output: torch.Tensor, input: torch.Tensor, **kwargs) -> None:
    quant_config = self.quant_config or FUSED_MOE_UNQUANTIZED_CONFIG
    if activation == MoEActivation.SWIGLUOAI:
        alpha = quant_config.gemm1_alpha if quant_config.gemm1_alpha is not None else 1.702
        limit = quant_config.gemm1_clamp_limit if quant_config.gemm1_clamp_limit is not None else 7.0
        torch.ops._C.swigluoai_and_mul(output, input, alpha, limit)
    elif activation == MoEActivation.SILU and quant_config.gemm1_clamp_limit is not None:
        swiglu_limit_func(output, input, quant_config.gemm1_clamp_limit)
    elif activation == MoEActivation.SWIGLUOAI_UNINTERLEAVE: # 新增分支,支持 MiniMax-M3-MXFP4
        assert quant_config.gemm1_clamp_limit is not None
        alpha = quant_config.gemm1_alpha if quant_config.gemm1_alpha is not None else 1.0
        beta = quant_config.gemm1_beta if quant_config.gemm1_beta is not None else 0.0
        torch.ops._C.silu_and_mul_with_clamp(output, input, quant_config.gemm1_clamp_limit, alpha, beta)
    else:
        super().activation(activation, output, input)
vllm/model_executor/layers/fused_moe/oracle/mxfp4.py core-logic

修改 MXFP4 后端选择逻辑,将 ROCm 从 CUDA 分支分离,直接返回 TRITON_UNFUSED,是支持新模型的关键路由变更。

# select_mxfp4_moe_backend 函数中平台判断片段
if current_platform.is_xpu():
    backend = Mxfp4MoeBackend.XPU
    logger.info_once(_make_log_backend(backend))
    return _return_or_raise(Mxfp4MoeBackend.XPU, config, kMxfp4Static, None, activation_format)if current_platform.is_cpu():
    backend = Mxfp4MoeBackend.CPU
    logger.info_once(_make_log_backend(backend))
    return _return_or_raise(Mxfp4MoeBackend.CPU, config, kMxfp4Static, None, activation_format)if current_platform.is_rocm(): # 新增 ROCm 分支,避免抛出 NotImplementedError
    backend = Mxfp4MoeBackend.TRITON_UNFUSED
    logger.info_once(_make_log_backend(backend))
    return _return_or_raise(Mxfp4MoeBackend.TRITON_UNFUSED, config, kMxfp4Static, None, activation_format)if current_platform.is_cuda():
    raise NotImplementedError(
        "No MXFP4 MoE backend supports the deployment configuration. "
        f"weight_key=kMxfp4Static, activation_key={activation_key}. "
        ...
    )

评论区精华

ROCm backend fallback 安全风险 正确性

BowenBao 指出无条件选择 TRITON_UNFUSED 可能静默改变输入量化规格;fxmarty-amd 确认会破坏激活量化测试。

结论:作者承诺将在另一个 PR 中处理,当前 PR 未修复。 · 待处理

风险与影响

主要风险:mxfp4.py 中无条件为 ROCm 选择 TRITON_UNFUSED 后端,对于原本使用激活量化的模型(如 W4A8),该后端可能不支持,导致精度下降或运行时错误。此变更静默地改变了后端行为,缺乏日志警告。此外,测试覆盖不足,没有新增针对该模型或后端选择的测试用例。

对用户:ROCm 用户现在可以运行 MiniMax-M3-MXFP4 模型;但可能遇到其他 MXFP4 模型因后端不兼容而出错。对系统:MXFP4 MoE 后端的平台选择逻辑改变,影响所有使用 MXFP4 的 ROCm 系统。对团队:需要在后续 PR 中修复 fallback 行为的警告与条件限制,并补充测试。

平台后端 fallback 缺少测试覆盖 静默行为改变

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论