1. 为什么 Tesla V100s 的驱动安装值得单独写一篇避坑指南
Tesla V100s 这张卡在二手市场和实验室环境里保有量不小,32GB HBM2 显存、4096 个 CUDA 核心,跑深度学习推理和中小规模训练依然能打。但它和普通 GeForce 卡不一样——它是数据中心卡,没有视频输出接口,驱动栈走的是 NVIDIA Data Center 分支,和消费级显卡的安装逻辑有本质区别。很多人在 Ubuntu 22.04 上装 GeForce 驱动那套流程直接套过来,结果就是nvidia-smi报 "No devices were found",或者内核模块nvidia.ko加载失败,卡在unable to load the kernel module nvidia.ko这个经典报错上。
这篇内容面向的是手里有 V100s、需要在 Ubuntu 22.04 上把驱动、CUDA 12.2、cuDNN 8.9.7 一次性配通的人。不管你是刚拿到卡的实验室新人,还是被驱动反复折磨过的老手,这里面的步骤和坑都是实测踩出来的。我会把每一步为什么这么做讲清楚,包括版本选择的依据、内核模块编译的机制、以及那些官方文档不会告诉你的细节。整套流程走完,你能得到一个nvidia-smi正常输出、nvcc -V显示 12.2、cuDNN 版本校验通过的可用环境。
先说结论性的版本搭配:Ubuntu 22.04 + 内核 5.15/6.2 + NVIDIA 驱动 535 系列 + CUDA 12.2 + cuDNN 8.9.7。这个组合是经过验证的稳定搭配,驱动 535 对 V100s 的 Volta 架构支持成熟,CUDA 12.2 是 12.x 系列里兼容性较好的版本,cuDNN 8.9.7 对应 CUDA 12.x 的运行时。下面拆开讲。
2. 安装前的环境确认与版本选型逻辑
2.1 先搞清楚你的卡到底认不认
拿到机器第一件事不是急着装驱动,而是确认系统能不能看到这张卡。V100s 是 PCIe 卡,插在服务器或工作站上,用lspci看:
lspci | grep -i nvidia正常应该输出类似3D controller: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB]的信息。如果这里什么都看不到,那问题在硬件层——卡没插好、PCIe 供电不足、或者 BIOS 里没识别。这种情况装再多驱动也没用,先解决物理连接。
如果lspci能看到但nvidia-smi报错,那才是驱动层的问题。还有一个容易被忽略的点:V100s 是被动散热(没有风扇),必须依赖服务器机箱的强制风冷。如果装在普通台式机里,开机几分钟卡就会过热降频甚至保护性关机,这个和驱动无关,但很多人第一次用数据中心卡会踩这个坑。
2.2 为什么选 535 驱动而不是最新版
NVIDIA 驱动版本和 GPU 架构之间有对应关系。V100s 是 Volta 架构(计算能力 7.0),属于比较老的一代。最新的 550、560 系列驱动虽然理论上向下兼容,但在实际部署中,新驱动对老架构的优化重心已经转移,偶尔会出现兼容性抖动。
535 系列是长期支持分支(LTSB),对 Volta 的支持经过了充分验证。你可以用 NVIDIA 官方的驱动查询页面确认,或者直接看这个对应关系:
| 驱动分支 | 类型 | 对 Volta 支持 | 推荐场景 |
|---|---|---|---|
| 535.xx | LTSB | 完整支持 | 生产环境首选 |
| 545.xx | 新特性分支 | 支持 | 需要新功能时 |
| 550.xx+ | 新特性分支 | 兼容但非重点 | 新卡优先 |
选 535 的另一个理由是它和 CUDA 12.2 的匹配度。CUDA 12.2 要求驱动版本 >= 535.54.03,535 系列刚好满足且不过度超前。
2.3 CUDA 12.2 与 cuDNN 8.9.7 的匹配关系
CUDA 和 cuDNN 的版本必须严格对应,这是新手最容易搞错的地方。cuDNN 8.9.7 是专门为 CUDA 12.x 编译的,具体来说它支持 CUDA 12.0 到 12.3。如果你装了 CUDA 11.8 却下 cuDNN 8.9.7,运行时会报找不到符号的链接错误。
版本对应表(针对 CUDA 12.x 系列):
| CUDA 版本 | 对应 cuDNN 版本 | 最低驱动要求 |
|---|---|---|
| 12.0 | 8.7.x - 8.9.x | 525.60.13 |
| 12.1 | 8.8.x - 8.9.x | 530.30.02 |
| 12.2 | 8.9.x | 535.54.03 |
| 12.3 | 8.9.x | 545.23.06 |
我选 12.2 是因为它在 12.x 系列里生态最成熟,PyTorch、TensorFlow 的预编译包覆盖最全。cuDNN 8.9.7 是 8.9 分支的较新版本,修了不少 8.9.0 的 bug。
注意:不要盲目追新去装 CUDA 13.0。V100s 的 Volta 架构在 CUDA 13 里已经被移出官方支持列表,装了大概率跑不起来。热词里有人问 "cuda version: 13.0 需要安装 pytorch 的版本",答案是 V100s 别碰 13.0。
3. 驱动安装的完整实操流程
3.1 清理旧驱动残留
这一步极其重要,尤其是之前装过驱动但失败的机器。残留的驱动文件会导致新驱动安装时内核模块冲突。先彻底清理:
# 卸载通过 apt 安装的 nvidia 驱动 sudo apt-get purge -y '^nvidia-.*' sudo apt-get purge -y '^libnvidia-.*' sudo apt-get autoremove -y # 卸载通过 runfile 安装的驱动(如果之前用过 .run 文件) sudo /usr/bin/nvidia-uninstall # 清理残留配置 sudo rm -rf /etc/X11/xorg.conf sudo rm -rf /etc/modprobe.d/nvidia-*.conf清理完重启一次,确保内核里没有加载任何 nvidia 模块:
lsmod | grep nvidia如果还有输出,说明模块还在内存里,重启后再查。这一步做完,lsmod | grep nvidia应该是空的。
3.2 禁用 nouveau 开源驱动
Ubuntu 默认会加载 nouveau 这个开源 NVIDIA 驱动,它和官方驱动冲突。必须禁用:
sudo bash -c "echo 'blacklist nouveau' >> /etc/modprobe.d/blacklist-nouveau.conf" sudo bash -c "echo 'options nouveau modeset=0' >> /etc/modprobe.d/blacklist-nouveau.conf" sudo update-initramfs -u然后重启。重启后验证 nouveau 是否真的被禁了:
lsmod | grep nouveau没有输出就对了。如果有输出,检查 blacklist 文件路径和内容是否正确。
3.3 安装编译依赖
驱动安装需要编译内核模块,所以 gcc、make、内核头文件必须齐全。这里有个坑:Ubuntu 22.04 默认的 gcc 版本是 11,而某些内核版本编译驱动时需要特定 gcc。先装基础依赖:
sudo apt update sudo apt install -y build-essential gcc make sudo apt install -y linux-headers-$(uname -r)linux-headers-$(uname -r)这个必须装,而且版本要和当前运行的内核完全一致。如果报 "Unable to locate package",说明你的内核版本没有对应的 headers 包,可能是内核被升级过但没重启。用uname -r确认当前内核,然后sudo apt install linux-headers-generic装通用版本。
实操心得:如果之前手动升级过内核,
uname -r显示的和/usr/src/下的 headers 目录可能对不上。这种情况要么重启到有 headers 的内核,要么重新装对应版本的 headers。我遇到过ubuntu安装gcc失败的情况,多半是 apt 源有问题,换清华或阿里源再试。
3.4 用 apt 安装 535 驱动
Ubuntu 22.04 的官方源里就有 535 驱动,直接装最省事:
sudo apt install -y nvidia-driver-535-server注意这里装的是nvidia-driver-535-server,不是nvidia-driver-535。带-server后缀的是数据中心版本,针对 Tesla 卡优化,包含nvidia-fabricmanager等数据中心组件。普通版本虽然也能用,但 server 版更匹配 V100s 的定位。
安装过程会编译内核模块,耐心等几分钟。装完重启:
sudo reboot3.5 验证驱动安装结果
重启后第一件事:
nvidia-smi正常输出应该显示 V100s 的型号、32GB 显存、驱动版本 535.xx、CUDA Version 12.2(这里的 CUDA Version 是驱动支持的最高 CUDA 版本,不是你装的 CUDA 工具包版本)。
如果报NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver,说明内核模块没加载。排查步骤:
# 检查模块是否编译成功 ls /lib/modules/$(uname -r)/kernel/drivers/video/nvidia/ # 手动加载模块看报错 sudo modprobe nvidia # 查看内核日志 dmesg | grep -i nvidia | tail -20最常见的报错是unable to load the kernel module nvidia.ko,原因通常是:
- 内核 headers 版本不匹配
- Secure Boot 没关(BIOS 里关掉)
- 之前 nouveau 没禁干净
Secure Boot 这个坑特别隐蔽,Ubuntu 22.04 默认可能开着 Secure Boot,它会阻止未签名的内核模块加载。进 BIOS 关掉 Secure Boot,或者给模块签名(麻烦,不推荐)。
4. CUDA 12.2 与 cuDNN 8.9.7 的部署细节
4.1 CUDA 12.2 的安装方式选择
CUDA 有三种装法:runfile、deb 本地包、deb 网络包。我推荐deb 本地包,原因是它走 apt 管理,卸载干净,不会像 runfile 那样把文件散落到各处。
去 NVIDIA 官网下载 CUDA 12.2 的 deb 本地包,文件名类似cuda-repo-ubuntu2204-12-2-local_12.2.2-535.104.05-1_amd64.deb。下载后:
sudo dpkg -i cuda-repo-ubuntu2204-12-2-local_12.2.2-535.104.05-1_amd64.deb sudo cp /var/cuda-repo-ubuntu2204-12-2-local/cuda-*-keyring.gpg /usr/share/keyrings/ sudo apt update sudo apt install -y cuda-toolkit-12-2注意装的是cuda-toolkit-12-2而不是cuda。cuda这个元包会连带装驱动,可能覆盖你刚装好的 535 驱动。cuda-toolkit只装工具链,不动驱动。
4.2 环境变量配置
装完 CUDA 后要配环境变量。编辑~/.bashrc:
export PATH=/usr/local/cuda-12.2/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH export CUDA_HOME=/usr/local/cuda-12.2然后source ~/.bashrc。验证:
nvcc -V应该输出Cuda compilation tools, release 12.2, V12.2.xxx。
注意:
ubuntu环境变量配置错误是个高频问题。常见错误是把LD_LIBRARY_PATH写成了LD_LIBRARY_PATH=(覆盖而非追加),导致系统库找不到。一定要用:$LD_LIBRARY_PATH追加。
4.3 cuDNN 8.9.7 的安装
cuDNN 现在需要登录 NVIDIA 开发者账号才能下载。下载cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz这个包,然后手动复制文件:
tar -xvf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz cd cudnn-linux-x86_64-8.9.7.29_cuda12-archive sudo cp include/cudnn*.h /usr/local/cuda-12.2/include/ sudo cp lib/libcudnn* /usr/local/cuda-12.2/lib64/ sudo chmod a+r /usr/local/cuda-12.2/include/cudnn*.h sudo chmod a+r /usr/local/cuda-12.2/lib64/libcudnn*验证 cuDNN 版本:
cat /usr/local/cuda-12.2/include/cudnn_version.h | grep CUDNN_MAJOR -A 2应该看到CUDNN_MAJOR 8、CUDNN_MINOR 9、CUDNN_PATCHLEVEL 7。
热词里有人遇到
cuda gzip: stdin: invalid compressed>cd /usr/local/cuda-12.2/samples/1_Utilities/deviceQuery sudo make ./deviceQuery输出里应该能看到
Detected 1 CUDA Capable device(s),设备名Tesla V100S-PCIE-32GB,CUDA Capability Major/Minor version number: 7.0。这个测试同时验证了驱动、CUDA 运行时、编译器的连通性。5. 常见报错与排查速查
5.1 驱动层报错
报错信息 根本原因 解决方法 No devices were found驱动没加载或卡未识别 检查 lspci,重装驱动unable to load the kernel module nvidia.ko内核模块编译失败 装对应内核 headers,关 Secure Boot Driver/library version mismatch驱动版本和运行库不一致 重启,或重装驱动 nvidia-smi命令找不到驱动没装成功 检查 apt 安装日志 5.2 CUDA 层报错
nvcc: command not found是环境变量没配好,检查PATH里有没有/usr/local/cuda-12.2/bin。cuda安装指令安装不了多半是 apt 源没更新,或者 deb 包的 keyring 没导入。
CUDA error: no kernel image is available for execution这个报错说明编译时的计算能力和 GPU 不匹配。V100s 是 sm_70,编译时要指定-arch=sm_70或者-gencode arch=compute_70,code=sm_70。5.3 cuDNN 层报错
libcudnn.so.8: cannot open shared object file是库路径问题,确认/usr/local/cuda-12.2/lib64在LD_LIBRARY_PATH里,且ldconfig已更新:sudo ldconfig
cuDNN version mismatch说明装的 cuDNN 和 CUDA 版本不对应,回到 2.3 节的对应表重新选版本。5.4 独家避坑技巧
技巧一:用 Docker 隔离环境。如果宿主机驱动已经装好,深度学习框架全部跑在容器里,能避免 90% 的依赖冲突。NVIDIA Container Toolkit 装好后,
docker run --gpus all直接透传 GPU。热词里ubuntu安装docker和wsl2安装cuda的需求,用容器方案最省心。技巧二:记录每次变更。驱动、CUDA、cuDNN 的版本组合很容易搞混。我习惯在
/etc/nvidia-version.txt里记下当前所有版本号,出问题时对照排查。技巧三:内核升级后要重装驱动。Ubuntu 自动更新内核后,原来的 nvidia 模块对新内核不生效,
nvidia-smi会突然失效。这时候sudo apt install --reinstall nvidia-driver-535-server重新编译模块即可。热词里nvidia显卡驱动丢失无法重装多半是这个原因。技巧四:V100s 的持久化模式。数据中心卡建议开启 persistence mode,减少每次调用时的初始化开销:
sudo nvidia-smi -pm 1这个设置重启后会失效,可以写进 systemd 服务里持久化。
6. 装完之后该验证什么
环境配好只是开始,真正要确认的是深度学习框架能不能用上 GPU。装 PyTorch 时注意选 CUDA 12.2 对应的版本:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121注意 PyTorch 官方对 CUDA 12.2 的支持是通过 cu121 的 wheel 包实现的,12.1 和 12.2 的 ABI 兼容。装完验证:
import torch print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0)) print(torch.version.cuda)三个输出分别是
True、Tesla V100S-PCIE-32GB、12.1(PyTorch 内部标记为 12.1,但实际兼容 12.2 运行时)。如果
torch.cuda.is_available()返回 False,先确认nvidia-smi正常,再检查 PyTorch 版本和 CUDA 版本是否匹配。conda cuda 11.7 cudnn这种混搭是常见错误来源,conda 环境里的 cudatoolkit 和系统 CUDA 是两套东西,别搞混。我在实际部署中体会最深的一点是:V100s 这套环境一旦配通,稳定性非常好,连续跑几周训练不用重启。但初次配置的坑确实多,尤其是驱动和内核的配合。把版本锁死、记录清楚、用容器隔离,后面就省心了。最后分享一个小技巧,如果实验室有多台同配置机器,配好一台后用
dpkg --get-selections导出软件包列表,其他机器直接导入,能省大量重复劳动。