Prhub

#27858 [AMD] Fix the dsv4 performance of MoE issue.

原始 PR 作者 kkHuang-amd 合并时间 2026-06-11 16:06 文件变更 1 提交数 2 评论 2 代码增减 +19 / -11

执行摘要

修复 AMD DSV4 MoE 性能:传递 intermediate_pad 参数

在 AMD MI355X/gfx950 上,aiter fused_moe 内核性能明显低于参考 ATOM 引擎。经过微观基准测试定位到 intermediate_pad 未正确设置(默认为 0),导致内核计算了填充的零值通道。PR body 提到:“AITER FP4 MoE kernel requires the per-partition intermediate size to be 256-aligned, so during weight loading we pad it (…). But the pad amount was never propagated to fused_moe.”

该 PR 值得精读,特别是性能调优方法:通过微观基准定位到内核参数缺失,再用端到端测试验证。设计上记录了填充量并在内核调用处传递,是一种清晰的解耦方式。Shuffle 函数的清理也提高了代码可维护性。

讨论亮点

Review 评论仅一条:HaiShaw 要求将 gu_intv 从实例属性(self.gu_intv)改为 process_weights_after_loading_block_quant 内的局部变量,作者在第二个 commit 中已采纳。无其他争议。

实现拆解

  1. 记录填充量到 layer 属性:在 Fp8MoEMethod.process_weights_after_loading_block_quant 中,计算 padded_inter 后,将 layer.intermediate_pad = padded_inter - inter_per_partlayer.hidden_pad = 0 保存到 layer 上。
  2. 传递 intermediate_pad 到 fused_moe:在 maybe_get_hip_aiter_quant_info 中,新增 hidden_padintermediate_pad 参数,通过 getattr(layer, ...) 读取并传入 AiterMoeQuantInfo,使得内核跳过填充计算。
  3. 统一 FP4 权重/缩放洗牌:移除对 shuffle_scale_a16w4 / shuffle_weight_a16w4 的导入,改用通用 shuffle_scale / shuffle_weight,并引入 gu_intv 参数(来自环境变量 SGLANG_USE_AITER_MOE_GU_ITLV),使交错布局可配置。
  4. 根据 review 建议将 gu_intv 改为局部变量:初始提交将 gu_intv 设为实例属性,审查要求改为局部变量,最终实现在 process_weights_after_loading_block_quant 中直接读取。
  5. 数值等价性:填充通道权重/缩放为零,计算与否数值等效,GSM8K 精度测试确认无回归(0.970 vs 0.965,在运行间噪声范围内)。
文件 模块 状态 重要度
python/sglang/srt/layers/quantization/fp8.py 量化层 modified 6.68

关键符号

process_weights_after_loading_block_quant maybe_get_hip_aiter_quant_info

关键源码片段

python/sglang/srt/layers/quantization/fp8.py core-logic

所有性能修复和代码清理均在此文件:记录 intermediate_pad/hidden_pad 到 layer 属性、在 maybe_get_hip_aiter_quant_info 中传递给 AiterMoeQuantInfo、统一 shuffle 函数并引入 gu_intv 局部变量。

# python/sglang/srt/layers/quantization/fp8.py# 在 process_weights_after_loading_block_quant 中记录填充量
fp4_k_align = 256
padded_inter = (
    (inter_per_part + fp4_k_align - 1) // fp4_k_align * fp4_k_align
)
# 记录填充量,告诉 fused_moe 实际中间大小
# aiter fused_moe 需要 intermediate_pad = padded - real # ATOM 传 128,
# SGLang 之前默认为 0 导致计算了填充区域
layer.intermediate_pad = padded_inter - inter_per_part # 例如 128
layer.hidden_pad = 0if padded_inter != inter_per_part:
    # pad 权重逻辑不变 ...# 在 maybe_get_hip_aiter_quant_info 中传递到 AiterMoeQuantInfo
AiterMoeQuantInfo(
    ...
    # 以下两个参数是关键修复:让内核跳过填充通道的计算
    hidden_pad=getattr(layer, "hidden_pad", 0),
    intermediate_pad=getattr(layer, "intermediate_pad", 0),
)

评论区精华

gu_intv 应设为局部变量而非实例属性 设计

HaiShaw 在 review 中建议将 `self.gu_intv` 改为 `process_weights_after_loading_block_quant` 内的局部变量,因为该变量仅在函数内使用,无需作为实例属性。

结论:作者采纳建议,在第二个 commit 中将 `gu_intv` 改为函数内局部变量。 · 已解决

风险与影响

该 PR 修改了量化核心逻辑,但变更集中且已验证:

  • 性能回归:无,正确传递 pad 后性能提升。
  • 精度回归:PR 提供了 GSM8K 对比数据,前后精度在运行噪声范围内,无实质回归。
  • 兼容性:默认行为不变(SGLANG_USE_AITER_MOE_GU_ITLV 默认 True,与之前硬编码交错一致)。
  • 风险:缺少独立测试覆盖,仅依赖作者提供的基准测试。如果环境变量或 aiter 版本变更可能受影响,但概率较低。

影响范围:仅影响 AMD GPU(MI355X/gfx950)上使用 aiter 后端的 DeepSeek-V4 FP4 MoE 路径。
影响程度:显著——MoE 内核性能提升 18-19%,端到端解码吞吐提升 5-6%,TPOT/ITL 下降 6-8%。
用户影响:AMD 用户无需配置变更即可获得性能提升;其他硬件平台无影响。

核心路径变更 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论