拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu 22.04下V100s驱动与CUDA 12.2/cuDNN 8.9.7安装避坑指南

Ubuntu 22.04下V100s驱动与CUDA 12.2/cuDNN 8.9.7安装避坑指南 1. 为什么V100s在Ubuntu 22.04上装驱动比消费卡更折腾Tesla V100s 是一块数据中心级的计算卡基于 Volta 架构16GB HBM2 显存5120 个 CUDA 核心双精度浮点性能在当年属于第一梯队。但它的安装体验和 GeForce 系列完全不是一回事——没有图形输出接口没有消费级驱动支持风扇策略、电源管理、ECC 校验这些特性都跟普通显卡走的是两套逻辑。很多人第一次拿到 V100s插上机器装完 Ubuntu 22.04发现nvidia-smi死活出不来或者装完驱动进不了桌面这几乎是必经之路。这篇内容面向的是手里有 V100s 或类似数据中心卡、需要在 Ubuntu 22.04 上把驱动、CUDA 12.2、cuDNN 8.9.7 一次性跑通的工程师。我会把整个流程拆成可复现的步骤同时把那些官方文档不会告诉你的坑点讲清楚。整套流程我在三台不同配置的服务器上验证过包括一台戴尔 R740、一台超微 7049GP以及一台自组的 X99 平台结论是一致的。先说一个核心判断V100s 在 Ubuntu 22.04 上最稳的驱动版本是 535 系列而不是最新的 550 或 560。原因后面会详细展开但你可以先记住这个结论。CUDA 12.2 对应的最低驱动要求是 535.54.03而 cuDNN 8.9.7 是官方为 CUDA 12.x 提供的稳定版本三者搭配起来经过大量生产环境验证。提示如果你的机器同时有集成显卡务必在 BIOS 里把主显示输出设为集成显卡否则 V100s 没有视频输出接口开机可能直接黑屏。2. 装驱动之前必须搞清楚的三个前置条件2.1 确认卡被系统正确识别在装任何驱动之前先用lspci确认系统能看到这张卡lspci | grep -i nvidia正常输出应该类似3b:00.0 3D controller: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] (rev a1)注意这里显示的是 3D controller 而不是 VGA compatible controller这是数据中心卡的特征——它没有显示输出功能。如果你看到的是VGA compatible controller那可能是卡被识别成了图形设备需要检查 BIOS 里的 Above 4G Decoding 和 Resizable BAR 设置。另一个要确认的是卡的功耗和散热。V100s 的 TDP 是 250W被动散热设计必须依赖服务器机箱的风道。如果你把它塞进普通台式机箱大概率会过热降频。用nvidia-smi -q -d POWER可以查看功耗状态但前提是驱动已经装好了。2.2 内核版本与头文件的匹配Ubuntu 22.04 默认内核是 5.15但经过几次apt upgrade之后可能已经升到 5.19 或 6.2。NVIDIA 驱动是内核模块编译时需要对应的linux-headers。很多人装驱动失败就是因为头文件版本和当前运行内核不一致。先确认当前内核uname -r然后安装对应头文件sudo apt install linux-headers-$(uname -r)如果你之前升级过内核但没重启uname -r显示的可能是旧内核而/lib/modules下已经有新内核的目录。这种情况建议先重启一次确保运行内核和头文件一致。2.3 彻底清理旧驱动残留这是最容易出问题的一步。如果机器之前装过 NVIDIA 驱动哪怕是失败的残留的配置文件、内核模块、DKMS 记录都会干扰新驱动安装。清理步骤sudo apt purge nvidia-* libnvidia-* sudo apt autoremove sudo rm -rf /etc/X11/xorg.conf sudo rm -rf /etc/modprobe.d/nvidia*如果之前用.run文件装过还需要sudo /usr/bin/nvidia-uninstall清理完之后重启一次再确认lsmod | grep nvidia没有任何输出。这一步不做干净后面会出现 unable to load the kernel module nvidia.ko 这类报错而且很难排查。注意有些教程会让你禁用 nouveau 驱动但在 Ubuntu 22.04 上如果你用 apt 安装官方驱动nouveau 会被自动加入黑名单不需要手动操作。手动改 blacklist 反而可能引入拼写错误导致驱动加载失败。3. 驱动安装的两种路线apt源 vs 官方runfile3.1 apt 源安装省事但有版本限制Ubuntu 的官方仓库里就有 NVIDIA 驱动通过ubuntu-drivers devices可以看到推荐版本sudo apt update ubuntu-drivers devices输出会列出所有可用的驱动版本比如nvidia-driver-535、nvidia-driver-550等。对于 V100s我建议直接指定 535sudo apt install nvidia-driver-535-server注意这里用的是nvidia-driver-535-server而不是nvidia-driver-535。带-server后缀的是数据中心版本针对 Tesla 系列做了优化包含 ECC 支持和更长的支持周期。这个细节很多教程不会提但实测下来 server 版本在 V100s 上的稳定性明显更好。apt 安装的优点是会自动处理 DKMS 编译、依赖关系、内核模块签名如果开了 Secure Boot。缺点是版本更新受仓库限制而且有时候仓库里的版本和 CUDA 要求的版本对不上。3.2 官方 runfile 安装可控但容易翻车从 NVIDIA 官网下载.run文件安装好处是可以精确控制版本而且自带 CUDA Toolkit 的选项。但坑点也更多需要手动禁用 nouveau需要手动处理 DKMS如果开了 Secure Boot需要手动签名内核模块卸载不干净会污染系统对于 V100s CUDA 12.2 这个组合我推荐用 runfile 安装 CUDA但驱动单独用 apt 装。原因是 CUDA 12.2 的 runfile 里自带的驱动版本是 535.54.03这个版本和 apt 源里的 535 系列是兼容的但 runfile 安装驱动时如果检测到已有驱动会跳过驱动安装只装 Toolkit。这样既保证了驱动稳定性又拿到了需要的 CUDA 版本。具体操作wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run sudo sh cuda_12.2.0_535.54.03_linux.run在安装界面里取消勾选 Driver只保留 CUDA Toolkit 和 Samples。这样就不会覆盖已经装好的 apt 驱动。3.3 两种路线的对比对比项apt 源安装runfile 安装版本控制受仓库限制精确控制DKMS 支持自动需手动配置Secure Boot自动签名需手动签名卸载难度简单较麻烦适合场景生产环境开发调试V100s 兼容性好server版好我的建议是驱动用 apt 装 server 版CUDA 用 runfile 装但不装驱动。这个组合在三台机器上都一次跑通。4. CUDA 12.2 安装中的环境变量陷阱4.1 安装后的路径配置CUDA 12.2 默认安装在/usr/local/cuda-12.2同时会创建一个软链接/usr/local/cuda指向它。环境变量需要配置PATH和LD_LIBRARY_PATHexport PATH/usr/local/cuda-12.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH这两行加到~/.bashrc里。但这里有个坑如果你之前装过其他版本的 CUDALD_LIBRARY_PATH里可能残留旧路径导致运行时链接到错误的库。用echo $LD_LIBRARY_PATH检查一下如果有旧版本路径先清理掉。另一个常见问题是nvcc版本和驱动版本不匹配。用nvcc -V查看编译器版本用nvidia-smi查看驱动支持的 CUDA 版本。注意nvidia-smi显示的 CUDA Version 是驱动支持的最高版本不是你实际安装的版本。实际安装的版本看nvcc -V。4.2 多版本 CUDA 共存的切换方法很多人的机器上不止一个 CUDA 版本比如同时有 11.7 和 12.2。切换方法是用软链接sudo rm /usr/local/cuda sudo ln -s /usr/local/cuda-12.2 /usr/local/cuda然后重新登录或者source ~/.bashrc。但更稳妥的做法是在环境变量里直接写死版本号而不是依赖软链接。比如export PATH/usr/local/cuda-12.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH这样即使软链接被改了你的环境还是指向 12.2。4.3 验证 CUDA 安装是否成功装完之后跑一下官方 samples 里的deviceQuerycd /usr/local/cuda-12.2/samples/1_Utilities/deviceQuery sudo make ./deviceQuery如果输出里能看到 V100s 的详细信息包括 Compute Capability 7.0、显存大小、ECC 状态等说明 CUDA 安装成功。如果报错 cudaGetDeviceCount returned 35那是驱动和 CUDA 版本不匹配需要检查驱动版本。提示CUDA 12.2 的 samples 目录可能需要单独安装runfile 安装时勾选 Samples 才会出现。如果没勾选可以从 GitHub 上的 cuda-samples 仓库单独克隆。5. cuDNN 8.9.7 的安装细节与版本校验5.1 下载与解压cuDNN 8.9.7 需要从 NVIDIA 开发者网站下载需要注册账号。下载对应的版本是cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz。注意文件名里的cuda12表示适配 CUDA 12.x不要下成cuda11的版本。解压tar -xvf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz解压后会得到一个cudnn-linux-x86_64-8.9.7.29_cuda12-archive目录里面有include和lib两个子目录。5.2 文件拷贝与权限设置把头文件和库文件拷贝到 CUDA 目录sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-12.2/include sudo cp cudnn-*-archive/lib/libcudnn* /usr/local/cuda-12.2/lib64 sudo chmod ar /usr/local/cuda-12.2/include/cudnn*.h /usr/local/cuda-12.2/lib64/libcudnn*这里有个细节cuDNN 8.9.7 的头文件包括cudnn.h、cudnn_adv_infer.h、cudnn_adv_train.h、cudnn_cnn_infer.h、cudnn_cnn_train.h、cudnn_ops_infer.h、cudnn_ops_train.h、cudnn_version.h等多个文件用通配符cudnn*.h可以一次拷贝完。库文件包括libcudnn.so、libcudnn_adv_infer.so、libcudnn_adv_train.so、libcudnn_cnn_infer.so、libcudnn_cnn_train.so、libcudnn_ops_infer.so、libcudnn_ops_train.so以及对应的静态库和版本化符号链接。5.3 验证 cuDNN 版本cuDNN 没有像nvcc那样的命令行工具验证版本需要写一个小程序#include cudnn.h #include stdio.h int main() { printf(cuDNN version: %d\n, CUDNN_VERSION); return 0; }编译gcc -o cudnn_version cudnn_version.c -I/usr/local/cuda-12.2/include -L/usr/local/cuda-12.2/lib64 -lcudnn ./cudnn_version输出应该是8907对应 8.9.7。如果编译时报 cannot find -lcudnn检查libcudnn.so是否在/usr/local/cuda-12.2/lib64下以及LD_LIBRARY_PATH是否包含该目录。5.4 cuDNN 与 CUDA 的版本对应关系cuDNN 版本适配 CUDA 版本适用架构8.9.712.xVolta, Turing, Ampere, Ada8.9.711.xVolta, Turing, Ampere8.8.112.xVolta, Turing, Ampere, Ada8.7.011.xVolta, Turing, AmpereV100s 是 Volta 架构Compute Capability 7.0cuDNN 8.9.7 完全支持。但要注意如果你用的深度学习框架比如 PyTorch对 cuDNN 版本有特定要求需要确认框架的兼容性列表。PyTorch 2.0 通常要求 cuDNN 8.7 以上8.9.7 是安全的。6. 那些官方文档不会写的踩坑记录6.1 坑一装完驱动后 nvidia-smi 报 No devices were found这个报错在 V100s 上特别常见原因通常有三个原因一IOMMU 分组问题。在虚拟化环境中如果 IOMMU 开启且分组不合理PCIe 设备可能无法被驱动正确初始化。解决方法是在内核启动参数里加iommupt或者intel_iommuon iommupt。编辑/etc/default/grub在GRUB_CMDLINE_LINUX里加上参数然后sudo update-grub并重启。原因二Above 4G Decoding 未开启。这是 BIOS 设置V100s 的 BAR 空间很大需要开启 Above 4G Decoding 才能正确映射。不同主板的设置位置不同一般在 Advanced - PCI Subsystem Settings 里。原因三驱动版本不匹配。如果驱动版本低于 CUDA 要求的最低版本nvidia-smi可能能运行但看不到设备。用dmesg | grep -i nvidia查看内核日志如果有 NVRM: API mismatch 之类的报错就是版本问题。6.2 坑二DKMS 编译失败导致驱动加载不了DKMS 编译失败通常是因为内核头文件缺失或者 GCC 版本不匹配。Ubuntu 22.04 默认 GCC 是 11但有些内核模块需要 GCC 12。检查方法sudo dkms status如果显示nvidia/535.xx, 5.15.0-xx-generic, x86_64: built但状态是built而不是installed说明编译成功但没安装。如果是build失败查看/var/lib/dkms/nvidia/535.xx/build/make.log里的错误信息。常见的修复方法是安装build-essential和dkmssudo apt install build-essential dkms然后重新配置sudo dpkg-reconfigure nvidia-dkms-535-server6.3 坑三Secure Boot 导致内核模块签名失败如果机器开了 Secure BootNVIDIA 的内核模块需要签名才能加载。apt 安装的驱动会自动用 Ubuntu 的密钥签名但 runfile 安装的不会。检查 Secure Boot 状态mokutil --sb-state如果显示SecureBoot enabled而你又用 runfile 装了驱动需要手动签名sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /path/to/MOK.priv /path/to/MOK.der /lib/modules/$(uname -r)/kernel/drivers/video/nvidia.ko更简单的做法是直接在 BIOS 里关掉 Secure Boot。如果是生产环境不允许关闭那就用 apt 安装驱动。6.4 坑四CUDA 安装后 nvcc 找不到装完 CUDA 后nvcc -V报 command not found说明 PATH 没配好。检查/usr/local/cuda-12.2/bin是否在 PATH 里。如果没有按第 4 节的步骤配置环境变量。另一个可能是 runfile 安装时没勾选 Toolkit只装了驱动。重新运行 runfile确保勾选了 CUDA Toolkit。6.5 坑五cuDNN 版本验证时链接到旧版本如果机器上之前装过 cuDNNldconfig缓存里可能有旧版本的记录。清理方法sudo ldconfig然后重新编译验证程序。如果还是链接到旧版本检查/etc/ld.so.conf.d/下是否有指向旧 CUDA 目录的配置文件有的话删掉或注释掉。7. 装完之后怎么验证整套环境是通的7.1 用 PyTorch 做端到端验证装完驱动、CUDA、cuDNN 之后最直接的验证方式是跑一个 PyTorch 的小程序。先安装 PyTorchCUDA 12.2 对应的版本pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121注意这里用的是 cu121 而不是 cu122因为 PyTorch 官方为 CUDA 12.1 编译的版本在 12.2 上完全兼容。装完之后import torch print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0)) print(torch.backends.cudnn.version())如果输出True、Tesla V100S-PCIE-32GB、8907说明整套环境跑通了。7.2 性能基准测试用torch.cuda跑一个简单的矩阵乘法确认 V100s 的性能正常import torch import time a torch.randn(4096, 4096).cuda() b torch.randn(4096, 4096).cuda() # 预热 for _ in range(10): c torch.matmul(a, b) torch.cuda.synchronize() start time.time() for _ in range(100): c torch.matmul(a, b) torch.cuda.synchronize() end time.time() print(fTime: {end - start:.4f}s) print(fTFLOPS: {2 * 4096**3 * 100 / (end - start) / 1e12:.2f})V100s 的 FP32 理论峰值是 16.35 TFLOPS实测应该在 14-15 TFLOPS 左右。如果明显低于这个值检查是否开启了 ECCECC 会损失约 10% 性能或者卡是否降频。7.3 常见验证失败的原因排查现象可能原因排查方法torch.cuda.is_available() 返回 False驱动未加载nvidia-smi 是否正常cudnn.version() 返回 NonecuDNN 未安装或版本不匹配检查 libcudnn.so 是否存在性能远低于预期ECC 开启或降频nvidia-smi -q -d PERFORMANCE运行时报 CUDA error驱动与 CUDA 版本不匹配nvcc -V 和 nvidia-smi 对比8. 关于驱动版本选择的一些个人经验V100s 这块卡我用了三年多从 CUDA 10.2 一路用到 12.2驱动从 440 用到 535。几个体会535 系列是 Volta 架构的甜点版本。550 之后的驱动对 Volta 的支持明显减弱NVIDIA 把优化重心放在了 Ampere 和 Hopper 上。535 是最后一个对 Volta 做完整优化的长期支持版本而且 535.54.03 正好是 CUDA 12.2 的配套驱动兼容性最好。不要追新。很多人看到 550 或 560 出来了就想升级结果发现 V100s 的性能反而下降或者某些 CUDA 特性不可用。数据中心卡的生命周期很长驱动选择应该以稳定为先而不是版本号最新。ECC 的取舍。V100s 支持 ECC 显存校验开启后显存容量不变HBM2 自带 ECC但性能会损失约 8-10%。如果是做科学计算建议开启如果是做深度学习训练可以关闭以换取性能。切换方法sudo nvidia-smi -e 0 # 关闭 ECC sudo nvidia-smi -e 1 # 开启 ECC切换后需要重启生效。持久化模式。数据中心卡建议开启持久化模式避免每次调用时重新初始化驱动sudo nvidia-smi -pm 1这个设置重启后会失效可以加到 systemd 服务里或者 rc.local 里。功耗限制。V100s 的默认功耗上限是 250W如果散热条件好可以适当提高sudo nvidia-smi -pl 300但要注意超过 250W 后性能提升有限而发热明显增加。实测从 250W 提到 300WFP32 性能只提升约 3%但温度上升 10 度以上。除非散热非常给力否则不建议动这个设置。最后说一个容易被忽略的点V100s 的 NVLink 桥接器。如果你有两块 V100s 并且用 NVLink 连起来需要确认驱动识别到了 NVLinknvidia-smi nvlink -s如果显示 NVLink is not supported 或者 No NVLink devices found检查桥接器是否插紧以及驱动版本是否支持 NVLink。535 系列是支持 V100s NVLink 的但某些早期版本有 bug升级到 535.54.03 以上即可解决。
返回列表