环境准备:NVIDIA驱动安装与验证、CUDA Toolkit与cuDNN部署、Docker与NVIDIA Container Toolkit配置
说实话,很多人在GPU集群上栽跟头,不是栽在算法上,而是栽在环境准备上。我见过太多团队,模型写好了,一上集群跑不起来,最后发现是驱动版本不对,或者CUDA和cuDNN没配对。嗯,这章我们就来把这些基础打牢。
核心要点:环境准备是GPU集群的基石。驱动、CUDA Toolkit、cuDNN、Docker与NVIDIA Container Toolkit,这四层必须像齿轮一样咬合紧密。任何一个版本错位,都会导致后续所有工作白费。
1. NVIDIA驱动安装与验证
驱动是GPU和操作系统之间的翻译官。没有它,你的显卡就是一块昂贵的散热器。我个人习惯在装驱动前,先确认GPU型号和操作系统版本。
第一步:检查硬件
# 查看GPU型号
lspci | grep -i nvidia
# 或者用更直观的方式
nvidia-smi # 如果已经装了驱动
如果是新机器,大概率还没装驱动。这时候lspci是你的好朋友。我在项目中遇到过,有人拿A100的机器装了T4的驱动,结果性能大打折扣。所以,先看清楚型号。
第二步:安装驱动
我推荐两种方式:
- 官方runfile安装:最干净,但需要手动处理nouveau冲突
- 包管理器安装:方便,但版本可能不是最新的
# 方式一:runfile安装(推荐)
# 先禁用nouveau
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist.conf
update-initramfs -u
reboot
# 安装驱动
chmod +x NVIDIA-Linux-x86_64-535.154.05.run
./NVIDIA-Linux-x86_64-535.154.05.run
# 方式二:Ubuntu包管理器
apt install nvidia-driver-535
注意:runfile安装时,如果提示"Unable to find the kernel source tree",说明缺少内核头文件。执行 apt install linux-headers-$(uname -r) 即可解决。我曾经在这上面浪费过半小时,后来学乖了,装驱动前先装好内核头文件。
第三步:验证驱动
# 最直接的验证
nvidia-smi
# 输出示例
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 535.154.05 Driver Version: 535.154.05 CUDA Version: 12.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 NVIDIA A100-SXM... On | 00000000:00:04.0 Off | 0 |
| 0% 35C P0 55W / 400W| 0MiB / 40960MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
看到这个输出,说明驱动装好了。注意看右上角的"CUDA Version",这只是驱动支持的CUDA版本,不代表你已经装了CUDA Toolkit。嗯,很多人在这里被误导过。
2. CUDA Toolkit与cuDNN部署
驱动装好了,接下来是CUDA Toolkit。说白了,CUDA Toolkit就是NVIDIA给开发者准备的一套工具链,包括编译器、运行时库、调试工具等。
CUDA Toolkit安装
我个人建议用runfile安装,因为可以自定义安装路径,方便多版本共存。
# 下载CUDA 12.2 runfile
wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run
# 执行安装
sh cuda_12.2.0_535.54.03_linux.run
# 安装时注意:
# - 不要安装驱动(已经装过了)
# - 选择自定义安装路径,比如 /usr/local/cuda-12.2
配置环境变量
# 添加到 ~/.bashrc 或 /etc/profile
export PATH=/usr/local/cuda-12.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH
# 生效
source ~/.bashrc
验证CUDA Toolkit
# 查看CUDA版本
nvcc --version
# 输出示例
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Tue_Jun_13_19:16:58_PDT_2023
Cuda compilation tools, release 12.2, V12.2.140
小技巧:如果 nvcc --version 报错,但 nvidia-smi 正常,说明PATH没配好。检查一下 which nvcc 能不能找到。我习惯在装完CUDA后,马上跑一个 deviceQuery 示例程序来验证。
# 编译并运行deviceQuery
cd /usr/local/cuda-12.2/samples/1_Utilities/deviceQuery
make
./deviceQuery
# 看到 "PASS" 字样,说明CUDA Toolkit工作正常
cuDNN部署
cuDNN是深度学习专用的加速库。注意,它需要和CUDA版本严格匹配。我见过有人把cuDNN 9.0配到CUDA 11.x上,结果训练时各种诡异错误。
# 下载cuDNN(需要NVIDIA开发者账号)
# 下载后解压
tar -xzvf cudnn-linux-x86_64-9.0.0.312_cuda12-archive.tar.xz
# 复制到CUDA目录
cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-12.2/include/
cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda-12.2/lib64/
# 设置权限
chmod a+r /usr/local/cuda-12.2/include/cudnn*.h
chmod a+r /usr/local/cuda-12.2/lib64/libcudnn*
验证cuDNN
# 查看cuDNN版本
cat /usr/local/cuda-12.2/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
# 输出示例
#define CUDNN_MAJOR 9
#define CUDNN_MINOR 0
#define CUDNN_PATCHLEVEL 0
3. Docker与NVIDIA Container Toolkit配置
终于到了容器化这一步。为什么要用Docker?说白了,就是为了环境隔离和快速部署。你想想看,一个团队10个人,每个人装不同的CUDA版本,机器上乱成一锅粥。用Docker,每个人一个容器,互不干扰。
安装Docker
# Ubuntu上安装Docker
apt update
apt install docker.io
# 启动并设置开机自启
systemctl start docker
systemctl enable docker
# 验证
docker --version
安装NVIDIA Container Toolkit
这个工具的作用,就是让Docker容器能访问宿主机的GPU。没有它,容器里是看不到GPU的。
# 添加NVIDIA容器工具包仓库
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list
# 安装
apt update
apt install nvidia-container-toolkit
# 重启Docker
systemctl restart docker
验证GPU容器
# 运行一个测试容器
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
# 如果看到nvidia-smi输出,说明一切正常
关键配置:Docker的默认运行时需要改成nvidia。编辑 /etc/docker/daemon.json,添加:
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
}
}
然后重启Docker:systemctl restart docker
避坑指南:我曾经遇到过一个问题——容器里能识别GPU,但跑深度学习模型时特别慢。后来发现是 --gpus all 把所有GPU都分配给了容器,但容器里的进程只用了其中一个。正确的做法是用 --gpus '"device=0,1"' 精确指定。嗯,这个坑我踩过,你们就别踩了。
日常使用小技巧
- 用
docker run --gpus all -it --rm nvidia/cuda:12.2.0-devel-ubuntu22.04 bash进入开发容器 - 用
nvidia-smi监控GPU使用情况,结合watch -n 1 nvidia-smi实时查看 - 多版本CUDA共存时,用Docker镜像隔离,比在宿主机上折腾环境变量省心多了
好了,环境准备这块就这些。驱动、CUDA Toolkit、cuDNN、Docker,一层层搭起来,就像盖房子一样,地基要稳。下次遇到环境问题,先检查这四层,90%的问题都能定位到。