
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 update3. 处理潜在的内核模块冲突重启系统在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-devlinux-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 [archamd64 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更规范。指定[archamd64]确保只获取对应架构的包。2. 设置优先级可选但重要为了避免ROCm的包与Ubuntu主仓库中的一些低版本库如libstdc发生冲突可以设置一个较低的优先级让系统优先使用Ubuntu官方仓库的版本除非ROCm仓库的包版本更高。创建文件/etc/apt/preferences.d/rocm-pin-600Package: * Pin: release orepo.radeon.com Pin-Priority: 600Pin-Priority: 600是一个较低的优先级默认是500Ubuntu主仓库是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 $LOGNAMErender和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 常见故障与深度排查实录在实际操作中你很可能会遇到各种错误。下面是我遇到过的几个典型问题及其解决方案。问题1rocminfo命令报错 “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_support0 radeon.cik_support0 amdgpu.si_support1 amdgpu.cik_support1针对GCN 1.0/1.1架构的旧卡新卡一般不需要。然后运行sudo update-grub并重启。问题2编译HIP程序时出现“undefined reference tostd::xxx”等链接错误这通常是C标准库链接问题。HIP编译器hipcc是一个包装脚本它最终会调用底层的Clang或GCC。有时环境中的G版本不匹配会导致问题。解决方案明确指定C标准库。在编译命令中加上-stdliblibstdchipcc test_hip.cpp -o test_hip -stdliblibstdc或者确保你的系统安装了完整版本的Gsudo apt install g-11Ubuntu 22.04默认是g-11问题3运行程序时出现“error: hipErrorNoDevice”这个错误明确表示没有找到可用的HIP设备。这又回到了rocminfo的问题。请按照问题1的步骤仔细排查内核模块、固件和权限。问题4sudo apt install rocm-hip-sdk时出现依赖冲突这通常是因为系统中存在不兼容的库版本或者之前残留的包没有清理干净。解决方案尝试使用apt的-ffix broken选项来修复依赖sudo apt install -f如果不行可以尝试更激进的清理并指定安装版本# 模拟安装查看具体冲突的包 sudo apt install -s rocm-hip-sdk # 根据输出手动尝试移除或降级冲突的包 sudo apt remove 冲突的包名 # 或者尝试安装特定版本的ROCm元包 sudo apt install rocm-hip-sdk6.0.0.60000-63~22.04版本号可以通过apt-cache policy rocm-hip-sdk查看。5. 进阶配置与性能调优要点当基础功能验证通过后为了获得更好的稳定性和性能可以进行一些进阶配置。5.1 配置HSA异构系统架构覆盖层对于多GPU系统或者为了更精细地控制GPU可见性可以配置HSA_OVERRIDE_GFX_VERSION环境变量。例如如果你有一张RX 7900 XTXGFX1100架构但ROCm默认可能没有为你的特定型号优化可以强制指定架构export HSA_OVERRIDE_GFX_VERSION11.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_DEVICES0 # 如果有多卡指定使用哪一张 export HIP_ENABLE_POOL_ALLOCATOR1这可以减少内存分配的开销对于某些迭代式算法有性能提升。但需要注意这可能会增加整体的内存占用量。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(fPyTorch version: {torch.__version__}) print(fIs ROCm available? {torch.cuda.is_available()}) # 注意PyTorch for ROCm仍然使用cuda接口 print(fROCm 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系统上玩转硬件除了按照教程操作更需要对系统底层有一定的理解这样才能在踩坑时知道该从哪里爬出来。