装完Ubuntu 20.04之后把Nvidia驱动、CUDA Toolkit、Anaconda和PyTorch一层层搭起来这个流程看起来是一堆命令的堆叠实际上每一步之间都有严格的依赖关系。我在不同的机器上重装过很多次这套环境遇到过无数次黑屏、循环登录、nvcc -V没输出、PyTorch检测不到GPU这类问题。折腾到最后才明白大部分坑都源于一个共同点没搞清楚驱动、CUDA Toolkit、Anaconda、PyTorch这四者到底是谁依赖谁。这篇文章就把我反复验证过、确定可用的完整流程记录下来。从一张空白系统开始到PyTorch能正常调用GPU跑张量运算每一步我都会解释为什么这样做以及装到一半出问题时怎么判断是哪一层出了问题。适合刚接触Linux环境、或者打算把开发机从Windows迁移到Ubuntu的深度学习新手参考也适合想要重装一套干净环境的老人快速翻阅。1. 先把依赖关系理清楚为什么顺序不能乱先说一个最常见的认知误区很多人以为Nvidia驱动装完就自带了CUDA所以PyTorch应该直接能用或者以为CUDA Toolkit是独立软件装完它驱动就可以不要了。这两种理解都不完整。1.1 四个组件各自是什么把这一整套环境类比成一套摄影设备Nvidia驱动是相机机身和镜头之间的接口。它让操作系统能识别并调用显卡负责把CUDA指令翻译成GPU硬件能执行的任务。驱动装好之后系统里就有了一个基础的CUDA Driver运行时。CUDA Toolkit是配合这套接口使用的开发工具包里面包含编译器nvcc、CUDA运行时库、cuBLAS、cuDNN这些数学库。类比的话它是镜头旁边那组滤镜和调节配件让上层软件能更快更精准地操作硬件。Anaconda是一个Python环境管理工具。它存在的意义是隔离不同项目之间的依赖版本冲突让你在一个机器上同时维护PyTorch 1.13的项目和PyTorch 2.1的项目而互不影响。PyTorch是真正跑深度学习代码的框架。它以CUDA为后端检测到GPU可用时会把张量运算交给显卡执行。四者的依赖链条是物理显卡 → Nvidia驱动 → CUDA Driver → CUDA Toolkit → PyTorch。也就是说PyTorch不是直接跟磁盘上的CUDA Toolkit打交道而是通过驱动提供的CUDA Driver去调用GPU。这就是为什么存在一种情况驱动和CUDA Toolkit版本不一致PyTorch照样能跑因为PyTorch发行包本身带了它需要的CUDA运行库。1.2 版本对齐的核心规则真正要死记硬背的只有一条规则Nvidia驱动支持的最高CUDA版本必须大于等于你想要运行的所有上层软件的CUDA版本。驱动安装好之后在终端敲nvidia-smi右上角会显示一行CUDA Version: xx.x。这个数字不是说你机器里装了CUDA Toolkit而是说当前驱动最高能支持到哪个CUDA版本。只要上层要求低于这个数字驱动就能兜住。不同系列驱动和CUDA版本的对应关系大致如下以我实测过的常见组合为例驱动系列最高支持CUDA版本适合场景470.x11.4RTX 30系早期、老平台510.x11.6兼容性折中方案520.x11.8搭配CUDA 11.8的稳定组合525.x12.0新卡、新PyTorch补充一个容易忽略的点CUDA大版本是向后兼容的。驱动只支持到11.4但你想跑一个18.0的PyTorch它底层用了CUDA 12.x的库这时候就装不了。反过来驱动支持12.0你却装一个基于CUDA 11.8的PyTorch完全没问题。1.3 为什么先装驱动再装CUDA Toolkit很多教程的顺序是随缘的实际上有讲究。CUDA Toolkit安装包在探测环境时会检查当前驱动版本。如果驱动版本低于Toolkit要求的最低值安装过程中虽然能继续但后续nvcc -V能正常显示版本号、编译一个cu文件却会报运行时错误。这种“编译通过、运行失败”的诡异问题排查起来最痛苦。所以流程上必须严格遵守系统装好 → 驱动装好并重启验证 → 再装CUDA Toolkit → 最后用Anaconda搭Python环境。下面每一步都按这个顺序来。2. 系统层面的准备Ubuntu 20.04最小化配置如果机器上已经有一个跑了很多项目的Ubuntu系统建议先备份数据后重新安装。因为驱动安装涉及内核模块旧系统里的残留依赖往往会让问题变得不可控。2.1 选择20.04的理由Ubuntu 20.04对应的内核版本是5.4虽然现在也有了22.04甚至更新的24.04但20.04在深度学习生态里依然是兼容性最好的那一档。原因其实很朴素Nvidia官方驱动和CUDA Toolkit都会为LTS版本做充分测试而20.04作为长期维护版本测试覆盖面最广。很多专用软件比如某些神经网络加速库、机器人仿真工具官方文档里写的支持矩阵就是以20.04为基准。另外20.04的桌面环境对显卡驱动的兼容也更宽容。我遇到过在22.04上安装Nvidia驱动后默认显示管理器LightDM起不来的情况20.04基本没有这个问题。2.2 安装时的几个细节安装Ubuntu本身不复杂有几点经验值得记一下分区时单独分一个/home分区。这样以后系统崩了重装系统盘项目数据和下载的模型权重都还在/home里不用重新下载省下大量时间。不需要单独分/boot分区除非你计划做双系统并且之前被引导问题坑过。单独分/boot反而容易在后续内核升级时空间不足。安装过程中不要联网更新。有些网卡在安装阶段驱动不完整会卡在“正在安装系统”的界面很久。断网安装能先把基础系统装完进系统后再配网络。2.3 系统装完后的基础配置进入系统后先把软件源换成国内镜像很多人会卡在这一步因为默认源太慢。以清华源为例修改/etc/apt/sources.list里的地址为镜像地址然后执行sudo apt update sudo apt upgrade -y升级完成后顺手把常用工具装上sudo apt install -y build-essential dkms gcc make cmake git vim net-tools这里面build-essential和dkms值得单独说两句。build-essential包含了编译Linux内核模块和C程序需要的gcc、make等基础工具。dkms是Dynamic Kernel Module Support它能让Nvidia驱动的内核模块在系统升级内核时自动重新编译。没有dkms的话每次内核一升级显卡驱动就失效桌面直接进不去需要重新装驱动非常糟糕。3. Nvidia驱动安装三种方式、一个推荐驱动安装是整个流程里最容易翻车的一步。我在不同机器上试过三种方式系统自动安装、runfile手动安装、deb包安装。下面把各自的适用场景和坑都说清楚。3.1 第一步永远是禁用nouveauNouveau是Linux内核自带的开源Nvidia显卡驱动框架。听起来挺美好但它的社区开发资源有限很多新型号的显卡在nouveau下的性能表现很差甚至无法正确初始化。更关键的是nouveau和官方Nvidia驱动会抢占同一个硬件资源两者同时存在会导致启动时黑屏或循环登录。所以装官方驱动之前先把nouveau禁掉sudo bash -c echo blacklist nouveau /etc/modprobe.d/blacklist-nouveau.conf sudo bash -c echo options nouveau modeset0 /etc/modprobe.d/blacklist-nouveau.conf sudo update-initramfs -u执行完重启。重启之后验证一下lsmod | grep nouveau如果没有任何输出说明禁用生效了。这一步要是不做后面装的官方驱动会跟nouveau打架症状是装完驱动重启后桌面进不去卡在一个闪烁的登录界面。3.2 方式A自动安装Ubuntu自带一个工具叫ubuntu-drivers-common它可以自动检测显卡型号并推荐合适的驱动版本sudo apt install -y ubuntu-drivers-common ubuntu-drivers devices执行后系统会列出当前显卡可用的驱动版本并标注recommended。直接执行sudo apt install -y nvidia-driver-535自动安装的好处是省心驱动版本由Ubuntu官方维护并且自动注册了dkms模块以后内核升级不用管。坏处是版本不是最新有时候推荐的版本可能跟最新版PyTorch依赖的CUDA版本配合不佳。3.3 方式Brunfile手动安装如果需要装特定版本的驱动比如为了对齐某个CUDA版本就需要去Nvidia官网下载对应驱动型号的runfile。这个方式灵活但步骤多先确保nouveau已禁用见3.1。从Nvidia官网选择显卡型号和操作系统下载对应的.run文件。安装前要先退出图形界面。在终端执行sudo service lightdm stop给runfile加执行权限并运行chmod x NVIDIA-Linux-x86_64-535.146.02.run sudo sh ./NVIDIA-Linux-x86_64-535.146.02.run安装过程中会询问是否安装nvidia-modprobe、是否更新Xorg配置这些默认项保持默认即可。装完重启。3.4 我的推荐和理由如果你只是一台深度学习开发机我的建议很简单用自动安装选515或535系列。理由有三个第一这两个系列都是长维护版本经历了足够多的内核版本测试稳定性有保障。第二它们对CUDA 11.8支持良好恰好是PyTorch官方预编译包常见的CUDA版本。第三apt方式集成dkms省去维护内核模块的心力。装完后重启执行nvidia-smi正常输出会显示显卡型号、驱动版本、显存占用以及右上角的CUDA Version。如果显示“NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver”说明驱动没装上或者没有成功加载内核模块。此时先检查dkms status如果是空白多半是需要重启或者重新安装驱动。4. CUDA Toolkit装哪个版本、怎么与驱动配合驱动装好之后系统已经能调用GPU了。但要让深度学习框架PyTorch获得完整的库支持还需要安装CUDA Toolkit。4.1 CUDA Toolkit的组成与安装方式选择CUDA Toolkit里包含几个层次的东西nvccCUDA编译器用来把.cu文件编译成GPU可执行代码。检查环境时常用nvcc -V。CUDA Runtime Library运行时库比如libcudart.soPyTorch在调用GPU时依赖它。CUDA数学库cuBLAS、cuFFT、cuSPARSE等。CUDA Driver安装时会检测驱动环境如果驱动版本不够会拒绝安装。安装方式推荐runfile。去Nvidia官网CUDA Toolkit页面选择Linux → x86_64 → Ubuntu → 20.04然后把下面类似这样的命令复制下来wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run sudo sh cuda_11.8.0_520.61.05_linux.run注意runfile在运行过程中会检查驱动版本。前面我们已经装好了驱动所以这里要小心安装器默认会尝试再装一遍驱动。此时在选项界面把驱动前面的X去掉只保留Toolkit和下方的Driver。如果已经装了驱动这里再装一遍容易引发版本冲突。也可以用这样的命令跳过交互直接安装sudo sh cuda_11.8.0_520.61.05_linux.run --toolkit --silent --override--override是绕过驱动版本检查用的如果驱动版本比Toolkit要求的低但又确定想装可以加这个参数。但正常流程下不建议这么做容易埋雷。4.2 环境变量配置安装完成后CUDA Toolkit默认会放在/usr/local/cuda-11.8同时系统会创建一个/usr/local/cuda软链接指向它。为了让终端能找到nvcc和动态库需要把路径写进用户环境变量echo export PATH/usr/local/cuda/bin:$PATH ~/.bashrc echo export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH ~/.bashrc source ~/.bashrc然后验证nvcc -V正常会显示Cuda compilation tools版本信息。如果提示命令不存在多半是PATH没写进去或者软链接没生成先检查ls /usr/local/cuda是否存在。4.3 两个版本号的区别为什么nvidia-smi和nvcc显示不一致这是被问得最多的问题之一。nvidia-smi右上角显示的是驱动支持的最大CUDA版本比如12.2。而nvcc -V显示的是Toolkit的编译版本比如11.8。两者的数字不需要一致。打个比方驱动相当于一条高速公路其最高限速是120km/hCUDA Toolkit是你用的车最高时速110km/h。两者各自的参数当然不同但只要车速不超过限速就能正常运行。只有当Toolkit需要的版本高于驱动的支持上限时才会出事。反过来也有一种情况nvcc -V没有输出但nvidia-smi正常。这说明驱动环境正常但Toolkit没有正确安装或环境变量没配好。常见解法是上面那步环境变量重新确认一遍。5. Anaconda安装与环境隔离思路很多人习惯直接在系统Python里装PyTorch这样短时间内省事但项目一多就会互相污染A项目要求PyTorch 1.13B项目要2.1直接装在系统Python里只有一个版本能用。Anaconda就是来解决这个问题的。5.1 为什么推荐Anaconda而不是venv或裸Python从Anaconda官网下载安装脚本bash Anaconda3-2023.09-0-Linux-x86_64.sh一路回车到询问是否初始化conda时选yes它会自动把你的shell配置文件~/.bashrc加上conda初始化代码。重新打开终端后命令行前缀会多一个(base)。安装完之后建议先做一个操作备份默认的源配置。Anaconda默认的源服务器在国外国内网络环境下载速度不太理想。改用国内镜像源能大幅提升下载体验conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes修改之后后续conda install创建环境的速度会明显变快。5.2 创建独立的深度学习环境不建议所有环境都堆在base里。为每个项目建一个独立环境是值得坚持的好习惯conda create -n pytorch python3.9 -y conda activate pytorch这里python版本选3.9是考虑到PyTorch官方对3.8到3.11都有支持而中间版本3.9/3.10在依赖兼容性上最稳。创建环境下环境隔离的意义在于每个环境都有自己独立的Python解释器和依赖包。即使你删掉某个环境不会影响系统的Python和其他环境相当于给项目排了一间独立办公室互不干扰。5.3 conda源和pip源的区别Anaconda环境里装包有两条路径conda install和pip install。conda会把二进制包的依赖一起解决但有些包的conda版本更新滞后。pip版本更新快但不会自动处理系统级依赖。实操经验是优先用pip装PyTorch相关库conda用来管理环境本身。因为PyTorch官方提供的预编译包在pip上最全版本也最新。6. PyTorch安装与CUDA可用性验证最简单的5行代码环境准备好之后重头戏来了。6.1 选择安装命令PyTorch官网安装向导会根据你选择的平台自动生成安装命令。对于CUDA 11.8命令是pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果网络环境不好也可以改用国内组织维护的PyTorch稳定版wheel仓库。但要注意用第三方源时一定要确认下的是cu118变体而不是cpu变体否则装了个CPU版PyTorch后面验证阶段会一脸懵。一个判断技巧装完之后在Python里执行import torch; print(torch.version.cuda)。如果输出是11.8说明装的是GPU版如果显示None说明装的是CPU版。6.2 验证脚本逐行解释验证CUDA是否可用不用多复杂五句话足够import torch print(PyTorch版本:, torch.__version__) print(CUDA是否可用:, torch.cuda.is_available()) print(GPU数量:, torch.cuda.device_count()) print(GPU名称:, torch.cuda.get_device_name(0)) print(PyTorch使用的CUDA版本:, torch.version.cuda)建议把上面代码存成一个check_gpu.py每次在新环境里跑一遍一眼看清状态。如果最后输出如下说明整个链路已经通了PyTorch版本: 2.1.0cu118 CUDA是否可用: True GPU数量: 1 GPU名称: NVIDIA GeForce RTX 3080 PyTorch使用的CUDA版本: 11.8torch.cuda.is_available()是True意味着PyTorch通过驱动成功找到了GPU。6.3 推荐做的几个额外验证第一次装完建议多做两个验证能提前暴露很多隐患第一个是真正的张量运算测试看GPU是否真的在计算import torch x torch.rand(1000, 1000).cuda() y torch.matmul(x, x) print(y.sum().item())不报错就说明CUDA运算链路没问题。顺带说一下这段代码执行时GPU会瞬间把张量搬到显存并完成矩阵乘法如果驱动或者CUDA运行库有问题报错信息大概率是AssertionError: Torch not compiled with CUDA enabled或者RuntimeError: No CUDA GPUs are available。第二个是测试cuDNN深度学习加速库版本是否正常import torch print(torch.backends.cudnn.is_available()) print(torch.backends.cudnn.version())输出True和8xxx这样的版本号说明cuDNN可用。cuDNN对卷积神经网络的加速效果非常显著is_available()返回False虽然不影响模型训练但会被迫退回到较慢的算法路径。7. 实际操作中踩过的坑与完整排查链路配置这套环境的次数多了踩过的坑五花八门。挑几个最有代表性的记录一下给你一个排查思路的参考。7.1 现象一torch.cuda.is_available()返回False但nvidia-smi正常这是我见过的最高频问题。现象是驱动正常显示但PyTorch就是检测不到GPU。排查链路先在Python里打印torch.version.cuda如果输出为None说明装的PyTorch是CPU版。原因通常是安装时使用了不带cu标识的源或者命令拼写时缺少了--index-url那段。如果torch.version.cuda有数字但还是False则检查驱动支持的最高CUDA版本。比如驱动只支持到11.4但你装的是cu118的PyTorch下层库要求的CUDA版本超过了驱动的能力范围于是加载失败。此时要么升级驱动要么换一个老版本的PyTorch。还有一种比较少见的双显卡笔记本混合显卡上PyTorch默认选择了核显而不是独显。此时需要设置环境变量指定设备export CUDA_VISIBLE_DEVICES07.2 现象二安装CUDA Toolkit后nvcc -V找不到明明runfile安装日志一大片成功重启后nvcc -V提示command not found。排查链路先看/usr/local/下有没有cuda文件夹ls /usr/local/cuda/bin/nvcc如果文件不存在说明Toolkit没有真正装到默认路径。大概率是安装过程中选择了“不创建软链接”或者环境变量里的PATH没生效。此时直接把路径加上export PATH/usr/local/cuda-11.8/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH然后把这两行写入~/.bashrc再source。7.3 现象三旧显卡装了新驱动后报“no kernel image is available”这属于老显卡配合新驱动时的经典问题。比如GTX 750 Ti这类旧卡官方驱动的后续新版本不再包含其对应的内核编译模块装上后运行nvidia-smi会报no kernel image is available for execution on the device。排查链路确认显卡型号后去Nvidia官网查它的架构代号Kepler/Maxwell/Ampere等然后选择该架构最后一个官方支持版本的驱动。比如Maxwell架构的显卡装470系列驱动通常比较稳。此时CUDA Toolkit版本也要向下兼容选择11.4及以下。PyTorch版本则需要选择旧版本——比如1.12.x或更早的版本因为新版本PyTorch的CUDA后端放弃了旧架构支持。这个问题的本质是驱动、CUDA、PyTorch三者都需要在硬件算力范围之内链条上任何一环超出硬件上限都会失败。7.4 重建环境时最快的检查顺序重装或新机配置时按照下面的顺序排查效率最高第1步nvidia-smi → 是否有输出 → 无输出则驱动没装好 第2步nvcc -V → 是否正常显示 → 没显示则检查Toolkit路径 第3步python -c import torch; print(torch.cuda.is_available()) → 再验证功能三步走完基本能锁定问题发生在哪一层。我个人实际操作中的体会是大多数时候问题出在第1步和第3步之间驱动和Toolkit都有但PyTorch装成了CPU版。所以每次装完PyTorch第一件事永远是跑一遍验证脚本而不是急着一头扎进训练代码。7.5 关于驱动版本更新的一个个人建议很多人习惯装最新的驱动程序以为新驱动性能一定更好。但对于深度学习工作机我一般倾向于选择半年左右没曝出严重问题的稳定版驱动。道理很简单生产环境里稳定压倒一切性能提升个百分之一二远远抵不上驱动更新导致某个项目突然跑不了带来的损失。装好这套环境如果不折腾内核和显卡用上一两年是很常见的事情。最后再提醒一点Conda环境和CUDA Toolkit的关系不是“装了Toolkit才能用PyTorch”而是“深度学习框架需要CUDA运行库来支持GPU运算”。大多数时候直接用pip安装的PyTorch已经自带了所需CUDA库所以不装完整CUDA Toolkit也可以跑起来。但编译扩展算子、使用某些第三方CUDA扩展库时还是需要Toolkit在系统里的。所以我始终建议把它装到位一劳永逸。