在 Windows WSL2 下跑 AMD 显卡 ROCm,本质不是“在 Windows 上装 ROCm”,而是在 WSL2 的 Linux 环境里安装 ROCm 运行时,再通过 WSL2 的 /dev/dxg 设备将 GPU 计算请求转发给 Windows 侧的 AMD 驱动。这个机制决定了它和原生 Linux 主机上的 ROCm 有一些显著差异:不需要安装 amdgpu-dkms 内核模块,大部分 ROCm 工具如 rocminfo 也未必能在 WSL2 里看到完整设备信息。先把这条边界记清楚,后面排查会省很多时间。
WSL2 下 AMD 显卡跑 ROCm 推理,通常可行的路径是:在 WSL2 内安装 ROCm 用户态库,用 HIP/PyTorch 的 ROCm 后端调用 /dev/dxg 转发到 Windows 驱动。安装时不要碰 amdgpu-dkms 内核模块;验证以 hipDevice 枚举和 PyTorch 实际运行为准,不要依赖 rocminfo 是否显示 GPU。遇到 gfx 架构不匹配、库路径缺失和 MIOpen 首次初始化报错,按版本和缓存路径排查。
先看安装前提和最简安装路径
WSL2 下使用 ROCm 推理,通常需要满足这几个条件:Windows 侧安装了较新的 AMD Radeon 驱动(Radeon Software 版本一般比仅驱动更稳),WSL2 内核是 5.14 以上,发行版建议选 Ubuntu 22.04 或 24.04。确认 WSL2 能看到显卡设备,可以在 Linux 侧执行:
ls -l /dev/dxg
ids | grep -i dxg
/dev/dxg 存在,说明 WSL2 已把 Windows GPU 转发进来。之后安装 ROCm 时,注意不要直接使用 amdgpu-install 全量安装,因为该脚本在多数情况下会尝试安装 amdgpu-dkms 内核模块,而 WSL2 不依赖这套内核驱动,反而容易把环境装坏。建议只安装 rocm 用户态组件:
sudo apt update
sudo apt install rocm
安装完成后,把路径加进 shell 配置,再检查 HIP 能否枚举到显卡:
export PATH=/opt/rocm/bin:$PATH
export LD_LIBRARY_PATH=/opt/rocm/lib:$LD_LIBRARY_PATH
torch.cuda.is_available() # 在 Python 中验证
注意:ROCm 在 WSL2 下使用 HSA 的路径和原生环境不同,所以 rocminfo 可能显示缺少 /dev/kfd,这是 WSL2 的已知差异,不代表 ROCm 不可用。判断 ROCm 是否真正可用,以 HIP 设备枚举和实际推理为准。
常见报错与诊断顺序
报错按出现时机大致分三类:环境初始化失败、库加载失败、模型运行/内核加载失败。建议按下面的顺序排查,不要一上来就重装整个 ROCm:
- 先确认 /dev/dxg 存在,排除 WSL2 或 Windows 驱动层问题。
- 再确认 ROCm 版本是否覆盖你的显卡架构。RDNA3 系列通常对应 gfx1100/gfx1101/gfx1102,RDNA2 部分型号则需要用 HSA_OVERRIDE_GFX_VERSION 强制指定。
- 确认 Python 侧使用的是 ROCm 版 PyTorch。不要用标准 pip 源安装 PyTorch,那通常是 CUDA 版或 CPU 版;需要从 PyTorch 的 ROCm wheel 索引安装。
- 最后排查 MIOpen 相关警告。
比较典型的两个报错:运行 PyTorch 时提示找不到 libMIOpen.so,通常是因为 MIOpen 组件缺失或 LD_LIBRARY_PATH 里没有把 /opt/rocm/lib 加进去;提示 no binary for current GPU 或 gfx 架构不支持,需要先通过 rocminfo 或 HIP 查询实际 gfx 编号,再调整 HSA_OVERRIDE_GFX_VERSION。
python -c "import torch; print(torch.version.hip); print(torch.cuda.is_available())"
这里 torch.cuda.is_available() 返回 True 并不是错误,PyTorch 的 ROCm 后端沿用了 CUDA 的接口命名,返回 True 说明 torch 已识别到 ROCm 设备。这一步能通过,再跑一个小模型验证 MIOpen 初始化,避免一上来就跑大模型而分不清是哪一层报错。
两个必须知道的环境变量
排查时最常用的是下面两个变量,涉及架构强制覆盖和 MIOpen 缓存隔离:
| 变量 | 作用 | 适用场景 |
|---|---|---|
| HSA_OVERRIDE_GFX_VERSION | 让 HIP 按指定 gfx 架构编译/加载内核 | 显卡架构未在 ROCm 默认支持列表里时使用 |
| MIOPEN_USER_DB_PATH / MIOPEN_CUSTOM_CACHE_DIR | 指定 MIOpen 内核缓存路径 | WSL2 首次运行或缓存目录不可写时使用 |
HSA_OVERRIDE_GFX_VERSION 要按显卡实际代次填,例如 RDNA2 的 RX 6600 可试 gfx1032,RDNA3 的 RX 7700 XT 可试 gfx1101。这里不需要精确记忆对应关系,关键是先通过 HIP 查到实际 device 信息,再去设置覆盖值。设置后重新运行同一个小模型,观察是否出现新的报错。
运行前的一个验证清单
建议在跑正式推理前,按这个顺序快速过一遍:
- 确认 /dev/dxg 存在且 Windows 驱动已更新。
- 确认 rocm 包已安装,/opt/rocm 目录存在。
- 在 Python 中导入 torch,打印 torch.version.hip,确认是 ROCm 版而非 CUDA 版。
- 跑一个很小的 Float32 模型(比如 4 层 MLP),确认前向传播和反向传播(若需要训练)没有报错。
- 再次运行同一个小模型,观察 MIOpen 缓存是否已生成。WSL2 首次运行 MIOpen 会花较长时间构建缓存,第二次运行仍然很慢或反复报错时,再考虑清理或迁移缓存目录。
排查到最后,如果发现 gfx 架构、库路径、驱动版本都检查过且仍未解决,建议把问题拆成两层:先确认 HIP 层能否枚举设备,再确认 torch 层能否实际分配显存并执行 kernel。这两层边界清晰后,很多混合报错就不会互相干扰判断了。
常见问题
WSL2 里 rocminfo 找不到 GPU,是不是 ROCm 没装好?
不一定。WSL2 下 ROCm 通过 dxg 转发访问 Windows 驱动,rocminfo 依赖 HSA 的 /dev/kfd,而该节点在 WSL2 中通常不可用。先用 Python 调 torch.cuda.is_available() 或 HIP 枚举设备列表,如果能看到设备,说明 ROCm 可用,rocminfo 的表现属于 WSL2 的已知显示差异。
第一次跑推理时提示 MIOpen 相关错误,是环境坏了吗?
需要区分两种情况:libMIOpen.so 找不到属于库路径或组件缺失,要检查 LD_LIBRARY_PATH 和 rocm 安装完整性;如果提示类似“MIOpen 正在编译内核”或慢速初始化,则属于首次构建缓存,通常可继续运行。判断要点是看报错是否中断程序,以及第二次运行是否恢复正常。WSL2 使用 Windows 侧驱动,缓存路径权限、跨版本残留都可能导致 MIOpen 反复重新编译,必要时用 MIOpen 的缓存变量隔离一套 WSL2 专用目录。