1. 项目缘起:为什么选择Deb包安装CUDA?
在深度学习或者高性能计算领域,NVIDIA的CUDA和cuDNN是绕不开的两座大山。很多刚入门的朋友,包括一些有一定经验的开发者,在Ubuntu这类Linux系统上配置环境时,常常会一头扎进NVIDIA官网,然后被各种.run安装器、网络安装包、版本依赖搞得晕头转向。尤其是当你按照某些教程,使用.run文件安装CUDA时,一个不小心就可能把系统自带的Nouveau驱动给冲了,或者导致图形界面崩溃,只能对着黑屏的命令行发呆。
我自己就踩过这个坑。有一次为了赶项目进度,在Ubuntu 20.04上直接用.run文件装CUDA 11,结果安装程序“贴心”地帮我覆盖了系统驱动,重启之后直接进了tty命令行,图形界面消失得无影无踪。那次折腾了大半天才恢复过来。后来我发现,对于Ubuntu这类基于Debian的系统,使用官方提供的.deb包来安装CUDA,才是更稳妥、更“系统友好”的方式。
简单来说,.deb包安装就像是通过系统的“应用商店”来安装软件。它会将CUDA的库、头文件、工具链等,以符合Debian/Ubuntu软件包管理规范的方式部署到系统中,并且能很好地处理与其他系统组件的依赖关系。而.run文件更像是一个“绿色安装包”,它会把所有东西打包塞进你指定的目录(通常是/usr/local/cuda-xx.x),但有时会过于“霸道”,容易引发冲突。
所以,这篇内容就是来分享如何在Ubuntu 20.04 LTS上,通过.deb包这种更优雅的方式来安装CUDA 12.x和对应的cuDNN。这个方法逻辑清晰,步骤明确,对系统侵入性小,即便是刚接触Linux的“宝宝”们,跟着步骤一步步来,也能顺利搭建起自己的深度学习环境。我们目标是:一次成功,远离黑屏。
2. 安装前的核心准备工作:理清概念与检查环境
在动手之前,我们必须把几个关键概念和系统状态搞清楚。这就像盖房子前要勘测地质一样,能避免很多后续的麻烦。
2.1 CUDA Toolkit、驱动与cuDNN的关系
很多人容易混淆这几个概念,我们先来理一理:
- NVIDIA显卡驱动:这是让你的操作系统能够识别和使用NVIDIA显卡的底层软件。没有它,你的显卡就是一块高级砖头。我们常说的
nvidia-smi命令就是由它提供的。 - CUDA Toolkit:这是一个由NVIDIA提供的软件开发工具包。它包含了:
- CUDA编译器(nvcc):用于编译你写的CUDA C/C++代码。
- CUDA运行时库(libcudart):为CUDA程序提供运行时的支持。
- 各种工具和库:如性能分析器
nvprof、调试器cuda-gdb,以及数学库cuBLAS、cuFFT等。
- cuDNN:全称CUDA Deep Neural Network library。这是一个专门为深度学习优化的GPU加速库。像TensorFlow、PyTorch这些框架,它们的底层卷积、池化等操作,很多都是调用cuDNN来实现的。cuDNN必须和特定版本的CUDA Toolkit配套使用。
它们三者的关系可以简单理解为:驱动是地基,CUDA Toolkit是建筑工具和材料,cuDNN是针对“深度学习”这个特定装修需求的豪华工具箱。你需要先打好地基(装驱动),然后准备好通用工具(CUDA Toolkit),最后再配置专用工具箱(cuDNN)。
注意:通过
.deb包安装CUDA时,通常会包含一个与该CUDA版本兼容的NVIDIA驱动。这意味着我们可能不需要单独安装驱动,安装过程会一并处理。这是.deb安装的一大优势。
2.2 系统环境检查清单
在下载任何安装包之前,请务必完成以下检查:
确认系统架构: 打开终端,输入:
uname -m对于大多数现代电脑,输出应该是
x86_64(即64位系统)。这是下载对应安装包的前提。检查当前NVIDIA驱动(如果有): 输入:
nvidia-smi如果系统已经安装了NVIDIA驱动,这个命令会显示显卡信息、驱动版本和CUDA版本。这里显示的CUDA版本是驱动所能支持的最高CUDA版本,不代表你已经安装了CUDA Toolkit。记下这个驱动版本号。如果命令报错(
Command ‘nvidia-smi’ not found),说明没有安装专有驱动,可能在使用开源驱动nouveau,这没关系,.deb安装包会处理。卸载可能存在的旧版本CUDA(非必须,但建议): 如果你之前通过其他方式(比如
.run文件)安装过CUDA,为了干净起见,可以尝试卸载。但.deb方式管理更规范,冲突概率小。如果你不确定,可以跳过此步,让新安装过程去覆盖或升级。 如果是用.run文件安装的,可以运行:sudo /usr/local/cuda-xx.x/bin/cuda-uninstaller # 将xx.x替换为你的旧版本号或者直接删除目录:
sudo rm -rf /usr/local/cuda # 这是一个软链接 sudo rm -rf /usr/local/cuda-xx.x # 这是具体版本目录禁用开源Nouveau驱动(关键步骤): 这是避免安装过程中出现冲突或失败的重要一步。Ubuntu默认使用开源的Nouveau驱动来驱动NVIDIA显卡,但它与NVIDIA官方驱动不兼容。
- 创建配置文件:
(如果不会用vim,可以用sudo vim /etc/modprobe.d/blacklist-nouveau.confsudo gedit /etc/modprobe.d/blacklist-nouveau.conf) - 在文件中添加以下两行内容:
blacklist nouveau options nouveau modeset=0 - 保存并退出编辑器。
- 更新内核initramfs:
sudo update-initramfs -u - 重启系统。重启后,Nouveau驱动将被禁用。你可以通过以下命令验证是否已禁用:
如果没有输出任何内容,说明禁用成功。lsmod | grep nouveau
- 创建配置文件:
完成以上准备工作,我们的“地基”就算勘察和清理完毕了,可以开始正式“施工”。
3. 实战步骤一:通过Deb包安装CUDA 12.x
这里我们以CUDA 12.4为例(请以NVIDIA官网最新稳定版为准),演示完整的安装过程。
3.1 从NVIDIA官网获取正确的Deb包安装指令
不要盲目搜索下载链接,最可靠的方式是直接从官网获取针对你系统的安装命令。
访问 NVIDIA CUDA Toolkit 官网(搜索 “CUDA Toolkit Archive” 可以找到历史版本页面,选择12.x的最新版,例如12.4)。
在选择界面,按如下方式勾选:
- Operating System: Linux
- Architecture: x86_64
- Distribution: Ubuntu
- Version: 20.04
- Installer Type: deb (network) “deb (network)” 指的是通过网络安装的deb包,它会从NVIDIA仓库下载,能更好地管理依赖。这是推荐的方式。
官网会生成一个安装指南,其中包含类似下面的命令块。请务必复制你在官网上看到的完整命令,不要直接使用我下面例子中的版本号,因为版本可能会更新。
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600 wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda-repo-ubuntu2004-12-4-local_12.4.0-550.54.14-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu2004-12-4-local_12.4.0-550.54.14-1_amd64.deb sudo cp /var/cuda-repo-ubuntu2004-12-4-local/cuda-*-keyring.gpg /usr/share/keyrings/ sudo apt-get update sudo apt-get -y install cuda-toolkit-12-4
3.2 逐行执行安装命令并理解其含义
现在,我们打开终端,逐条执行从官网复制的命令,并了解每一步在做什么:
下载并设置软件包优先级(Pin)文件:
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600wget下载一个名为cuda-ubuntu2004.pin的文件。这个文件的作用是告诉系统的APT包管理器:“当从其他仓库也有CUDA相关包时,优先使用NVIDIA官方仓库的版本”。这能防止系统自动更新时被其他源覆盖。sudo mv将这个pin文件移动到/etc/apt/preferences.d/目录下,使其生效。
下载并安装本地仓库包:
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda-repo-ubuntu2004-12-4-local_12.4.0-550.54.14-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu2004-12-4-local_12.4.0-550.54.14-1_amd64.deb- 第一行下载一个具体的
.deb包。这个包不是CUDA Toolkit本身,而是一个“本地仓库包”。安装它,相当于在你的系统里添加了一个NVIDIA的软件源。 - 第二行用
dpkg -i安装这个仓库包。安装后,你可以在/etc/apt/sources.list.d/目录下找到新增的源列表文件。
- 第一行下载一个具体的
导入密钥环:
sudo cp /var/cuda-repo-ubuntu2004-12-4-local/cuda-*-keyring.gpg /usr/share/keyrings/- 这一步将仓库的GPG密钥复制到系统密钥环目录,用于验证从该仓库下载软件包的完整性和真实性,避免安装被篡改的包。
更新软件源并安装CUDA Toolkit:
sudo apt-get update sudo apt-get -y install cuda-toolkit-12-4sudo apt-get update:更新本地软件包索引,这将获取我们刚刚添加的NVIDIA仓库中的软件包信息。sudo apt-get -y install cuda-toolkit-12-4:这是核心安装命令。-y参数表示自动回答“yes”确认安装。cuda-toolkit-12-4是一个元包,它会自动拉取所有CUDA 12.4 Toolkit必需的组件,包括兼容版本的NVIDIA驱动、编译器、运行时库等。
这个过程会持续一段时间,需要下载几百MB到上GB的数据,具体取决于网络速度。安装过程中,可能会提示你接受驱动相关的许可协议,按提示操作即可。
3.3 安装完成后的环境配置
安装程序结束后,CUDA已经被安装到了/usr/local/cuda-12.4(版本号可能不同)目录下。为了方便使用,我们通常需要设置环境变量。
编辑用户的环境变量配置文件:
vim ~/.bashrc或者
gedit ~/.bashrc在文件的末尾添加以下几行:
# CUDA Toolkit export PATH=/usr/local/cuda-12.4/bin${PATH:+:${PATH}} export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}- 第一行:将CUDA的二进制工具目录(如
nvcc)添加到系统的PATH环境变量中。这样你才能在终端任何地方直接运行nvcc等命令。 - 第二行:将CUDA的库文件目录添加到
LD_LIBRARY_PATH环境变量中。这样在运行程序时,系统才能找到CUDA的动态链接库(如libcudart.so)。
提示:如果你未来可能安装多个CUDA版本,这里有个小技巧。你可以不直接写死路径,而是创建一个软链接:
sudo ln -sf /usr/local/cuda-12.4 /usr/local/cuda然后在
.bashrc中设置PATH和LD_LIBRARY_PATH时指向/usr/local/cuda。这样,当你需要切换版本时,只需更改这个软链接指向的目录即可,无需修改环境变量。- 第一行:将CUDA的二进制工具目录(如
使环境变量立即生效:
source ~/.bashrc
4. 实战步骤二:安装与CUDA 12.x匹配的cuDNN
cuDNN的安装相对独立,NVIDIA将其作为一个单独的库提供。你需要注册一个免费的NVIDIA开发者账号才能下载。
4.1 下载正确版本的cuDNN Deb包
- 访问 NVIDIA cuDNN 官网(搜索 “cuDNN Archive”)。
- 登录你的NVIDIA开发者账号。
- 在存档页面,找到与你的CUDA 12.x版本对应的cuDNN版本。例如,CUDA 12.x 通常对应 cuDNN 8.x 或 9.x 系列。务必确认版本兼容性,官网会有明确说明(如“For CUDA 12.x”)。
- 选择对应的版本后,进入下载页面。你需要下载三个
.deb包(以Ubuntu 20.04, x86_64架构为例):- 运行时库:例如
libcudnn8_8.x.x.x-1+cuda12.x_amd64.deb - 开发者库:例如
libcudnn8-dev_8.x.x.x-1+cuda12.x_amd64.deb - 文档和示例:例如
libcudnn8-samples_8.x.x.x-1+cuda12.x_amd64.deb其中8.x.x.x是具体的cuDNN版本号,12.x是对应的CUDA主版本号。
- 运行时库:例如
4.2 按顺序安装cuDNN Deb包
下载完成后,在终端中进入存放deb包的目录,按以下顺序安装:
# 安装运行时库 sudo dpkg -i libcudnn8_8.x.x.x-1+cuda12.x_amd64.deb # 安装开发者库(包含头文件等,编译深度学习框架需要) sudo dpkg -i libcudnn8-dev_8.x.x.x-1+cuda12.x_amd64.deb # 安装文档和示例(可选,用于验证) sudo dpkg -i libcudnn8-samples_8.x.x.x-1+cuda12.x_amd64.deb安装过程很快,因为这些包实际上是将文件解压到系统标准路径(如/usr/include/,/usr/lib/x86_64-linux-gnu/),并更新系统的库缓存。
4.3 验证cuDNN安装
安装完cuDNN后,强烈建议运行其自带的示例程序来验证是否安装成功。
- 拷贝cuDNN示例代码到你的家目录:
cp -r /usr/src/cudnn_samples_v8/ ~/ - 进入一个示例目录,例如测试卷积操作的目录:
cd ~/cudnn_samples_v8/mnistCUDNN - 编译示例程序:
如果编译过程中报错找不到sudo make clean && sudo makeFreeImage.h,你需要安装libfreeimage3和libfreeimage-dev:
然后重新执行sudo apt-get install libfreeimage3 libfreeimage-devsudo make。 - 运行编译好的示例:
如果输出结果中看到./mnistCUDNNTest passed!字样,恭喜你,cuDNN安装成功,并且可以与CUDA协同工作。
5. 安装后的全面验证与问题排查
环境装好了,但到底成不成功?我们需要一套“组合拳”来验证。
5.1 基础命令验证
验证驱动和CUDA驱动API:
nvidia-smi这个命令应该能正常输出,顶部会显示驱动版本和最高支持的CUDA版本(例如
CUDA Version: 12.4)。这证明了驱动安装正确。验证CUDA编译器(nvcc):
nvcc --version这个命令会输出
nvcc的版本信息,它应该与你安装的CUDA Toolkit版本(如12.4)一致。这证明了CUDA开发环境配置正确。验证CUDA运行时库: 我们可以写一个最简单的CUDA程序来测试。创建一个文件
test_cuda.cu:#include <stdio.h> #include <cuda_runtime.h> int main() { int deviceCount = 0; cudaError_t error_id = cudaGetDeviceCount(&deviceCount); if (error_id != cudaSuccess) { printf("cudaGetDeviceCount returned %d\n-> %s\n", (int)error_id, cudaGetErrorString(error_id)); return 1; } if (deviceCount == 0) { printf("No CUDA-capable devices found.\n"); } else { printf("Found %d CUDA Capable device(s).\n", deviceCount); for (int dev = 0; dev < deviceCount; ++dev) { cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, dev); printf("\nDevice %d: \"%s\"\n", dev, deviceProp.name); } } return 0; }编译并运行:
nvcc test_cuda.cu -o test_cuda ./test_cuda如果输出显示了你显卡的型号和数量,那么恭喜,CUDA运行时环境完全正常。
5.2 常见问题与解决方案
即使按照步骤操作,也可能遇到一些问题。这里列举几个常见的:
问题1:
nvidia-smi命令正常,但nvcc --version报错 “command not found”。- 原因:环境变量
PATH没有设置正确,或者.bashrc修改后没有source。 - 解决:
- 检查
~/.bashrc文件中的PATH设置是否正确指向了/usr/local/cuda-12.4/bin。 - 执行
source ~/.bashrc。 - 如果还不行,尝试直接指定路径运行
/usr/local/cuda-12.4/bin/nvcc --version。如果可以,说明环境变量路径有误。
- 检查
- 原因:环境变量
问题2:运行CUDA示例程序时,报错 “error while loading shared libraries: libcudart.so.12.x: cannot open shared object file”。
- 原因:环境变量
LD_LIBRARY_PATH没有设置或设置错误,系统找不到CUDA的运行时库。 - 解决:
- 检查
~/.bashrc中的LD_LIBRARY_PATH是否包含/usr/local/cuda-12.4/lib64。 - 执行
source ~/.bashrc。 - 也可以临时设置:
export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH,然后再运行程序。
- 检查
- 原因:环境变量
问题3:在安装CUDA deb包过程中,
sudo apt-get install cuda报错,提示依赖问题。- 原因:可能是之前的NVIDIA驱动残留、系统包索引过时或其他软件源冲突。
- 解决:
- 首先尝试修复依赖:
sudo apt-get install -f。 - 更新系统:
sudo apt-get update && sudo apt-get upgrade。 - 如果问题依旧,可以尝试彻底清除之前的NVIDIA相关包(谨慎操作):
sudo apt-get purge *nvidia* *cuda* *cudnn* sudo apt-get autoremove - 重新执行从官网获取的完整安装命令序列。
- 首先尝试修复依赖:
问题4:cuDNN示例编译失败,提示找不到
cudnn.h或libcudnn.so。- 原因:cuDNN的开发包(
libcudnn8-dev)没有安装成功,或者安装后头文件和库的路径不在系统默认搜索路径中。 - 解决:
- 确认
libcudnn8-dev包已正确安装:dpkg -l | grep cudnn。 - 检查头文件是否存在:
ls /usr/include/cudnn*或ls /usr/include/cudnn.h。 - 检查库文件是否存在:
ls /usr/lib/x86_64-linux-gnu/libcudnn*。 - 如果路径不对,可能是安装到了非标准路径。可以尝试手动创建软链接,或者修改示例代码的Makefile中的包含路径和链接库路径。
- 确认
- 原因:cuDNN的开发包(
6. 进阶配置与管理:多版本CUDA与虚拟环境
对于深度学习开发者,经常需要在不同项目间切换CUDA版本。.deb安装方式虽然规范,但默认会安装到系统路径。如何优雅地管理多个版本?
6.1 利用软链接实现系统级CUDA版本切换
如前文提示,我们可以利用/usr/local/cuda这个软链接来指向当前活跃的CUDA版本。
- 假设你已经通过
.deb方式安装了CUDA 11.8和CUDA 12.4,它们分别位于/usr/local/cuda-11.8和/usr/local/cuda-12.4。 - 当你需要切换到CUDA 12.4时,执行:
sudo rm -f /usr/local/cuda # 删除旧软链接 sudo ln -s /usr/local/cuda-12.4 /usr/local/cuda # 创建新软链接指向12.4 - 更新环境变量(如果你的
.bashrc里设置的是/usr/local/cuda):source ~/.bashrc - 验证版本:
现在输出的应该是12.4。nvcc --version
这种方法简单直接,但属于系统级切换,会影响所有用户和所有终端会话。
6.2 更推荐的方式:在Conda虚拟环境中管理CUDA
对于Python深度学习项目,更专业和推荐的做法是使用Conda虚拟环境。Conda不仅可以管理Python包,还可以管理CUDA和cuDNN的版本,真正做到环境隔离。
- 安装Miniconda或Anaconda。
- 为特定项目创建虚拟环境并指定CUDA版本:
# 创建一个名为 pytorch_12.4 的环境,并指定python版本 conda create -n pytorch_12.4 python=3.9 conda activate pytorch_12.4 - 在虚拟环境中安装PyTorch或TensorFlow: 在PyTorch官网,使用Conda命令安装时会自动帮你解决对应版本的CUDA依赖。例如,安装支持CUDA 12.1的PyTorch:
这个命令会在当前的conda环境里安装PyTorch以及与之匹配的CUDA 12.1工具包(这是一个精简版的CUDA,只包含运行PyTorch必需的运行时库,不会影响系统全局的CUDA)。此时,在这个环境里,conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidiaimport torch; torch.cuda.is_available()会返回True,并且使用的是conda环境内的CUDA 12.1,与你系统里安装的CUDA 12.4互不干扰。
我个人在实际工作中,几乎为每一个主要项目都会创建一个独立的Conda环境,并在里面通过框架的安装命令来间接管理CUDA依赖。这样,项目A用PyTorch 1.13 + CUDA 11.7,项目B用TensorFlow 2.10 + CUDA 12.0,可以在一台机器上完美共存,切换环境即可,完全不需要去动系统级的CUDA。这是目前最清晰、最安全的深度学习环境管理方案。