环境准备:NVIDIA驱动安装与验证、CUDA Toolkit与cuDNN部署、Docker与NVIDIA Container Toolkit配置

说实话,很多人在GPU集群上栽跟头,不是栽在算法上,而是栽在环境准备上。我见过太多团队,模型写好了,一上集群跑不起来,最后发现是驱动版本不对,或者CUDA和cuDNN没配对。嗯,这章我们就来把这些基础打牢。

核心要点:环境准备是GPU集群的基石。驱动、CUDA Toolkit、cuDNN、Docker与NVIDIA Container Toolkit,这四层必须像齿轮一样咬合紧密。任何一个版本错位,都会导致后续所有工作白费。

GPU集群环境准备四层架构 NVIDIA 驱动 nvidia-smi 验证 · 内核模块加载 CUDA Toolkit nvcc --version · 运行时库 cuDNN 深度学习加速库 · 版本匹配 Docker + NVIDIA Container Toolkit 容器化GPU资源隔离与调度 硬件层 工具链层 加速库层 部署层 推荐:535+ 系列 推荐:12.x 推荐:9.x 最新稳定版

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%的问题都能定位到。

可可精品资料库