4. 环境准备与部署

好,咱们进入实战前的第一道硬菜——环境搭建。

说实话,我见过太多同学在压测时翻车,最后发现是环境没配好。驱动版本不对、CUDA 和 cuDNN 打架、NCCL 通信死活起不来……这些坑我都踩过。今天我把一套经过多次验证的流程分享给你,照着做,能省下不少调试时间。

4.1 整体环境概览

先看一张图,理清各组件的关系:

GPU 集群压测环境组件关系图 硬件层:NVIDIA GPU(A100/H100/4090 等) 物理 GPU、NVLink、PCIe、网卡(IB/RoCE) NVIDIA 驱动(Kernel Module + User-Space Library) nvidia-smi、nvidia-ml、libnvidia-ml.so CUDA Toolkit(nvcc、cuda runtime、cublas、cudart) /usr/local/cuda、LD_LIBRARY_PATH、PATH cuDNN(深度学习加速) 卷积、RNN、注意力机制优化 NCCL(多卡通信库) AllReduce、Broadcast、Ring 算法 Docker + NVIDIA Container Toolkit(运行时容器化)

从上到下,一层依赖一层。驱动是地基,CUDA 是桥梁,cuDNN 和 NCCL 是加速引擎,Docker 是打包工具。哪个环节出问题,压测都跑不起来。

4.2 NVIDIA 驱动安装与验证

我个人习惯用 runfile 方式安装驱动,而不是系统包管理器。为什么?因为包管理器经常给你装一个旧版本,或者跟内核模块冲突。

4.2.1 检查当前环境

# 查看 GPU 型号和驱动信息
lspci | grep -i nvidia
nvidia-smi

# 如果 nvidia-smi 报错,说明驱动没装或内核模块没加载
# 查看内核模块
lsmod | grep nvidia

我在项目中遇到过一台机器,nvidia-smi 能显示 GPU 但显存为 0。折腾半天发现是驱动版本太老,不支持新卡。所以,第一步先确认驱动版本。

4.2.2 安装驱动

# 1. 卸载旧驱动(如果有)
sudo apt-get purge nvidia-* -y
sudo apt-get autoremove -y

# 2. 禁用 Nouveau 开源驱动
echo "blacklist nouveau" | sudo tee /etc/modprobe.d/blacklist-nvidia-nouveau.conf
echo "options nouveau modeset=0" | sudo tee -a /etc/modprobe.d/blacklist-nvidia-nouveau.conf
sudo update-initramfs -u

# 3. 重启后安装 runfile
chmod +x NVIDIA-Linux-x86_64-*.run
sudo ./NVIDIA-Linux-x86_64-*.run --dkms --no-opengl-files

# 4. 验证
nvidia-smi
⚠️ 注意: 安装时加上 --no-opengl-files,避免跟桌面环境的 OpenGL 库冲突。如果你在服务器上装,这一步尤其重要。

4.2.3 驱动版本选择建议

GPU 型号 推荐驱动版本 最低要求
A100 / H100 ≥ 525.60.13 470.82.01
V100 ≥ 470.82.01 418.87.01
RTX 4090 ≥ 525.60.13 525.60.13

嗯,这里要注意:驱动版本不是越新越好。我见过有人装 550 版本,结果跟某个老 CUDA 程序不兼容。建议先查一下你要跑的框架(PyTorch/TensorFlow)官方推荐的驱动版本。

4.3 CUDA Toolkit 安装

CUDA 说白了就是 NVIDIA 给 GPU 编程用的工具链。包括编译器 nvcc、运行时库、数学库等。

4.3.1 安装方式

我推荐用 runfile 安装,这样你可以控制安装路径,方便多版本共存。

# 下载 CUDA 12.1 runfile
wget https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run

# 执行安装(不要装驱动,只装 toolkit)
sudo sh cuda_12.1.0_530.30.02_linux.run --toolkit --silent --override

# 设置环境变量
echo 'export PATH=/usr/local/cuda-12.1/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc

# 验证
nvcc --version
💡 小技巧: 如果你需要多个 CUDA 版本,用 update-alternatives 管理软链接。我习惯把 /usr/local/cuda 指向当前使用的版本。

4.3.2 验证 CUDA 功能

# 编译并运行 deviceQuery 示例
cd /usr/local/cuda-12.1/samples/1_Utilities/deviceQuery
make
./deviceQuery

# 输出应该显示 GPU 型号、计算能力、显存等信息
# 如果报错 "no CUDA-capable device",检查驱动和 CUDA 版本是否匹配

我曾经在调试一个集群时,deviceQuery 能通过,但跑训练就崩。后来发现是 CUDA 版本跟 cuDNN 不匹配。所以,验证要分两步:先验证 CUDA 本身,再验证跟 cuDNN 的配合。

4.4 cuDNN 安装与验证

cuDNN 是 NVIDIA 针对深度学习场景优化的加速库。说白了,卷积、池化、归一化这些操作,用 cuDNN 比手写快 10 倍以上。

4.4.1 安装步骤

# 下载 cuDNN(需要 NVIDIA 开发者账号)
# 选择对应 CUDA 12.1 的版本:cuDNN v8.9.0 for CUDA 12.x

# 解压并复制到 CUDA 目录
tar -xzvf cudnn-linux-x86_64-8.9.0.131_cuda12-archive.tar.xz
sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-12.1/include/
sudo cp -P 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*

# 验证版本
cat /usr/local/cuda-12.1/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

4.4.2 验证 cuDNN 功能

# 编译 cuDNN 示例
cp -r /usr/src/cudnn_samples_v8/ $HOME
cd $HOME/cudnn_samples_v8/mnistCUDNN
make clean && make
./mnistCUDNN

# 输出 "Test passed!" 表示成功
🔑 关键点: cuDNN 版本必须跟 CUDA 版本严格对应。比如 CUDA 12.1 只能用 cuDNN 8.9.x 或 9.x 的对应版本。混用会导致运行时崩溃。

4.5 NCCL 安装与验证

NCCL 是多 GPU 通信的命脉。压测时,AllReduce 的性能直接决定了训练速度。

4.5.1 安装 NCCL

# 方法一:使用 NVIDIA 官方 apt 源(推荐)
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/3bf863cc.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/ /"
sudo apt-get update
sudo apt-get install libnccl2 libnccl-dev

# 方法二:下载 deb 包手动安装
wget https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2204/x86_64/libnccl2_2.18.3-1+cuda12.1_amd64.deb
sudo dpkg -i libnccl2_2.18.3-1+cuda12.1_amd64.deb

4.5.2 验证 NCCL

# 编译 NCCL 测试工具
git clone https://github.com/NVIDIA/nccl-tests.git
cd nccl-tests
make

# 单机 8 卡 AllReduce 测试
./build/all_reduce_perf -b 8 -e 128M -f 2 -g 8

# 输出示例:
# # nThread 1 nGpus 8 minBytes 8 maxBytes 134217728 step: 2(factor)
# # Bus bandwidth: 600 GB/s (理想值取决于 NVLink 带宽)
⚠️ 注意: 如果测试结果远低于理论带宽(比如 A100 NVLink 理论 600 GB/s,你只测到 200 GB/s),检查:
  • NVLink 是否启用(nvidia-smi topo -m)
  • 网卡是否绑定到正确的 NUMA 节点
  • NCCL 环境变量是否设置(如 NCCL_IB_DISABLE=0)

4.6 Docker + NVIDIA Container Toolkit 配置

容器化部署是集群压测的标配。为什么?因为你可以把环境打包好,分发到所有节点,保证一致性。

4.6.1 安装 Docker

# 安装 Docker Engine
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 将当前用户加入 docker 组(避免每次 sudo)
sudo usermod -aG docker $USER
newgrp docker

# 验证
docker run hello-world

4.6.2 安装 NVIDIA Container Toolkit

# 添加 NVIDIA 容器运行时源
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# 配置 Docker 使用 NVIDIA 运行时
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

# 验证 GPU 是否能在容器内使用
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
💡 个人经验: 如果 --gpus all 报错,检查 /etc/docker/daemon.json 是否包含 "runtimes": {"nvidia": ...}。我曾经因为配置文件格式错误,折腾了半小时。

4.6.3 多节点容器通信配置

# 创建 Docker 网络(用于多节点通信)
docker network create --driver bridge --subnet=172.18.0.0/16 gpu-net

# 启动容器时指定网络和共享内存
docker run --gpus all --network gpu-net --shm-size=32g \
  -v /mnt/data:/data \
  -it nvidia/cuda:12.1.0-devel-ubuntu22.04 bash

# 在容器内验证 NCCL 通信
# 安装 nccl-tests 后运行多节点测试

4.7 环境验证清单

最后,我整理了一个检查清单。每次搭建新集群,我都会跑一遍:

检查项 命令 预期结果
驱动版本 nvidia-smi 显示 GPU 型号、驱动版本、CUDA 版本
CUDA 编译器 nvcc --version 显示 CUDA 版本号
cuDNN 版本 cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR 显示主版本号
NCCL 版本 dpkg -l | grep nccl 显示 libnccl2 版本
容器 GPU 访问 docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi 容器内显示 GPU 信息
多卡通信 ./build/all_reduce_perf -b 8 -e 128M -f 2 -g 8 带宽接近理论值

嗯,这套流程我用了两年,在十几个集群上验证过。只要按步骤来,基本不会出大问题。如果遇到奇怪的现象,先检查驱动和 CUDA 的版本匹配,这是 80% 问题的根源。

环境准备好后,下一章咱们就开始真正的压测了。到时候你会感谢今天花时间把环境配好的自己。

📌 总结: 环境准备是压测的基石。驱动、CUDA、cuDNN、NCCL 四者版本必须匹配,Docker 容器化能保证环境一致性。花 1 小时配环境,省 10 小时排错。