Prhub

#37833 [ROCm] Fix MoE kernel test failures on gfx950

原始 PR 作者 AndreasKaratzas 合并时间 2026-03-26 02:46 文件变更 12 提交数 19 评论 15 代码增减 +480 / -88

执行摘要

修复 ROCm gfx950 平台 Mixture of Experts 内核测试失败,涉及 API 差异、数值稳定性和测试增强。

修复ROCm-specific MoE kernel test failures on MI355 (gfx950),具体问题包括:triton_kernels.topk在ROCm上返回tuple而非SparseMatrix导致expert_map路径失败;C++ persistent_masked_m_silu_mul_quant内核仅在CUDA下可用,需在ROCm上回退到Triton实现;FP8量化边界因GPU快速除法误差导致测试失败,需改用乘法提高精度。这些修复基于aiter项目issue #2418、#2419、#2420、#2421,以保障ROCm平台MoE功能稳定性。

该PR值得精读,特别是ROCm平台MoE内核的实现细节和数值稳定性技巧。建议关注以下设计决策:

  • 平台特定回退机制(如C++内核保护)的优雅处理方式。
  • FP8量化中乘法替换除法以避免边界误差的通用性。
  • 测试中容差放松与诊断增强的平衡,可作为处理硬件差异的参考案例。
    工程师可从中学习如何适配多平台API差异和优化数值鲁棒性。
讨论亮点

review讨论聚焦于平台特定逻辑的精确性和测试正确性:

  • 检查顺序争议:gshtras建议在batched_deep_gemm_moe.py中先检查current_platform.is_cuda()再检查cuda_arch,AndreasKaratzas随后修复,确保逻辑清晰。
  • FP8数据类型处理:tjtanaa指出应使用get_fp8_min_max()而非硬编码torch.float8_e4m3fn,以支持gfx942平台的float8_e4m3fnuz;AndreasKaratzas集成变更,统一使用平台fp8_dtype。
  • gfx942适用性疑问:gshtras询问hidden_size填充是否也适用于gfx942,AndreasKaratzas澄清仅限gfx950原生CK路径,并后续重构代码以准确限制。
  • 测试平台限制:tjtanaa建议ROCm特定测试添加skipif条件,AndreasKaratzas实施,避免非ROCm平台执行。
    所有讨论点均已解决,达成共识,未遗留重大疑虑。

实现拆解

实现方案分为内核修改和测试更新两大模块:

  1. 内核修改
    • gpt_oss_triton_kernels_moe.py:处理topk_fn返回tuple与SparseMatrix的差异,通过instance检查适配expert_map路径。
    • batched_deep_gemm_moe.py:将C++ persistent_masked_m_silu_mul_quant内核用current_platform.is_cuda()保护,ROCm时回退到Triton实现;同时使用get_fp8_min_max()替代硬编码fp8_dtype。
    • fp8_utils.py:在三个Triton FP8量化内核中将除法(amax / fp8_max)替换为乘法(amax * (1/fp8_max)),消除1-ULP GPU快速除法误差。
    • quark_moe.py:为gfx950的GFX950MXScaleLayout swizzle添加hidden_size填充逻辑,仅限于原生CK路径。
  2. 测试更新
    • 多个测试文件添加平台感知逻辑:如test_silu_mul_fp8_quant_deep_gemm.py区分CUDA C++内核和ROCm Triton回退的参考精度;test_modular_kernel_combinations.py添加fe_supports_quant_scheme()验证并放松AITER FP8硬件matmul的容差。
    • 增强诊断工具:test_shared_fused_moe_routed_transform.py引入_assert_close函数,提供NaN检测和差异统计;test_routing.py添加assert_aiter_routing_valid验证AITER路由输出结构。
    • 测试跳过与过滤:如跳过ROCm上不支持的UE8M0和block-scaled apply_router_weight_on_input组合。
文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/gpt_oss_triton_kernels_moe.py fused_moe modified 7.0
vllm/model_executor/layers/fused_moe/batched_deep_gemm_moe.py fused_moe modified 7.0
vllm/model_executor/layers/quantization/utils/fp8_utils.py quantization modified 6.0
tests/kernels/moe/test_modular_kernel_combinations.py testing modified 6.0
tests/kernels/moe/test_shared_fused_moe_routed_transform.py testing modified 5.0

关键符号

fe_supports_quant_scheme persistent_masked_m_silu_mul_quant _silu_mul_fp8_quant_deep_gemm triton_kernel_moe_forward assert_aiter_routing_valid

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

评论区精华

平台检查顺序优化 设计

gshtras 建议在 batched_deep_gemm_moe.py 中先检查 current_platform.is_cuda() 再检查 cuda_arch,以提高代码清晰度和可维护性。

结论:AndreasKaratzas 接受建议并修改代码,确保逻辑正确性。 · 已解决

FP8 数据类型与平台兼容性 正确性

tjtanaa 指出测试中应使用 get_fp8_min_max() 而非硬编码 torch.float8_e4m3fn,以支持 gfx942 的 float8_e4m3fnuz,避免测试失败。

结论:AndreasKaratzas 集成变更,统一使用平台 fp8_dtype 和 get_fp8_min_max(),确保跨平台正确性。 · 已解决

gfx950 特定逻辑的适用范围 question

gshtras 询问 hidden_size 填充是否也适用于 gfx942,AndreasKaratzas 澄清仅限 gfx950 原生 CK 路径,并后续重构以精确限制。

结论:通过代码重构,确保填充逻辑仅应用于 gfx950 且非模拟路径,避免误用。 · 已解决

风险与影响

技术风险包括:

  1. 回归风险:内核修改如topk返回类型处理和除法替换可能影响CUDA平台或其他ROCm硬件,需依赖现有测试覆盖和CI验证。
  2. 性能影响:乘法替换除法声称零性能影响,但需确保编译器优化一致;C++内核回退到Triton可能增加ROCm平台开销,但已通过基准测试确认。
  3. 兼容性问题:平台特定逻辑(如is_cuda()检查)可能在未来平台扩展时失效,需文档说明。
  4. 测试松绑风险:放松AITER FP8硬件matmul容差(允许5%元素超出基差)可能掩盖真实数值问题,但添加了日志跟踪和边界检查以控制风险。
  5. 初始化漏洞修复test_shared_fused_moe_routed_transform.py中修复了未初始化权重导致的测试静默通过,提升了测试可靠性。

影响范围:

  • 用户影响:ROCm平台用户(特别是gfx950)将获得更稳定的MoE推理体验,测试通过率提升,减少运行时错误。
  • 系统影响:CI测试稳定性增强,减少ROCm构建失败,支持更广泛的硬件验证;数值改进可能提升FP8量化精度,但仅限于ROCm平台。
  • 团队影响:降低ROCm维护负担,提供更清晰的平台差异处理模式,促进跨团队协作;测试诊断工具改进有助于未来调试。
    影响程度中等,主要集中在ROCm特定路径,不影响核心CUDA功能。
平台特定逻辑 测试容差放松 内核修改 数值稳定性变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论