Prhub

#39280 [ROCm][Perf] Add Fused Shared Expert (FSE) support for Qwen3-Next

原始 PR 作者 nholmber 合并时间 2026-05-09 03:38 文件变更 8 提交数 15 评论 59 代码增减 +359 / -10

执行摘要

融合共享专家加速 Qwen3-Next 解码 16%-24%

Qwen3-Next模型包含共享专家,常规实现需要独立SharedExpert MLP前向,带来额外kernel启动和显存读写。通过将共享专家融合到MoE内核,可以减少kernel启动次数、提高GPU利用率,显著提升解码吞吐。

值得精读。展示了ROCm专有性能优化的一般模式:利用环境变量开关、运行时版本检查、fallback路径、以及通过独立路由器类避免污染通用代码。设计权衡(门控融合位置、条件判断缓存)值得参考。后续扩展FSE到其他模型时可以参考此框架。

讨论亮点
  • 架构选择:@tjtanaa 和 @bnellnm 建议采用 DeepSeekV2 的方式而非注入方式,最终PR调整为独立路由器类,符合路由器扩展性设计。
  • 路由器独立性:@robertgshaw2-redhat 提出将FSE逻辑从现有路由器中抽离,避免了条件膨胀,最终采纳。
  • 运行时检查:@dllehr-amd 建议将多次条件检查合并为单一缓存方法,PR实现了 fuse_sigmoid_in_kernel() 统一入口。
  • Bug修复:@gemini-code-assist[bot] 指出 n_shared_experts 传递 None 导致 TypeError 以及 SharedFusedMoE 返回解包错误,PR已修正。
  • 门控融合位置:@robertgshaw2-redhat 和 @bnellnm 讨论应在模型层还是 runner 层融合,当前采用 runner 层融合,但保留模型层可选路径的讨论空间。

实现拆解

实现包含以下主要步骤:

  1. 门控权重融合:在 moe_runner.pyMoERunner._maybe_fuse_gate_weights() 中,将 gate.weightshared_expert_gate.weight 沿第0维拼接为 [num_experts + num_shared, hidden] 的合并权重,使得一次 F.linear 即可产生路由和共享专家的组合logits。

  2. AITER ops扩展:在 _aiter_ops.py 中为 topk_softmax 函数新增 num_shared_expertsshared_expert_scoring_func 参数;类方法 topk_softmax_supports_fused_sigmoid() 动态检查 AITER 版本是否支持融合;fuse_sigmoid_in_kernel() 汇总全部条件(共享专家启用、AITER 支持、元数据已初始化)。

  3. 专用路由器:新建 aiter_shared_routed_fused_moe_router.py,包含 AiterSharedRoutedFusedMoERouter。在 _compute_routing 中根据 fuse_sigmoid_in_kernel 判断:若支持则调用7参数 topk_softmax 同时计算softmax和sigmoid;否则回退到分离的topk_softmax + sigmoid + inject_shared_expert_weights 合并。

  4. 权重注入rocm_aiter_fused_moe.py 新增 inject_shared_expert_weights(),将路由topk结果拷贝到AITER预分配 total_topk_weights/total_topk_ids 缓冲区,并将动态共享专家门控值写入对应槽位。

  5. 模型适配qwen3_next.py 中当FSE启用时 self.shared_expert 置为 None(避免模型侧重复计算);load_weights 中将共享专家权重重映射到第 num_experts 号的融合专家槽。qwen3_next_mtp.py 相应调整。

  6. 路由器工厂router_factory.py 增加条件分支,当 num_fused_shared_experts > 0 且符合 ROCm AITER 条件时返回 AiterSharedRoutedFusedMoERouter

  7. 其他配套layer.py 新增 shared_expert_gate 参数传递。

文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/router/aiter_shared_routed_fused_moe_router.py 路由器 added 9.27
vllm/_aiter_ops.py AITER 层 modified 7.76
vllm/model_executor/layers/fused_moe/rocm_aiter_fused_moe.py AITER MoE modified 7.54
vllm/model_executor/layers/fused_moe/runner/moe_runner.py MoE 执行器 modified 7.3
vllm/model_executor/models/qwen3_next.py 模型 modified 6.96
vllm/model_executor/layers/fused_moe/router/router_factory.py 路由器工厂 modified 6.9

关键符号

AiterSharedRoutedFusedMoERouter.__init__ AiterSharedRoutedFusedMoERouter._compute_routing rocm_aiter_ops.topk_softmax_supports_fused_sigmoid rocm_aiter_ops.fuse_sigmoid_in_kernel inject_shared_expert_weights MoERunner._maybe_fuse_gate_weights

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

评论区精华

采用 DeepSeek 方法替代注入 设计

@tjtanaa 建议采用 DeepSeekV2 的做法;@bnellnm 表示支持。

结论:PR 最终重构为独立路由器类,接近 DeepSeek 模式。 · 已解决

抽取 num_fused_shared_experts 为构造函数参数 设计

@bnellnm 和 @dllehr-amd 建议从 _compute_routing 中移除 extra 参数,放到路由器构造函数;@tpopp 最终实现。

结论:num_fused_shared_experts 作为 BaseRouter.__init__ 参数,per-instance 决定。 · 已解决

运行时条件检查缓存 性能

@dllehr-amd 建议将多次条件检查合并为一个缓存函数;@tpopp 实现了 fuse_sigmoid_in_kernel。

结论:通过单一方法组合静态和动态检查,减少重复计算。 · 已解决

门控融合位置选择 设计

@robertgshaw2-redhat 询问是否应该在 runner 中融合还是模型层预处理;@bnellnm 倾向模型层。

结论:当前采用 runner 内融合,保留后续优化空间。 · 已解决

n_shared_experts 默认为 None 导致 TypeError 正确性

@gemini-code-assist[bot] 指出传递 None 而不是 0 导致 runner 比较出错。

结论:修正为 default 0。 · 已解决

SharedFusedMoE 返回解包错误 正确性

@gemini-code-assist[bot] 指出当 shared_expert 和 is_fse_enabled 都为 False 时 final_hidden_states 仍是 tuple。

结论:修正解包逻辑。 · 已解决

风险与影响

  • 缺少测试覆盖:本PR未新增单元测试,依赖现有MoE测试套件,无法保证所有分支(fallback路径、异常条件)都覆盖。
  • 权重重映射依赖qwen3_next.py 将共享专家权重重映射到固定索引 num_routed 的专家槽,若模型配置变化(如 num_experts 动态调整)可能导致加载错误。
  • AITER版本兼容性:融合 sigmoid 功能依赖 aiter.topk_softmax 的7参数版本,若无则该功能透明fallback,但用户需同时更新 AITER 库才能获得性能收益。
  • 环境变量安全VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS 为新增变量,默认关闭,误开启但条件不满足时会调用 FusedTopKRouter 回退,行为与未开启一致,无崩溃风险。
  • 用户影响:仅 ROCm 用户受益,需设置 VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1 获得吞吐提升;非 ROCm 和默认配置无变化。
  • 系统影响:新增 AiterSharedRoutedFusedMoERouter 路由选择和 ROCM AITER ops 扩展,增加代码路径。
  • 团队影响:需跟踪 AITER 库版本变更以维护 topk_softmax 签名检查;可能引入与 DeepSeek 等其他共享专家实现的兼容问题。
缺少测试覆盖 AITER 版本兼容 权重重映射依赖 核心路径变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论