ARTICLE DETAIL

资讯详情

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

Ubuntu 18.04+CUDA 10.2+cuDNN环境搭建:NVIDIA驱动与深度学习实践

Ubuntu 18.04+CUDA 10.2+cuDNN环境搭建:NVIDIA驱动与深度学习实践 直接说结论Ubuntu 18.04 NVIDIA显卡驱动 CUDA 10.2 cuDNN这套组合放到今天依然是不少深度学习项目、旧模型复现和老显卡开发的“黄金搭档”。尤其是很多开源项目在文档里写死的就是这套环境你拿新版本CUDA去跑反而可能编译报错。这篇文章我是根据自己的实际安装经历写的从驱动版本的选择、禁用nouveau、CUDA runfile安装、cuDNN文件拷贝到验证环境和排查驱动通信失败等常见坑都给你捋一遍照着操作基本能一次过。1. 装前必读这套组合解决什么问题1.1 为什么Ubuntu 18.04和CUDA 10.2依然是刚需很多刚接触Linux深度学习环境的人会问Ubuntu都出到22.04、24.04了CUDA都到12.x了为什么还要费劲装一套“老环境”我的回答是因为项目要求。就以我实际碰到的情况为例。之前复现一个比较老的目标检测项目作者的requirements和Dockerfile里明确写的就是Ubuntu 18.04、CUDA 10.2、cuDNN 7.6.5。如果你用CUDA 11.x或者12.x去编译会出现两种结果要么是某些算子库找不到对应版本要么是编译时因为计算能力不匹配而直接报错。对于这类项目与其花时间改代码适配新版本不如老老实实把环境装成项目要求的样子省下来的时间足够跑好几轮实验了。另外就是显卡兼容性问题。目前常见的GTX 10系、20系、部分Pascal架构的专业卡在CUDA 10.2下支持得非常好。而如果你用的是那种比较老的显卡比如GTX 750 Ti、GTX 960那新驱动和CUDA版本反而不一定支持。NVIDIA对老显卡的驱动支持是有期限的越新的驱动可能越不支持旧卡。所以选CUDA 10.2并不是“落后”而是“匹配”。1.2 版本对应关系和硬件检查在动手安装之前先搞清楚你需要什么版本。CUDA 10.2对应的驱动版本是440.33但实际你可以装更高版本的驱动因为驱动是向后兼容的高版本驱动可以跑低版本CUDA。这里有个原则你们记住CUDA工具包自带的驱动是最低要求装比它新的驱动是安全的但尽量不要装比它老的驱动。安装前先检查硬件lspci | grep -i nvidia如果输出里有NVIDIA显卡型号比如NVIDIA Corporation GM206 [GeForce GTX 960]说明显卡能被系统识别。接着查看当前系统是否装了NVIDIA驱动nvidia-smi如果提示NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver说明驱动没装好或者没加载这是后面要解决的核心问题。还要确认你的系统是64位因为CUDA工具包只提供64位版本uname -m输出x86_64就对了。同时可以用uname -r查看内核版本Ubuntu 18.04一般默认是4.15内核后面驱动编译会用到对应的内核头文件。2. 依赖原理驱动、CUDA和cuDNN到底是什么关系2.1 三者的分工从GPU硬件到深度学习框架很多人把显卡驱动、CUDA、cuDNN混为一谈其实它们是三层不同的东西。显卡驱动是操作系统和GPU硬件之间的翻译官。没有驱动GPU就是一块“不干活”的硬件。驱动负责最底层的硬件管理、显存分配、运算调度。你用nvidia-smi能查到的显存占用、温度、进程信息都是驱动提供的。CUDA是NVIDIA提供的并行计算平台它运行在驱动之上。你可以把驱动理解成操作系统而CUDA就是基于这个操作系统的开发SDK。CUDA工具包里面包含了编译器nvcc、运行时库、数学库等。深度学习框架比如PyTorch、TensorFlow在调用GPU时实际上是通过CUDA接口和驱动进行通信的。cuDNN是针对深度学习中卷积、池化、循环神经网络、归一化等常用操作经过深度优化过的CUDA加速库。简单说同样一个卷积运算用cuDNN跑可能比手写的CUDA代码快好几倍。它相当于一个特调大厨把最常用的几道菜做到了极致。2.2 为什么驱动不能随便装、版本不能乱配驱动和CUDA的版本匹配是很有讲究的。CUDA工具包在编译和运行时会检查当前驱动的版本。如果驱动版本太老低于CUDA要求的最低版本就会报错。但如果驱动版本比较新通常没有问题。我之前踩过一个坑为了让一个旧项目跑起来我在Ubuntu 18.04上装了CUDA 10.2然后又手动去NVIDIA官网下载了一个非常新的驱动比如470或520系列想着新的总比旧的好。结果发现虽然能正常进桌面但在跑某些需要直接调用驱动库的应用时出现GLX错误/var/log/Xorg.0.log里报Failed to load module glxserver_nvidia。后来我明白了对于老版本Xorg和内核来说太新的驱动反而会引入兼容性问题。所以在这套组合里我最终的驱动版本用的是440.33.01这是CUDA 10.2内置的驱动版本。当然你也可以安装稍微新一点的450、460系列但尽量别超过470。如果是20系以下的老显卡440.33足够用而且是最稳的。2.3 查看当前环境的工具和命令在安装前和安装后你都需要一些工具来验证状态nvidia-smi查看驱动是否正常、显存使用情况、驱动版本、CUDA版本。nvcc --version查看CUDA编译器的版本。cat /usr/local/cuda/version.txt查看CUDA安装目录里的版本信息。cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2查看cuDNN版本。这些命令的使用我在后面的验证章节会再详细讲。3. 完整实操从零开始装好整个环境3.1 准备阶段备份、卸载旧驱动和配套软件我强烈建议在开始前把系统里已有的一些NVIDIA相关软件“清理干净”。如果你之前安装过NVIDIA驱动或者系统里有默认的nvidia-*包直接装新版驱动很容易冒出各种冲突问题。先执行卸载命令sudo apt-get purge nvidia-* libnvidia-* sudo apt-get autoremove接着卸载可能存在的CUDA工具包sudo rm -rf /usr/local/cuda*很多教程会忽略这一步但如果你是从CUDA 11.x降级到10.2或者曾经用runfile方式安装过CUDA旧的安装文件会留在/usr/local/cuda里并且环境变量还会指向旧版本导致nvcc -V显示的还是旧版本。然后安装编译依赖sudo apt update sudo apt install build-essential dkms linux-headers-$(uname -r) gcc makedkms非常关键它能够让驱动在每次内核更新后自动重新编译注册而不是升级内核后驱动就失效了。3.2 禁用nouveau开源驱动这是安装NVIDIA驱动前最关键的步骤之一。Ubuntu系统默认自带一个开源的显卡驱动nouveau如果不禁用NVIDIA驱动装不上去或者在加载时与nouveau冲突导致黑屏、卡在登录界面等问题。先检查一下nouveau是否启用lsmod | grep nouveau如果有输出说明nouveau正在运行。需要把它列入系统黑名单。创建配置文件sudo vim /etc/modprobe.d/blacklist-nouveau.conf在文件里写入以下内容blacklist nouveau options nouveau modeset0然后更新initramfs并重启sudo update-initramfs -u sudo reboot重启后再执行lsmod | grep nouveau如果没有输出说明禁用成功。注意禁用nouveau之后、安装完整NVIDIA驱动之前你的显示分辨率可能会异常这是正常的。因为系统此时处于“无驱动”状态完全靠CPU进行软件渲染桌面会卡顿这是必经过程。相当于做手术前先麻醉一样忍过这一阵就好。3.3 安装NVIDIA驱动的两种方式我试过两种安装方式apt装和runfile装都成功了但各有优缺点。方式一通过apt安装推荐的NVIDIA驱动这是最简单的方式。我一般是先查看系统推荐的驱动版本ubuntu-drivers devices这个命令会列出当前系统可以安装的驱动版本并标注推荐版本。例如输出结果是nvidia-driver-440那直接执行sudo apt install nvidia-driver-440安装完成后重启sudo reboot重启后执行nvidia-smi如果出现类似下面的输出----------------------------------------------------------------------------- | NVIDIA-SMI 440.33.01 Driver Version: 440.33.01 CUDA Version: 10.2 |说明驱动安装成功了。可以看到驱动版本440.33.01CUDA Version显示10.2注意这个CUDA Version是当前驱动支持的最高CUDA版本不代表你已经安装了CUDA工具包。方式二通过官网runfile安装apt方式的问题在于它不一定能找到你需要的特定版本。如果apt源里没有440.33.01而是给了470或者510你又想用特定版本那还是要用runfile。从NVIDIA官网下载对应显卡的驱动比如NVIDIA-Linux-x86_64-440.33.01.run。然后运行chmod x NVIDIA-Linux-x86_64-440.33.01.run sudo ./NVIDIA-Linux-x86_64-440.33.01.runrunfile安装过程中会提示你是否安装32位兼容库、是否更新Xorg配置等一般选择默认即可。它还会询问是否卸载旧驱动选择“Yes”。用runfile方式装完同样执行nvidia-smi验证。实用经验如果你的显卡是笔记本显卡有时会遇到Optimus双显卡切换的问题。这时候不仅需要NVIDIA驱动还需要安装nvidia-prime来管理切换。这个包通过apt安装sudo apt install nvidia-prime装好后可以在系统设置里选择使用独立显卡还是核显。我之前在笔记本上装驱动后一直用不了独显就是缺少这个包导致的。3.4 安装CUDA 10.2CUDA 10.2的安装包可以通过NVIDIA官网下载文件名叫cuda_10.2.89_440.33.01_linux.run。这个文件名里的440.33.01是什么含义它是CUDA 10.2内置的驱动版本号。也就是说如果你电脑上还没装显卡驱动这个runfile可以顺便把驱动也装上。但如果你已经按前面的方式装好了驱动那在执行安装时就要注意选项不要重复安装驱动。下载完成后chmod x cuda_10.2.89_440.33.01_linux.run sudo sh cuda_10.2.89_440.33.01_linux.run在出现的文本图形界面中有一个要注意的地方它会用[X]勾选要安装的组件。这里我强烈建议用键盘上下键移到”Driver“那一行按空格取消驱动安装只保留CUDA Toolkit、CUDA Samples等选项。为什么因为如果你选择安装驱动安装程序可能会覆盖或者与已装的驱动冲突。既然前面已经通过apt或者runfile独立装好了驱动这里就不要再装一遍了。安装过程会问你接受许可协议Accept然后选择安装路径默认是/usr/local/cuda-10.2并且会创建一个/usr/local/cuda软链接指向该版本。安装完成后需要设置环境变量。编辑~/.bashrcvim ~/.bashrc在文件末尾添加export PATH/usr/local/cuda-10.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH export CUDA_HOME/usr/local/cuda-10.2然后使配置生效source ~/.bashrc验证nvcc --version如果输出类似nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2019 NVIDIA Corporation Built on Wed_Oct_16_19:32:14_PDT_2019 Cuda compilation tools, release 10.2, V10.2.89说明CUDA装好了。提示软链接/usr/local/cuda默认指向你最新安装的CUDA版本。如果之后你又装了CUDA 11.x软链接就会被覆盖指向新版本。所以为了维持项目要求的10.2环境装多个CUDA版本时要手动修改软链接指向或者直接在环境变量里写死cuda-10.2路径而不是用cuda这个软链接路径。3.5 安装cuDNN 7.6.5cuDNN的安装相比CUDA简单很多本质上就是把头文件和库文件拷贝到CUDA目录里。但下载cuDNN需要在NVIDIA官网注册开发者账号这一点经常有人卡住其实免费注册一下就行了。下载时选择cuDNN v7.6.5 for CUDA 10.2会有几个安装包cudnn-10.2-linux-x64-v7.6.5.32.tgz开发库cudnn-10.2-linux-x64-v7.6.5.32.solitairetheme8这种是浏览器下载后自动改名的本质也是tar包把下载好的tgz包解压tar -xzvf cudnn-10.2-linux-x64-v7.6.5.32.tgz解压后会得到一个cuda文件夹里面是include和lib64两个子目录。把对应的文件复制到CUDA安装目录sudo cp cuda/include/cudnn.h /usr/local/cuda-10.2/include/ sudo cp cuda/lib64/libcudnn* /usr/local/cuda-10.2/lib64/然后给库文件添加读取和执行权限这是因为从压缩包解压出来的文件默认权限可能不对之前我复制完在编译时老提示找不到libcudnn.so.7其实就是权限问题sudo chmod ar /usr/local/cuda-10.2/include/cudnn.h sudo chmod ar /usr/local/cuda-10.2/lib64/libcudnn*最后更新动态链接库缓存sudo ldconfig验证cuDNN版本cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2输出类似#define CUDNN_MAJOR 7 #define CUDNN_MINOR 6 #define CUDNN_PATCHLEVEL 5说明cuDNN 7.6.5就绪。3.6 验证完整环境装完三个组件之后要做一次完整的验证。先看驱动和CUDA运行时的通信是否正常nvidia-smi看驱动版本和显存。接着看CUDA编译器nvcc -V然后可以编译CUDA自带的示例程序验证计算能力cd /usr/local/cuda-10.2/samples/1_Utilities/deviceQuery sudo make ./deviceQuery如果最后输出Result PASS说明CUDA环境完整可用。这里提醒一句编译sample时如果提示gcc: 错误 unrecognized command line option ‘-stdc14’之类的问题那是因为系统gcc版本过低。Ubuntu 18.04默认的gcc 7支持c14一般不会有问题。但如果你用的是Ubuntu 16.04的旧gcc就会遇到这个报错。4. 常见问题与排查技巧4.1NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver这是我见到频率最高的报错。它的含义是驱动文件装了但内核模块没有加载成功。有几种可能原因第一nouveau没有完全禁用。重启后仍有lsmod | grep nouveau的输出。这种情况多发生在禁用文件写错或者update-initramfs没执行成功。重新执行禁用步骤然后重启。第二内核源/头文件不匹配。如果你在驱动安装时是通过dkms方式注册的升级内核后驱动需要重新编译。有时候网络不好头文件没装齐编译就会失败导致内核模块缺失。解决方式是重新安装匹配的头文件sudo apt install linux-headers-$(uname -r)然后重启或重新启动dkmssudo dkms install -m nvidia -v 440.33.01第三Secure Boot安全启动干扰。如果你的主板开启了UEFI安全启动未签名的NVIDIA内核模块是不会被加载的。这种情况的处理方式我在下面单独讲。4.2 Secure Boot导致驱动加载失败Ubuntu 18.04在UEFI模式下安装时如果开启了Secure Boot系统会在安装第三方驱动时提示你设置一个密码MOK。你可能当时随便输入了一个重启后又忘记在蓝色的MOK管理界面里确认导致驱动模块一直是“未签名不加载”的状态。排查方法很简单。在启动时进入MOK管理界面选择“Enroll MOK”输入之前设置的密码。如果密码忘了那就得进BIOS暂时把Secure Boot关掉装好驱动后再决定开不开。4.3 登录后卡在登录界面循环安装完驱动重启后输入密码进不了桌面闪一下又跳回登录界面的情况也很典型。原因是LightDM或GDM在启动时无法正确加载NVIDIA的GLX模块或者显卡切换出了问题。可以先切换到文本模式排查。在登录界面按CtrlAltF2进入终端登录后用nvidia-smi看看驱动是否正常。如果驱动正常尝试重装显示管理器sudo apt install --reinstall lightdm sudo dpkg-reconfigure lightdm如果驱动不正常很可能是驱动版本和Xorg版本冲突。之前在Xorg日志里出现过(EE) NVIDIA: Failed to load module glxserver_nvidia这一类的错误。这种情况的解决办法是卸载当前驱动换成稍旧一点的版本比如从470换回440因为太新的NVIDIA驱动对老版本Xorg的支持并不好。4.4 多版本CUDA共存与切换很多人的需求不是“只装10.2”而是“同时装10.2和11.8”因为不同项目需要不同环境。CUDA工具包本身支持多版本共存因为它们的安装目录是独立的比如/usr/local/cuda-10.2和/usr/local/cuda-11.8。切换的方式就是修改软链接sudo rm -rf /usr/local/cuda sudo ln -s /usr/local/cuda-10.2 /usr/local/cuda这时候nvcc --version就会变成10.2。但要注意动态库文件.so有时会缓存旧的路径切换后最好执行一下sudo ldconfig。而cuDNN是和CUDA目录绑定的也就是说你复制到cuda-10.2/lib64里的libcudnn.so.7和复制到cuda-11.8/lib64里的libcudnn.so.8是各管各的互不干扰。这个设计其实很合理只是一开始容易搞混你装两个CUDA版本cuDNN也得分别装两份。4.5 一个容易忽视的细节Python层面的CUDA版本装完系统层面的CUDA 10.2和cuDNN后在Python里用PyTorch时PyTorch本身会携带自己编译时链接的CUDA和cuDNN版本。比如pip install torch1.8.0它对应的就是CUDA 10.2。但这时的CUDA工具包含nvcc并不需要来自系统因为PyTorch用的主要是运行库libcudart等而不是编译器。所以如果你只是用PyTorch跑模型系统里的CUDA工具包版本装得不完全匹配有时候问题也不大。但如果你要编译自定义的CUDA算子比如用torch.utils.cpp_extension那就需要nvcc和匹配的运行时这时候系统全局的CUDA版本就很有讲究了。我个人的建议是在conda里为每个项目创建独立环境通过conda install cudatoolkit10.2 cudnn7.6.5安装项目所需的运行时而系统层面只保留一个主要的工作CUDA工具包。这样能把系统环境损坏的风险降到最低。5. 实操经验与几个小技巧5.1 安装日志和错误定位是最大的效率来源整个安装过程中遇到报错不要慌先看日志。比如Xorg启动问题看/var/log/Xorg.0.log内核模块加载问题看dmesg | tail输出驱动安装失败看/var/log/nvidia-installer.log。这些日志文件里往往已经把具体原因写得明明白白比你去网上搜索关键字更直接。我之前处理Failed to load module glxserver_nvidia这个报错时就是在Xorg.0.log里看到module path有问题顺藤摸瓜发现是驱动安装时用了自定义路径和Xorg默认读取路径不一致而不是什么高深的兼容性问题。5.2 内核升级与驱动的“绑定关系”Ubuntu 18.04会不定期推送内核升级这是很多环境突然“坏掉”的元凶。因为内核升级后dkms会自动尝试重新编译驱动但如果新内核的头文件没有及时安装驱动编译就会失败。结果就是你重启后进入新内核驱动没了nvidia-smi又报communication失败。解决办法有两种一是进入老内核启动在grub界面选择Advanced options老内核下的驱动模块还在能正常用二是把新内核的头文件装好重新触发dkms编译。为了防止生产环境被意外内核升级破坏我建议锁住内核版本sudo apt-mark hold linux-generic linux-image-generic linux-headers-generic等确定了新内核没问题再解除锁定。5.3 驱动装了但nvidia-smi显示CUDA版本带括号很多新手会困惑nvidia-smi右上角显示CUDA Version: 10.2但nvcc --version却显示没有nvcc命令。这是正常的。nvidia-smi显示的CUDA Version是驱动支持的最大CUDA运行时版本是驱动本身支持的“上限指标”并不代表系统里已经安装了对应的CUDA工具包。nvcc是工具包里的编译器你可以只装驱动不装CUDA也可以只装CUDA不装驱动后者没什么意义。这俩是两码事别混淆。5.4 遇到搞不定的问题优先考虑重装而不是修复在某些情况下比如你折腾了一整天还是黑屏或者登录循环我的经验是不要恋战重装Ubuntu系统可能比修驱动更快。这听起来像是笨办法但实际操作中Ubuntu 18.04从头安装加装驱动加CUDA加cuDNN熟练的话只需一个多小时。而如果陷入无休止的驱动冲突排查一个下午搭进去也不算完。重装前把/home单独分区或者备份到其他盘这样重装时可以保留个人数据。这是我在Linux环境折腾多年后觉得最实用的一个习惯。5.5 顺带提一下Linux下的FFmpeg为什么需要NVIDIA驱动现在很多视频处理项目在Linux上编译FFmpeg时都会加上--enable-cuda-nvcc之类的参数利用NVIDIA硬件编码器NVENC做硬编解码加速。如果驱动没装好FFmpeg编译时根本检测不到CUDA的存在自然也就没法启用硬编解码。所以即便你不是做深度学习只是做视频转码、推流一套干净的NVIDIA驱动环境同样重要。这也是为什么标题里“显卡驱动”这一环值得认真对待的原因。6. 写在最后整个环境的维护建议到这里Ubuntu 18.04 NVIDIA显卡驱动 CUDA 10.2 cuDNN的完整安装就全部结束了。我最后再把维护这套环境的关键经验总结成几条第一驱动版本别乱升。只要当前环境稳定能用就别去动驱动。尤其是旧项目更新驱动可能牵一发而动全身。第二备份/etc/modprobe.d/blacklist-nouveau.conf和~/.bashrc这两个文件。以后系统出问题需要重装时能节省不少时间。第三每次开机后先跑nvidia-smi验证驱动。如果出现异常第一时间dmesg | tail看内核日志。养成这个习惯环境问题就不会拖太久。第四如果装完驱动后遇到桌面显示异常先试试sudo apt install nvidia-prime很多笔记本双显卡问题靠它就能解决。这套环境我前后在台式机和笔记本上装过不下十次踩过的坑基本都集中在驱动冲突、Secure Boot和内核升级这三个点。你按这篇文章的顺序走大部分问题都能提前规避。如果确实遇到没覆盖到的情况先看日志再搜索相信你能比我自己摸索的时候更快定位到问题。祝你们一次装通。
返回列表