3. CUDA 环境搭建:驱动安装、CUDA Toolkit、cuDNN 配置、环境变量设置与验证
搞 GPU 加速训练,第一步就是搭好 CUDA 环境。这一步要是没踩踏实,后面跑模型时会蹦出各种莫名其妙的问题——"CUDA error: out of memory"、"libcudnn.so.8 cannot open"…… 我自己刚入行那年就吃过这亏,折腾了两天才发现是环境变量配错了。今天把这套流程拆开讲清楚,你照着走一遍,基本不会翻车。
3.1 整体流程概览
搭建顺序其实有讲究:先装驱动,再装 CUDA Toolkit,然后配 cuDNN,最后设环境变量并验证。顺序反了可能互不兼容。我习惯先把整个链路画出来,心里有个底。
3.2 驱动安装
先说显卡驱动。你得先确定自己显卡型号在哪个驱动版本下能跑。NVIDIA 官网有一个 驱动兼容性矩阵,查一下就行。我个人习惯直接用 nvidia-smi 看当前驱动信息——如果已经装过且版本够新,就可以跳过这步。
安装步骤(以 Ubuntu 20.04 为例):
# 先卸载旧驱动(如果有)
sudo apt purge nvidia-*
sudo apt autoremove
# 添加 NVIDIA 官方驱动源
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
# 查看推荐版本
ubuntu-drivers devices
# 安装推荐驱动(比如 545)
sudo apt install nvidia-driver-545
# 重启
sudo reboot
# 验证
nvidia-smi
警告:千万不要用 Ubuntu 自带的 Nouveau 开源驱动跑 CUDA。它不支持 CUDA 运行时。安装前可以先禁用 Nouveau:sudo vim /etc/modprobe.d/blacklist-nouveau.conf,加上 blacklist nouveau 和 options nouveau modeset=0。
驱动版本与 CUDA Toolkit 版本的对应关系(常见组合):
| CUDA Toolkit 版本 | 最低驱动版本 (Linux x86_64) | 推荐驱动版本 |
|---|---|---|
| 12.3 | 545.23.08 | 550.x |
| 12.1 | 530.30.02 | 535.x |
| 11.8 | 520.61.05 | 525.x |
| 11.3 | 465.19.01 | 470.x |
嗯,这里要注意:驱动版本 向下兼容,但绝对不能低于最小要求。我曾经在项目里装了个 470 的驱动,结果 CUDA 11.8 怎么都识别不到设备——查了半天才发现最低要 520。你想想看,一个版本踩坑就浪费半天。
3.3 CUDA Toolkit 安装
驱动装好之后,到 NVIDIA Developer 官网 下载 CUDA Toolkit。现在主流版本是 12.x,但我推荐你根据框架(PyTorch / TensorFlow)的官方兼容性来选。比如 PyTorch 2.1 官方推荐 CUDA 12.1。
安装方式推荐用 runfile(本地安装),最可控:
wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run
sudo sh cuda_12.1.1_530.30.02_linux.run
安装过程中它会问要不要安装驱动——因为我们已经装好了,所以 取消驱动选项,只选 CUDA Toolkit、CUDA Samples 和 CUDA Documentation。装完后默认路径在 /usr/local/cuda-12.1。
我个人习惯建一个软链接让路径更干净:
sudo ln -s /usr/local/cuda-12.1 /usr/local/cuda
技巧:如果你的服务器上同时有多版本 CUDA(比如既有 11.8 又有 12.1),可以通过切换软链接来快速切换环境,不用每次都重新装。
3.4 cuDNN 配置
cuDNN 是 NVIDIA 的深度神经网络加速库。没有它,卷积、池化这些操作就跑在纯 CUDA 上,慢得要命。装 cuDNN 本质上就是 把几个 .so 和 .h 文件放到 CUDA 目录里。
操作步骤:
- 从 NVIDIA Developer 官网下载对应 CUDA 12.1 的 cuDNN(需要注册账号)。
- 下载下来的文件是
cudnn-linux-x86_64-8.9.4.25_cuda12-archive.tar.xz。 - 解压后复制文件到 CUDA 目录。
tar -xvf cudnn-linux-x86_64-8.9.4.25_cuda12-archive.tar.xz
sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-12.1/include
sudo cp cudnn-*-archive/lib/libcudnn* /usr/local/cuda-12.1/lib64
sudo chmod a+r /usr/local/cuda-12.1/include/cudnn*.h /usr/local/cuda-12.1/lib64/libcudnn*
顺带说一句,cuDNN 版本号要跟 CUDA Toolkit 匹配,否则编译时会提示符号找不到。我已经在项目中见过有人把 cuDNN 8.6 和 CUDA 12.1 混用,一跑 import torch 直接段错误。
3.5 环境变量设置
装好了,但系统并不知道 cuda 的 bin 和 lib 在哪儿。需要把路径加到 ~/.bashrc(或 ~/.zshrc)里。
# 打开配置文件
vim ~/.bashrc
# 在末尾添加
export CUDA_HOME=/usr/local/cuda-12.1
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
export LIBRARY_PATH=$CUDA_HOME/lib64:$LIBRARY_PATH
export C_INCLUDE_PATH=$CUDA_HOME/include:$C_INCLUDE_PATH
# 生效
source ~/.bashrc
注意:如果你通过 apt 安装的 CUDA Toolkit,环境变量可能不会被自动设置。我建议手动写上去,不要依赖系统自动配置。
对了,LD_LIBRARY_PATH 这个变量在有些发行版(比如 Ubuntu 22.04)上可能被安全策略限制——如果运行程序时提示 cannot open shared object file,可以试试把 /usr/local/cuda-12.1/lib64 添加到 /etc/ld.so.conf.d/cuda.conf 然后执行 sudo ldconfig。这招我用了很多次,屡试不爽。
3.6 验证环境
配好环境变量之后,不要急着跑大模型。先做三个简单验证,确认每一层都通了。
验证 1:nvidia-smi 正常
nvidia-smi
# 输出类似:
# +-----------------------------------------------------------------------------+
# | NVIDIA-SMI 545.23.08 Driver Version: 545.23.08 CUDA Version: 12.3 |
# |-------------------------------+----------------------+----------------------+
# | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
# | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
# | 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 |
# | N/A 56C P0 30W / 70W | 12MiB / 15360MiB | 0% Default |
# +-------------------------------+----------------------+----------------------+
看第一行的 CUDA Version 显示的版本号要 ≥ 你实际安装的 CUDA Toolkit 版本。比如你装了 12.1,这里显示 12.1 或 12.3 都行(驱动兼容性够就好)。
验证 2:nvcc 编译器正常
nvcc --version
# 输出:
# nvcc: NVIDIA (R) Cuda compiler driver
# Copyright (c) 2005-2023 NVIDIA Corporation
# Built on Fri_Dec_8_17:40:44_PST_2023
# Cuda compilation tools, release 12.1, V12.1.105
如果提示 nvcc: command not found,说明 PATH 没配好,回去检查 ~/.bashrc。
验证 3:编译并运行 deviceQuery 示例
cd /usr/local/cuda-12.1/samples/1_Utilities/deviceQuery
sudo make
./deviceQuery
成功的话末尾会显示 Result = PASS。如果失败,看报错信息——多半是 cuDNN 复制不全或环境变量漏了。
警告:如果你是在 Docker 容器里做训练,宿主机上只需要装驱动,容器内可以安装 CUDA Toolkit + cuDNN。但 nvidia-smi 必须在宿主机上验证通过。
3.7 常见踩坑与排查思路
最后分享几个我亲自碰过的血泪教训,你直接保存下来当排查清单。
- nvidia-smi 不显示 GPU:驱动没装好或 Nouveau 没禁用。重启后运行
lsmod | grep nouveau,如果还有输出说明没禁干净。 - nvcc 版本与驱动显示的 CUDA Version 不一致:正常。驱动显示的是驱动支持的最高 CUDA 版本,不代表实际安装了 Toolkit。只要 nvcc 版本是你要用的就行。
- import torch 报 CUDA error: no kernel image:大概率是 PyTorch 编译时用的 CUDA 版本和系统实际的 CUDA 版本不匹配。我曾经用 pip 装了的
torch是 CUDA 11.8 版本,但系统里是 CUDA 12.1,跑起来就报这个错。解决办法:用pip install torch==2.1.0 --index-url https://download.pytorch.org/whl/cu121指定对应版本。 - 链接库找不到 libcublas.so.11:查一下
/usr/local/cuda/lib64里有没有这个文件。没有的话,可能是 cuDNN 拷贝时漏了,或者版本号不对。重新执行 cuDNN 复制步骤,并运行sudo ldconfig。
好的,CUDA 环境搭建这块就到这儿。你按这个顺序走一遍,驱动、Toolkit、cuDNN、环境变量、验证,每一步都能拿到明确的结果。配好之后,下一部分就可以开始写真正的 CUDA 加速代码了。