1. 项目概述:为什么要在Ubuntu 22.04上折腾ROCm 6.0?

如果你手头有一块AMD的显卡,比如最近几年出的Radeon RX 6000/7000系列,或者数据中心级的Instinct系列,并且想在Linux系统上跑点机器学习、科学计算或者搞点高性能计算的研究,那么ROCm这个平台你肯定绕不开。它就像是AMD为自家GPU打造的一个“操作系统”,让GPU能听懂并执行那些复杂的计算任务。我最近就在一台搭载了RX 7900 XTX的工作站上,给Ubuntu 22.04 LTS装上了最新的ROCm 6.0,整个过程可以说是一波三折,踩的坑比预想的多,但也因此摸清了不少门道。

Ubuntu 22.04作为一个长期支持版本,系统稳定、软件生态成熟,是很多开发者和研究人员的首选。而ROCm 6.0带来了对更多GPU架构的正式支持、性能提升以及更好的软件栈兼容性。但是,官方文档有时候写得比较“理想化”,默认你有一个纯净的、特定配置的系统环境。现实往往是,我们的系统可能装过其他版本的驱动、有过不同的配置,或者硬件本身有些特殊。这篇内容就是把我从准备环境、执行安装到解决各种报错的完整过程,以及背后的原理和思考,详细地记录下来。目标很简单:让你能避开我踩过的那些坑,更顺畅地在自己的Ubuntu 22.04上把ROCm 6.0跑起来。

2. 安装前的深度准备:不只是看文档那么简单

很多人安装失败,第一步就错了。安装前的准备工作,其重要性不亚于安装过程本身。这一步的核心是创造一个对ROCm“友好”的系统环境,同时彻底摸清自家硬件的底细。

2.1 硬件与系统兼容性彻查

首先,必须确认你的GPU在ROCm 6.0的支持列表里。ROCm对GPU架构有严格要求。你可以通过以下命令快速查询你的显卡型号和当前的驱动情况:

lspci | grep -i vga

或者更详细地查看所有PCI设备中的显示控制器:

lspci | grep -i amd

对于AMD显卡,你可能会看到类似“Advanced Micro Devices, Inc. [AMD/ATI] Navi 31 [Radeon RX 7900 XTX]”这样的信息。关键在于“Navi 31”这个架构代号。接下来,去AMD ROCm的官方GitHub仓库或文档页面,查找“ROCm 6.0 Supported GPUs”列表。确保你的架构(如GFX90A for MI系列,GFX11xx for RDNA3系列)在列。

注意 :ROCm对消费级显卡(如RX 6000/7000系列)的支持被称为“Limited Support”,这意味着虽然核心计算功能可用,但可能不会像数据中心卡那样获得所有优化和官方测试覆盖。社区通常有解决方案,但需要多一点耐心。

其次,检查系统架构。ROCm目前主要支持x86_64架构。如果你的系统是ARM(比如某些基于AWS Graviton的实例),则需要特别版本的ROCm,普通安装方式不适用。

最后,确认系统版本。我们虽然目标是Ubuntu 22.04,但也要确保你的系统是最新的。运行:

lsb_release -a
sudo apt update && sudo apt upgrade -y

进行一次全面的系统更新,可以解决很多因旧软件包引起的底层库冲突问题。

2.2 清理战场:处理旧版驱动与冲突软件

这是最关键的步骤,也是最多坑的来源。你的系统里可能残留着以前通过 apt amdgpu-install 脚本甚至手动编译安装的AMD驱动或ROCm组件。混合安装会导致不可预知的冲突。

1. 识别并卸载现有AMD驱动/ROCm:

首先,尝试用AMD官方的卸载脚本(如果之前用过):

sudo amdgpu-uninstall
sudo rocm-uninstall

如果找不到这些命令,或者你不确定之前是怎么装的,那就进行手动清理。这需要一点魄力,但很有效:

# 移除通过apt安装的可能相关包
sudo apt autoremove --purge rocm-* amdgpu-* rock-dkms* -y

# 清理可能残留的仓库和配置
sudo rm -rf /etc/apt/sources.list.d/rocm.list /etc/apt/sources.list.d/amdgpu.list
sudo rm -rf /opt/rocm-* # 注意:这会删除所有旧版ROCm安装

2. 处理第三方驱动仓库冲突:

如果你之前为了打游戏或通用显示,添加了 ppa:oibaf/graphics-drivers ppa:kisak/kisak-mesa 这类第三方图形驱动PPA,强烈建议先移除它们。ROCm需要特定版本的内核驱动和用户态组件,这些第三方仓库的版本可能不兼容。

# 使用add-apt-repository移除PPA,或直接注释掉/etc/apt/sources.list.d/下对应的.list文件
sudo add-apt-repository --remove ppa:oibaf/graphics-drivers
sudo apt update

3. 处理潜在的内核模块冲突:

重启系统,在GRUB界面(如果需要,开机时按Shift键)选择进入“Advanced options for Ubuntu”,然后选择一个较新的、但非第三方修改的通用内核(generic kernel)启动。有时,为特定显卡优化的内核(如 linux-image-5.19.0-xx-lowlatency )可能与ROCm DKMS模块编译不兼容。使用通用内核是一个更安全的选择。

2.3 安装依赖与配置系统

在引入ROCm仓库前,先安装一些基础编译工具和依赖,这些是后续安装和DKMS编译所必需的:

sudo apt update
sudo apt install -y linux-headers-$(uname -r) linux-modules-extra-$(uname -r)
sudo apt install -y build-essential dkms libnuma-dev pkg-config libpci-dev

linux-headers dkms 至关重要,因为ROCm的核心内核驱动 amdgpu amdkfd 需要通过DKMS动态编译并插入到你当前运行的内核中。

3. 正式安装ROCm 6.0:步骤分解与原理剖析

准备工作做扎实了,安装过程本身反而相对直接。但每一步背后的“为什么”值得深究。

3.1 添加官方仓库并安装

ROCm团队为Ubuntu提供了APT仓库,这是最推荐的安装方式,便于后续管理和更新。

1. 添加ROCm仓库和密钥:

# 添加AMD GPU仓库密钥
wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/rocm-keyring.gpg

# 添加ROCm 6.0的APT仓库
echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/rocm-keyring.gpg] https://repo.radeon.com/rocm/apt/6.0 jammy main' | sudo tee /etc/apt/sources.list.d/rocm.list

这里有几个细节:

  • jammy 是Ubuntu 22.04的代号,必须写对。
  • 将GPG密钥放入 /etc/apt/trusted.gpg.d/ 是当前更推荐的做法,比直接 apt-key add 更规范。
  • 指定 [arch=amd64] 确保只获取对应架构的包。

2. 设置优先级(可选但重要):

为了避免ROCm的包与Ubuntu主仓库中的一些低版本库(如 libstdc++ )发生冲突,可以设置一个较低的优先级,让系统优先使用Ubuntu官方仓库的版本,除非ROCm仓库的包版本更高。

创建文件 /etc/apt/preferences.d/rocm-pin-600

Package: *
Pin: release o=repo.radeon.com
Pin-Priority: 600

Pin-Priority: 600 是一个较低的优先级(默认是500,Ubuntu主仓库是500),这意味着只有当ROCm仓库的包版本 高于 系统其他仓库时,才会被安装。这有助于维持系统基础库的稳定性。

3. 更新仓库并安装:

sudo apt update

现在,你可以选择安装不同的元包:

  • rocm-hip-sdk : 这是最核心的包,包含了HIP运行时、编译器、库等,适合大多数开发场景。
  • rocm-dev : 包含开发所需的头文件和库。
  • rocm-libs : 仅包含运行时库,适合部署环境。

对于初次安装和开发,我建议安装完整的开发套件:

sudo apt install -y rocm-hip-sdk

这个命令会拉取一大堆依赖,包括 rocm-core hipcc rocblas rocrand 等核心组件。安装过程可能会持续一段时间,取决于你的网速。

3.2 配置用户组与环境变量

安装完成后,需要让普通用户也能访问GPU设备。

1. 将用户加入 render video 组:

sudo usermod -a -G render,video $LOGNAME

render video 组是Linux系统中用于管理图形和视频设备访问权限的传统组。加入这些组后,用户无需 sudo 即可直接与GPU交互。 你需要注销并重新登录,或者重启系统,这个组变更才会生效。

2. 设置环境变量:

为了让系统找到ROCm的库和工具,需要将 /opt/rocm 下的相关路径加入环境变量。最持久的方法是在你的shell配置文件(如 ~/.bashrc ~/.zshrc )末尾添加:

export PATH=$PATH:/opt/rocm/bin:/opt/rocm/llvm/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib

添加后,执行 source ~/.bashrc 使其立即在当前终端生效。

实操心得 :关于 LD_LIBRARY_PATH ,有些教程会建议避免设置它,因为它可能引起库版本冲突。但对于ROCm,在用户级别设置是常见且必要的,因为它安装的库不在系统默认搜索路径中。只要确保你的系统库(通过 apt 安装)是稳定的,通常问题不大。

4. 安装后的验证与核心问题排查

安装完成并配置好环境后,千万不要以为就万事大吉了。验证阶段才是真正考验安装是否成功的环节。

4.1 基础验证命令

1. 检查ROCm信息:

/opt/rocm/bin/rocminfo

这个命令会输出一长串信息,包括检测到的GPU列表、每个GPU的架构特性、可用内存等。 关键看两点 :一是有没有列出你的显卡;二是看最后有没有报错。如果顺利列出,说明ROCm运行时识别了你的GPU。

2. 检查HIP编译器:

hipcc --version

这会显示HIP的版本信息,确认编译器安装成功。

3. 运行一个简单的HIP程序:

ROCm SDK自带了一些示例。我们可以编译并运行一个最简单的向量加法程序来测试整个工具链。

# 创建一个测试目录
mkdir ~/rocm_test && cd ~/rocm_test

# 编写一个简单的HIP程序,保存为 test_hip.cpp
cat << EOF > test_hip.cpp
#include <iostream>
#include <hip/hip_runtime.h>

__global__ void vectorAdd(const float *A, const float *B, float *C, int numElements) {
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < numElements) {
        C[i] = A[i] + B[i];
    }
}

int main() {
    int numElements = 50000;
    size_t size = numElements * sizeof(float);

    // 分配主机内存
    float *h_A = (float *)malloc(size);
    float *h_B = (float *)malloc(size);
    float *h_C = (float *)malloc(size);

    // 初始化主机数据
    for (int i = 0; i < numElements; ++i) {
        h_A[i] = rand() / (float)RAND_MAX;
        h_B[i] = rand() / (float)RAND_MAX;
    }

    float *d_A, *d_B, *d_C;
    // 分配设备内存
    hipMalloc((void **)&d_A, size);
    hipMalloc((void **)&d_B, size);
    hipMalloc((void **)&d_C, size);

    // 拷贝数据到设备
    hipMemcpy(d_A, h_A, size, hipMemcpyHostToDevice);
    hipMemcpy(d_B, h_B, size, hipMemcpyHostToDevice);

    // 启动核函数
    int threadsPerBlock = 256;
    int blocksPerGrid = (numElements + threadsPerBlock - 1) / threadsPerBlock;
    hipLaunchKernelGGL(vectorAdd, dim3(blocksPerGrid), dim3(threadsPerBlock), 0, 0, d_A, d_B, d_C, numElements);

    // 将结果拷贝回主机
    hipMemcpy(h_C, d_C, size, hipMemcpyDeviceToHost);

    // 简单验证前5个结果
    for (int i = 0; i < 5; i++) {
        std::cout << "C[" << i << "] = " << h_C[i] << " (should be " << h_A[i] + h_B[i] << ")" << std::endl;
    }

    std::cout << "Test PASSED!" << std::endl;

    // 清理
    hipFree(d_A); hipFree(d_B); hipFree(d_C);
    free(h_A); free(h_B); free(h_C);

    return 0;
}
EOF

# 使用hipcc编译
hipcc test_hip.cpp -o test_hip

# 运行程序
./test_hip

如果程序成功编译并运行,输出“Test PASSED!”,那么恭喜你,从HIP运行时、编译器到GPU内核执行,整个链路都是通的。

4.2 常见故障与深度排查实录

在实际操作中,你很可能会遇到各种错误。下面是我遇到过的几个典型问题及其解决方案。

问题1: rocminfo 命令报错 “ Failed to initialize. No devices found ” 或 “ HSA_STATUS_ERROR: Out of resources.

这是最常见的问题,意味着ROCm运行时没有找到可用的GPU,或者访问GPU资源失败。

  • 排查思路1:检查内核模块

    lsmod | grep amdgpu
    

    这个命令应该列出 amdgpu amdkfd 模块。如果只有 amdgpu 没有 amdkfd ,说明ROCm的计算内核驱动没有正确加载。尝试手动加载:

    sudo modprobe amdgpu
    sudo modprobe amdkfd
    

    如果 modprobe 失败,查看内核日志获取详细信息:

    sudo dmesg | tail -50
    

    常见的错误是“ Required firmware file amdgpu/xxx.bin is missing ”。这说明你的 linux-firmware 包太旧,不包含你的GPU所需的固件。

  • 解决方案 :升级 linux-firmware 包。

    sudo apt update
    sudo apt install --install-recommends linux-firmware
    

    安装后 必须重启系统 ,让新固件生效。

  • 排查思路2:检查用户组和权限 确认你已经重新登录,并且 id 命令显示你在 render video 组里。

    id
    

    检查GPU设备文件的权限:

    ls -l /dev/dri/renderD*
    

    输出应该类似 crw-rw----+ 1 root render ... 。确保你有读/写权限(通过 render 组)。

  • 排查思路3:检查GPU是否被其他驱动占用 有时,开源驱动 radeon 可能会和 amdgpu 冲突。确保 radeon 模块没有被加载:

    lsmod | grep radeon
    

    如果它被加载了,你可能需要在内核参数中禁用它。编辑 /etc/default/grub ,在 GRUB_CMDLINE_LINUX_DEFAULT 行添加 radeon.si_support=0 radeon.cik_support=0 amdgpu.si_support=1 amdgpu.cik_support=1 (针对GCN 1.0/1.1架构的旧卡,新卡一般不需要)。然后运行 sudo update-grub 并重启。

问题2:编译HIP程序时出现“ undefined reference to std::xxx`”等链接错误

这通常是C++标准库链接问题。HIP编译器 hipcc 是一个包装脚本,它最终会调用底层的Clang或GCC。有时环境中的G++版本不匹配会导致问题。

  • 解决方案 :明确指定C++标准库。在编译命令中加上 -stdlib=libstdc++
    hipcc test_hip.cpp -o test_hip -stdlib=libstdc++
    
    或者,确保你的系统安装了完整版本的G++:
    sudo apt install g++-11
    
    (Ubuntu 22.04默认是g++-11)

问题3:运行程序时出现“ error: hipErrorNoDevice

这个错误明确表示没有找到可用的HIP设备。这又回到了 rocminfo 的问题。请按照 问题1 的步骤仔细排查内核模块、固件和权限。

问题4: sudo apt install rocm-hip-sdk 时出现依赖冲突

这通常是因为系统中存在不兼容的库版本,或者之前残留的包没有清理干净。

  • 解决方案 :尝试使用 apt -f (fix broken)选项来修复依赖:
    sudo apt install -f
    
    如果不行,可以尝试更激进的清理,并指定安装版本:
    # 模拟安装,查看具体冲突的包
    sudo apt install -s rocm-hip-sdk
    # 根据输出,手动尝试移除或降级冲突的包
    sudo apt remove <冲突的包名>
    # 或者,尝试安装特定版本的ROCm元包
    sudo apt install rocm-hip-sdk=6.0.0.60000-63~22.04
    
    版本号可以通过 apt-cache policy rocm-hip-sdk 查看。

5. 进阶配置与性能调优要点

当基础功能验证通过后,为了获得更好的稳定性和性能,可以进行一些进阶配置。

5.1 配置HSA(异构系统架构)覆盖层

对于多GPU系统,或者为了更精细地控制GPU可见性,可以配置 HSA_OVERRIDE_GFX_VERSION 环境变量。例如,如果你有一张RX 7900 XTX(GFX1100架构),但ROCm默认可能没有为你的特定型号优化,可以强制指定架构:

export HSA_OVERRIDE_GFX_VERSION=11.0.0

将这个命令也加入你的 ~/.bashrc 。你可以在 /opt/rocm/lib/ 目录下查找 libamdhip64.so 等库文件,用 readelf strings 命令查看其支持的架构,来确定正确的覆盖版本。

5.2 使用 rocprof 进行性能分析

ROCm提供了性能分析工具 rocprof 。安装开发工具包后,通常已经包含。你可以用它来收集GPU内核执行的硬件计数器数据。

# 首先,编译你的HIP程序时加上-g生成调试信息
hipcc -g test_hip.cpp -o test_hip_prof

# 使用rocprof进行基本分析
rocprof --stats ./test_hip_prof

这会输出内核的执行时间、占用率等统计信息。对于更复杂的分析,可以编写一个配置文件(如 config.xml )来指定要收集的计数器。

5.3 内存分配策略调整

对于需要频繁分配释放大量GPU内存的应用,默认的分配器可能不是最优的。ROCm支持使用“Pooled Memory Allocator”,可以通过环境变量启用:

export HIP_VISIBLE_DEVICES=0 # 如果有多卡,指定使用哪一张
export HIP_ENABLE_POOL_ALLOCATOR=1

这可以减少内存分配的开销,对于某些迭代式算法有性能提升。但需要注意,这可能会增加整体的内存占用量。

6. 与深度学习框架的集成测试

安装ROCm的最终目的,往往是为了运行像PyTorch或TensorFlow这样的深度学习框架。这是最后的验收测试。

6.1 安装PyTorch with ROCm

访问PyTorch官网,找到支持ROCm的安装命令。对于ROCm 6.0和Ubuntu 22.04,命令可能如下:

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.0

安装完成后,在Python中验证:

import torch
print(f"PyTorch version: {torch.__version__}")
print(f"Is ROCm available? {torch.cuda.is_available()}") # 注意:PyTorch for ROCm仍然使用cuda接口
print(f"ROCm device name: {torch.cuda.get_device_name(0)}")

如果 torch.cuda.is_available() 返回 True ,并且能正确打印出你的显卡名称,那么恭喜你,PyTorch已经成功识别并可以调用你的AMD GPU了。

6.2 可能遇到的问题及解决

  • PyTorch找不到GPU : 首先确保你的Python环境(虚拟环境)里安装的是ROCm版本的PyTorch,而不是CUDA版本。其次,运行 rocminfo 确认ROCm本身工作正常。最后,检查PyTorch的构建是否与你的ROCm版本完全匹配。
  • 运行模型时内存不足 : 检查GPU内存使用情况: rocm-smi 。确保你的模型大小没有超过显卡的显存容量。对于消费级显卡,可能需要调整模型的 batch_size
  • 性能不如预期 : 使用 rocm-smi 监控GPU利用率和功耗。确保你的代码确实在GPU上运行(使用 .to(‘cuda’) )。对于矩阵运算密集型任务,ROCm的 rocBLAS 等库已经高度优化,性能问题可能出在数据从CPU到GPU的传输(PCIe带宽)上,或者内核启动开销上。尝试增大每次计算的数据量以减少相对开销。

整个安装和调试过程,本质上是一个不断缩小问题范围的过程:从系统环境到内核驱动,从用户权限到运行时库,从基础测试到上层应用。把每一步的原理搞清楚,遇到报错时耐心查看日志信息,利用社区资源(如ROCm的GitHub Issues),大部分问题都能找到解决方案。这次在Ubuntu 22.04上部署ROCm 6.0的经历让我深刻体会到,在Linux系统上玩转硬件,除了按照教程操作,更需要对系统底层有一定的理解,这样才能在踩坑时知道该从哪里爬出来。

更多推荐