1. 为什么这套环境值得单独写一篇完整流程
深度学习环境搭建这件事,看起来只是几条命令的事,但真正动手做过的人都知道,从裸机到能跑通torch.cuda.is_available()返回True,中间能踩的坑足够写满两页纸。我前后在不下十台机器上重复过这套流程,有工作站、有租用的云主机、也有自己攒的台式机,每次都会遇到不一样的问题。这篇内容就是把这十几次安装经验里最稳定的路径、最容易翻车的地方、以及那些官方文档不会告诉你的细节,完整地梳理一遍。
这套组合的核心价值在于:显卡驱动负责让系统认识硬件,CUDA 负责让计算任务能调度到显卡,cuDNN 负责加速深度学习的核心算子,PyTorch 则是最终写模型用的框架,而 Anaconda 负责把这些东西隔离在独立环境里互不打架。五者环环相扣,任何一环版本对不上,轻则报错,重则系统进不去图形界面。所以这不是简单的"装五个软件",而是一次需要严格对齐版本的系统工程。
适合读这篇的人有三类:第一类是刚拿到带独显的机器、准备入门深度学习的新手;第二类是之前装过但被版本冲突折磨过、想搞清楚原理的老手;第三类是需要批量部署多台机器、想要一份可复现清单的运维或实验室管理员。不管你属于哪一类,下面的内容都会从"为什么这么做"讲到"具体怎么敲",尽量让你一次装成,而不是反复重装系统。
我先把整体思路讲清楚:驱动和 CUDA 的版本必须匹配,CUDA 和 cuDNN 的版本必须匹配,cuDNN 和 PyTorch 的版本必须匹配,而 Anaconda 负责把 PyTorch 这一层隔离起来。理解了这条链,后面所有的选择就都有了依据,而不是照着某篇教程无脑复制命令。
2. 装之前必须想清楚的版本对齐逻辑
2.1 驱动版本决定了 CUDA 的上限
很多人一上来就问"我该装哪个版本的 CUDA",这个问题其实问反了。正确的顺序是:先看你的显卡型号支持到哪个驱动,再看这个驱动最高支持到哪个 CUDA 版本。NVIDIA 的驱动有一个"CUDA Version"字段,它表示这个驱动能支持的最高 CUDA 运行时版本,你装的 CUDA Toolkit 版本不能超过它。
查看方式很简单,装完驱动后运行:
nvidia-smi输出右上角会有一行CUDA Version: 12.x之类的字样。注意,这个数字不是你系统里装的 CUDA 版本,而是这个驱动能支持的最高CUDA 版本。你可以装比它低的版本,但不能装比它高的。这一点是新手最容易误解的地方,很多人看到这里显示 12.4,就以为自己已经装好 CUDA 12.4 了,其实并没有。
2.2 CUDA、cuDNN、PyTorch 三者的版本三角
这三者的关系可以用一句话概括:PyTorch 官方预编译包只针对特定的 CUDA 版本构建,而每个 CUDA 版本又只对应特定的 cuDNN 版本。所以最省事的做法是反着来——先去 PyTorch 官网看它当前支持哪些 CUDA 版本,选定一个,再倒推 cuDNN 和 CUDA。
举个例子,如果 PyTorch 官方给出的是cu118、cu121、cu124这几个选项,那你就从这三个里挑一个。挑的原则是:优先选和你驱动兼容的、且相对较新的版本。比如你的驱动支持到 12.4,那就选cu124;如果驱动只支持到 12.1,那就选cu121。
下面这张表是我整理的常见组合对照,可以作为参考:
| PyTorch 版本 | 推荐 CUDA | 对应 cuDNN | 最低驱动要求 |
|---|---|---|---|
| 2.0.x | 11.8 | 8.7.x | 520+ |
| 2.1.x | 11.8 / 12.1 | 8.9.x | 530+ |
| 2.2.x | 11.8 / 12.1 | 8.9.x | 535+ |
| 2.3.x | 11.8 / 12.1 | 8.9.x | 545+ |
| 2.4.x | 11.8 / 12.1 / 12.4 | 9.x | 550+ |
提示:这张表是经验总结,实际以 PyTorch 官网和 NVIDIA 官方文档为准。版本迭代很快,装之前一定去官网核对一次。
2.3 为什么一定要用 Anaconda 做隔离
有人会问,既然系统里已经装了 CUDA,为什么还要用 conda 再装一遍?答案是:conda 装的 PyTorch 会自带一份运行时所需的 CUDA 库,它和系统级的 CUDA Toolkit 是两回事。系统级的 CUDA 主要给编译自定义算子、跑nvcc用;而 conda 环境里的 CUDA 运行时是给 PyTorch 直接调用的。
这样做的好处是:你可以在同一台机器上开多个 conda 环境,一个用 CUDA 11.8,一个用 CUDA 12.1,互不干扰。如果全部依赖系统级 CUDA,切换版本就得重装系统级组件,非常痛苦。所以 Anaconda 在这里不是可选项,而是强烈推荐的做法。
3. 显卡驱动的安装与那个最坑的坑
3.1 先禁用开源驱动 nouveau
Ubuntu 默认会加载一个叫nouveau的开源显卡驱动,它会和 NVIDIA 官方驱动冲突。所以第一步是把它拉黑。操作如下:
sudo nano /etc/modprobe.d/blacklist-nouveau.conf写入以下内容:
blacklist nouveau options nouveau modeset=0保存后执行:
sudo update-initramfs -u然后重启。重启后运行lsmod | grep nouveau,如果没有输出,说明禁用成功。这一步没做干净,后面装驱动时会报"模块正在使用"之类的错误,非常难排查。
3.2 用 apt 装驱动还是用官方 runfile
这是第一个需要做选择的地方。我的建议是:优先用 Ubuntu 的"附加驱动"工具或 apt 源安装,而不是去 NVIDIA 官网下.run文件。原因有三点:
第一,apt 装的驱动会和系统内核模块管理机制配合得更好,内核升级后不容易失效;第二,卸载干净,apt remove一条命令搞定;第三,.run文件安装时需要关闭图形界面,在服务器上操作还好,在带桌面的机器上很容易把 X 服务搞崩。
具体操作:
ubuntu-drivers devices这条命令会列出你显卡推荐的驱动版本。然后:
sudo apt install nvidia-driver-550版本号按上一步推荐的来。装完重启,运行nvidia-smi,如果能看到显卡信息和驱动版本,就成功了。
3.3 装完驱动进不去桌面的排查思路
这是最经典的坑:装完驱动重启,卡在登录界面或者黑屏。原因通常是驱动版本和内核不匹配,或者Secure Boot 没关。
排查顺序是这样的:先在启动时进入 GRUB 菜单,选Advanced options,进一个旧内核或者 recovery 模式,能进命令行就行。然后检查dmesg | grep -i nvidia,看有没有报错。如果是 Secure Boot 的问题,进 BIOS 把它关掉即可。如果是内核模块没编译成功,运行:
sudo apt install --reinstall nvidia-dkms-550dkms这个包的作用是在内核更新时自动重新编译驱动模块,装驱动时一定要带上它,能省掉后面很多麻烦。
注意:如果你用的是租用的云主机,通常服务商已经装好了驱动,这一步可以跳过,直接
nvidia-smi验证即可。不要重复安装,否则可能把已有的驱动搞坏。
4. CUDA Toolkit 的安装与路径配置
4.1 选 deb 包还是 runfile
CUDA Toolkit 的安装方式主要有两种:deb 网络安装包和 runfile 本地安装包。我的经验是:如果你只是为了让 PyTorch 能跑,其实可以不装系统级 CUDA,因为 conda 环境里会自带。但如果你需要编译自定义 CUDA 算子、或者用nvcc编译代码,那就必须装系统级的。
装的话,推荐用 runfile 方式,因为它不会污染 apt 源,卸载也干净(sudo /usr/local/cuda-X.X/bin/uninstall_cuda_X.X.pl)。下载时注意选择runfile (local),并且在安装选项里取消勾选 Driver,因为驱动我们已经单独装过了,重复装会冲突。
安装命令:
sudo sh cuda_12.1.0_530.30.02_linux.run在交互界面里,把 Driver 那一项的勾去掉,只保留 CUDA Toolkit。
4.2 环境变量到底该写哪几个
装完 CUDA 后,需要把路径加到环境变量里。编辑~/.bashrc:
export PATH=/usr/local/cuda-12.1/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH这里有两个细节值得说。第一,不要用/usr/local/cuda这个软链接,直接写具体版本号,因为软链接会随着你装新版本而改变,导致环境变量指向混乱。第二,LD_LIBRARY_PATH这一项在有些教程里说不用加,但如果你要编译自定义算子,不加会找不到库。加了之后记得source ~/.bashrc生效。
验证:
nvcc -V能输出版本信息就说明配置成功。
4.3 多版本 CUDA 共存的切换方法
如果你机器上装了多个 CUDA 版本,可以通过软链接切换:
sudo rm -rf /usr/local/cuda sudo ln -s /usr/local/cuda-12.1 /usr/local/cuda但更推荐的做法是在 conda 环境里用环境变量覆盖,这样切换环境时自动切换 CUDA,不用动系统软链接。具体就是在激活环境后设置CUDA_HOME,后面讲 conda 时会提到。
5. cuDNN 的放置与验证
5.1 下载对应版本并解压
cuDNN 需要注册账号才能下载,选版本时严格对应你装的 CUDA 版本。下载下来通常是一个 tar 包,解压后是cuda目录,里面有include和lib64。
5.2 拷贝到 CUDA 目录的正确姿势
sudo cp cuda/include/cudnn*.h /usr/local/cuda-12.1/include sudo cp cuda/lib64/libcudnn* /usr/local/cuda-12.1/lib64 sudo chmod a+r /usr/local/cuda-12.1/include/cudnn*.h sudo chmod a+r /usr/local/cuda-12.1/lib64/libcudnn*这里有个容易忽略的点:权限。如果不加chmod a+r,普通用户运行时可能读不到这些库,报权限错误。另外,拷贝时用cudnn*通配符,因为 cuDNN 8 之后文件被拆成了多个,手动一个个拷容易漏。
验证:
cat /usr/local/cuda-12.1/include/cudnn_version.h | grep CUDNN_MAJOR -A 2能看到版本号就说明放对了。
5.3 为什么 conda 环境里还要再装一次
前面说过,conda 装的 PyTorch 会自带 CUDA 和 cuDNN 运行时。所以系统级的 cuDNN 主要是给编译场景用的。如果你只是跑 PyTorch,其实系统级 cuDNN 装不装都行。但装了没坏处,而且能避免一些奇怪的链接错误。我的习惯是:系统级装一份作为兜底,conda 环境里让 PyTorch 自带一份作为实际使用,两者互不干扰。
6. Anaconda 与 PyTorch 环境的落地
6.1 安装 Anaconda 与初始化
下载 Anaconda 的 Linux 安装脚本,执行:
bash Anaconda3-2024.02-1-Linux-x86_64.sh一路回车,最后问是否conda init时选 yes。然后source ~/.bashrc,命令行前面会出现(base)字样。
这里有个小建议:把 base 环境的自动激活关掉,因为 base 环境最好保持干净,不要往里装东西。执行:
conda config --set auto_activate_base false6.2 创建独立环境并安装 PyTorch
conda create -n dl python=3.10 conda activate dl然后去 PyTorch 官网复制对应的安装命令,比如:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121注意这里用的是 pip 而不是 conda。原因是pip 源的 PyTorch 更新更及时,且 wheel 包体积更小、安装更快。conda 源有时候版本滞后,而且解析依赖很慢。这是我踩过几次坑之后的固定选择。
6.3 验证是否真的用上了显卡
装完后,运行一段验证代码:
import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果第二行输出True,第三行输出你的显卡型号,就大功告成了。如果输出False,往下看排查部分。
7. 装完跑不起来时的排查链路
7.1torch.cuda.is_available()返回 False 的四种可能
这是最高频的问题,按可能性从高到低排查:
第一种,驱动没装好或版本太低。回到nvidia-smi确认能正常输出。如果这条命令都报错,那问题在驱动层,跟 PyTorch 无关。
第二种,PyTorch 装成了 CPU 版本。运行pip list | grep torch,看版本号后面有没有+cu121之类的后缀。如果没有,说明装的是 CPU 版,卸载重装。
第三种,CUDA 版本和 PyTorch 不匹配。比如你装的是cu121的 PyTorch,但系统驱动只支持到 11.8,就会失败。这种情况要么升级驱动,要么换 PyTorch 版本。
第四种,环境变量污染。有时候系统里残留的LD_LIBRARY_PATH指向了错误的 CUDA 库,导致 PyTorch 加载了不兼容的版本。可以在 Python 里运行import os; print(os.environ.get('LD_LIBRARY_PATH'))检查。
7.2 报libcudnn.so找不到怎么办
这个错误通常出现在你手动编译了依赖 cuDNN 的代码时。解决方法是确认/usr/local/cuda-12.1/lib64在LD_LIBRARY_PATH里,并且该目录下确实有libcudnn.so文件。如果文件在但还报错,运行sudo ldconfig刷新动态链接库缓存。
7.3 显存被占满但进程已退出
有时候训练脚本崩了,但显存没释放,nvidia-smi显示还有进程占着。这时候用:
sudo fuser -v /dev/nvidia*找到占用进程的 PID,然后kill -9掉。如果杀不掉,说明是僵尸进程,只能重启。这也是为什么我建议每个实验都在独立的 conda 环境里跑,出问题时直接删环境重建,比修系统级依赖快得多。
8. 我反复安装十几次后沉淀下来的几条经验
第一条,版本对齐永远比安装速度重要。我见过太多人为了图快,随便找了个教程就照着敲,结果版本对不上,折腾一整天。花十分钟去官网核对版本号,能省下几个小时。
第二条,驱动用 apt 装,CUDA 用 runfile 装,PyTorch 用 pip 装。这是我试过最稳的组合。apt 管驱动能自动处理内核更新,runfile 管 CUDA 能干净卸载,pip 管 PyTorch 能拿到最新版本。
第三条,每装完一层就验证一次。装完驱动跑nvidia-smi,装完 CUDA 跑nvcc -V,装完 PyTorch 跑torch.cuda.is_available()。不要等全部装完再一起验证,那样出了问题根本不知道是哪一层的锅。
第四条,把整个流程写成脚本。我现在有一份自己的setup.sh,里面按顺序写好所有命令,新机器上跑一遍就行。但脚本里要留好版本号变量,方便随时改。这样下次再装,十分钟搞定,不用重新回忆每一步。
第五条,善用 conda 的环境导出。环境配好后运行conda env export > environment.yml,下次直接conda env create -f environment.yml就能复现。不过要注意,导出的文件里会包含本地路径,跨机器用时需要手动清理一下。
最后分享一个我最近才用上的小技巧:如果你不确定某个 CUDA 版本和 PyTorch 版本是否兼容,可以在一个临时 conda 环境里先装一遍试试,验证通过再正式装到主环境。这样试错成本极低,删掉临时环境就行,不会污染你正在用的环境。这个习惯帮我避免了好几次把主环境搞崩的惨剧。