AMD ROCm折腾实录·其二

PyTorch 篇 重置

经典AI工具PyTorch。
在CUDA上用着非常痛快,但是ROCm版仅供Linux使用。
偶尔见到一个自行编译的教程,于是决定自己试一试。
前篇反复修改多次,在此重置,以2.14版本为主。

准备

  • 安装python3.10+(已实测3.14),安装annaconda,安装Visual Studio(实际使用VS2026),git等工具。
  • 需要手动构建 libuv 并添加一个指向它的系统变量。变量名称为libuv_ROOT,指向libuv/install。参考ci
1
2
3
4
5
git clone https://github.com/libuv/libuv.git -b v1.47.0 --depth 1
cd libuv
cmake -S . -B build -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=install
cmake --build build --config Release
cmake --install build --prefix install --config Release
  • 需要安装sccache。从仓库下载windows-amd64版本,将sccache.exe放置在一个添加至系统路径的路径下。
  • 可能需要ccache.exe。我使用的版本来自winlibs.com,解压至一个文件夹,将其添加至系统路径。
  • 本次编译目标为Radeon 880M gfx1150,其他型号请自行前往llvm-amdgpu查找对应架构名称。

极简步骤

  • 克隆TheRock仓库至本地
  • 使用Command Prompt for VS,创建conda虚拟环境,按以下操作克隆pytorch仓库,生成
1
2
3
4
5
6
7
8
9
10
11
12
13
conda create -n rocm python=3.14 -y
conda activate rocm
pip install -r D:\Storage\Developer\Python\TheRock\external-builds\pytorch\requirements-ci.txt
pip install -r D:\Storage\Developer\Python\TheRock\external-builds\pytorch\requirements-test.txt
cd /d "D:\Storage\Developer\Python\TheRock\external-builds\pytorch"

python pytorch_torch_repo.py checkout --gitrepo-origin https://github.com/rocm/pytorch.git --repo-hashtag release/2.14 --checkout-dir "D:\pyt"
python pytorch_audio_repo.py checkout --require-related-commit --checkout-dir ../audio --torch-dir "D:\pyt"
python pytorch_vision_repo.py checkout --require-related-commit --checkout-dir ../vision --torch-dir "D:\pyt"

python build_prod_wheels.py build --install-rocm --index-url https://rocm.nightlies.amd.com/whl-multi-arch/ --rocm-extras device-gfx1150 --pytorch-rocm-arch gfx1150 --pytorch-dir "D:/pyt" --pytorch-vision-dir "D:/Storage/Developer/Python/TheRock/external-builds/vision" --pytorch-audio-dir "D:\Storage\Developer\Python\TheRock\external-builds\audio" --output-dir "D:/Storage/Developer/Python/rocm-output"

python run_pytorch_smoke_tests.py --amdgpu-family gfx1150
  • 然后生成的文件在rocm-output文件夹,打开真实python环境,依次安装rocm_sdk_core rocm_sdk_libraries rocm_sdk_devel rocm_sdk_device_* rocm-*.tar.gz torch torchvision。

详细实战

  • 每次重新编译新版本前,记得清理pytorch/build/CMakeCache.txt和vision,audio的build目录。如果只是版本内的小修改,可以不清理。

  • 代码无改动但是部分生成失败需要重新生成时,可以临时注释掉therock/external-builds/pytorch/build_prod_wheels.py的force-reinstall,节省重新安装rocm全家桶的用时和硬盘损耗。

  • 初次初始化时,pytorch\build\CMakeFiles\4.*\CMakeHIPCompiler.cmake 里的 CMAKE_HIP_COMPILER_ROCM_ROOT 等的路径的反斜杠竟然会被直接识别为转义符,需要手动替换为正斜杠。

  • [pytorch 2.11+]此前版本使用的–require-related-commit现在会无法正确找到目标,所以改为手动指定版本。需要自己找到正确的版本号对应关系。2.14已修复。

  • [pytorch 2.11] :pytorch/third_party/build_bundled.py 118行分析分发许可证处,将分析失败的raise value error替换为return MIT或其他协议,以避免生成失败。这可能是由于setuptools的更新破坏了这部分的功能导致。新版本已修复。

  • [pytorch 2.13+] :checkout pyt 时,有可能遇到 gbk codec can’t decode,此时在pytorch/tools/amd_build/build_amd.py open函数添加参数 encoding=’utf-8’可以解决。

  • [pytorch 2.13] :你可能需要手动在虚拟环境安装 pip install ninja==1.11.0,并且禁用几行删除pypi ninja的build_prod_wheels代码。新版本已修复。

  • [pytorch 2.13] :.conda\envs\rocm\Lib\site-packages_rocm_sdk_devel\lib\llvm\lib\clang\23\include__clang_cuda_math_forward_declares.h 和 __clang_hip_cmath.h里的 isgreater isunordered 等的定义会和msvc的cmath定义冲突,建议使用MSVC v143(或者直接删掉这几行,后果自负)。然而MSVC v143会有其他报错……或者先删掉这几行,编译成功后恢复rocm_sdk_devel,删除 pytorch\build\third_party\gloo 和 pytorch\build\lib\gloo.lib gloo_hip.lib,使用 MSVC v143 跑一遍,到报错为止,再删除 pytorch\build\lib\gloo.lib gloo_hip.lib,回到145再跑一遍,大概也许可以成功。新版本已修复。

  • [pytorch 2.13-2.14] : pytorch\build\CMakeFiles\rules.ninja 里竟然会给 llvm-lib.exe 传入 qc 命令,但是windows环境不认这个,需要替换为/out:。如果每次重新运行build时都会重新生成这个rules.ninja并把命令改回qc,那就在确定生成内容不变后用一个脚本将其变为只读,无法更改,使其强行以out形态通过。新版本可能已修复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 param(
[Parameter(Mandatory=$true)]
[string]$Path
)

$fullPath = [System.IO.Path]::GetFullPath($Path)

if (-not (Test-Path -LiteralPath $fullPath)) {
throw "file not exist: $fullPath"
}

# 关键:FileShare::Read
# 允许其他进程以只读方式打开,但不允许写、删除、重命名
$stream = [System.IO.File]::Open(
$fullPath,
[System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read,
[System.IO.FileShare]::Read
)

Write-Host "LOCKED: $fullPath"
Write-Host "Ctrl+C to exit"

try {
while ($true) {
Start-Sleep -Seconds 3600
}
}
finally {
$stream.Close()
$stream.Dispose()
}

# powershell -NoProfile -ExecutionPolicy Bypass -File .\Lock-File-ReadOnly.ps1 -Path .\build\CMakeFiles\rules.ninja