# PR #44005 完整报告

- 仓库：`vllm-project/vllm`
- 标题：[Bug] Fix torch device issue for MOE permute
- 合并时间：2026-05-30 02:55
- 原文链接：http://prhub.com.cn/vllm-project/vllm/pull/44005

---

# 执行摘要

- 一句话：修复 MoE permute 中 torch 设备不一致崩溃
- 推荐动作：建议作为常规 bugfix 合并，改动简洁清晰。值得关注的是这种“设备字符串规范化”的模式——在 `__post_init__` 中从实际 tensor 推导设备，可作为后续类似初始化陷阱的参考修复方式。

# 功能与动机

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

# 实现拆解

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 路由；类别 source；类型 data-contract）: 核心修复位置，在 `__post_init__` 末尾添加设备刷新逻辑，确保 `self.device` 与实际 tensor 设备一致。

关键符号：未识别

## 关键源码片段

### `vllm/model_executor/layers/fused_moe/moe_permute_unpermute.py`

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

```python
# 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

```

# 评论区精华

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

- 暂无高价值评论线程

# 风险与影响

- 风险：风险极低：变更仅将 `self.device` 重新赋值为实际 tensor 所在设备，不影响其他逻辑；此前 `validate` 中的断言会因设备字符串差异（`"cuda"` vs `"cuda:0"`）错误地阻止合法输入，修复后断言正常工作。未引入新依赖或副作用。
- 影响：影响范围狭窄：仅修复使用 `torch.device("cuda")`（无索引）初始化配置且后续实际运行在多 GPU 场景下的 MoE permute 流程。对于已通过其他方式设置正确设备的用户无影响。涉及文件为 `moe_permute_unpermute.py`，是 MoE 专家路由的核心路径之一。
- 风险标记：窄范围修复

# 关联脉络

- PR #42553 [MoE Refactor] WNA16 MoE backend selection into oracle module: 同为 MoE 模块的改动，涉及后端选择和专家路由的底层重构，本次 permute 修复是 MoE 执行路径上的一个小补丁。
- PR #43219 [EPLB] Make async EPLB default: 同为 MoE 相关 PR，关注专家并行负载均衡，与 permute 同属于 MoE 路由执行流程。