Prhub

#44005 [Bug] Fix torch device issue for MOE permute

原始 PR 作者 yewentao256 合并时间 2026-05-30 02:55 文件变更 1 提交数 1 评论 0 代码增减 +3 / -0

执行摘要

修复 MoE permute 中 torch 设备不一致崩溃

PR body 中复现了 vllm serve nm-testing/fp8_dynamic_moe-e2e 时 MoE permute 流程中 assert hidden_states.device == self.device 触发的 AssertionError,根因是配置阶段 devicetorch.device("cuda")(无索引),但实际 tensor 位于 cuda:0(带索引),导致设备不匹配。

建议作为常规 bugfix 合并,改动简洁清晰。值得关注的是这种“设备字符串规范化”的模式——在 __post_init__ 中从实际 tensor 推导设备,可作为后续类似初始化陷阱的参考修复方式。

讨论亮点

无 review 评论或讨论。PR 由 mgoin 直接 approve 合并。

实现拆解

  1. MoEPermuteUnpermuteScratchPad.__post_init__ 方法末尾(vllm/model_executor/layers/fused_moe/moe_permute_unpermute.py:77-79)追加一行:self.device = self.token_expert_indices.device
  2. 该赋值基于已创建的第一个 tensor token_expert_indices 的实际设备信息(包含索引),覆盖掉初始化时可能传入的纯 "cuda" 字符串。
  3. 仅修改一个文件,新增 3 行代码(含注释),无测试或配置变更。
文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/moe_permute_unpermute.py MoE 路由 modified 5.2

关键源码片段

vllm/model_executor/layers/fused_moe/moe_permute_unpermute.py data-contract

核心修复位置,在 `__post_init__` 末尾添加设备刷新逻辑,确保 `self.device` 与实际 tensor 设备一致。

# vllm/model_executor/layers/fused_moe/moe_permute_unpermute.py
# 类 MoEPermuteUnpermuteScratchPad 的 __post_init__ 方法末尾(新增第 77-79 行):self.sort_workspace = torch.empty(
    sorter_size, dtype=torch.int8, device=self.device
)# torch.device("cuda") 在配置阶段可能不带索引,
# 初始化后实际 tensor 会位于 cuda:0 等具体设备上,
# 因此需要从已创建的 tensor 中获取正确的设备来更新 self.device,
# 确保后续 validate 断言中的设备比较不会因索引差异而误报。
self.device = self.token_expert_indices.device

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险极低:变更仅将 self.device 重新赋值为实际 tensor 所在设备,不影响其他逻辑;此前 validate 中的断言会因设备字符串差异("cuda" vs "cuda:0")错误地阻止合法输入,修复后断言正常工作。未引入新依赖或副作用。

影响范围狭窄:仅修复使用 torch.device("cuda")(无索引)初始化配置且后续实际运行在多 GPU 场景下的 MoE permute 流程。对于已通过其他方式设置正确设备的用户无影响。涉及文件为 moe_permute_unpermute.py,是 MoE 专家路由的核心路径之一。

窄范围修复

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论