1. 先理清依赖链,别上来就点下载
深度学习环境搭建翻车,九成不是因为命令敲错,而是版本关系没理清楚。我在实验室和公司来回折腾过十几台机器,从 1080Ti 到 4060Ti,从 Ubuntu 18.04 到 22.04,Windows 上也装过,最常见的场景就是:显卡驱动装好了,pip install torch也跑完了,结果torch.cuda.is_available()返回一个冷冰冰的False;或者 TensorFlow 一 import 就甩出libcudart.so.11.0: cannot open shared object file。这类问题排查起来其实不复杂,难的是很多人一开始就没把 CUDA、cuDNN、驱动、框架这四者的关系搞清楚。
这篇内容我打算把自己实际用过的完整流程写下来,包含 CUDA Toolkit 的下载安装、cuDNN 的部署、PyTorch 与 TensorFlow 的适配,以及一堆踩过的坑。适合刚接触 GPU 训练的同学,也适合手上有多台机器、需要维护多套环境的同行。看完你应该能做到:明确自己机器该装哪个版本、装完之后能自证生效、遇到报错知道往哪个方向查。
1.1 四个概念先钉死,不然后面全是糊涂账
显卡驱动(Driver):操作系统和显卡之间的翻译官,由 NVIDIA 提供,nvidia-smi看到的CUDA Version: 12.4指的是这个驱动最多能支持的 CUDA Runtime 版本,注意是上限,不是你已经装了什么。
CUDA Toolkit:真正提供nvcc编译器、cudart运行库、cublas/cufft这些数学库、头文件和 samples 的一整套 SDK。我们自己手动下载安装的,就是它。
cuDNN:NVIDIA 在 CUDA 基础上封装的深度神经网络加速库,卷积、RNN、Attention 这些算子的高性能实现都在里面。它必须匹配 CUDA 的主版本号,比如 cuDNN 8.9.x 对应 CUDA 11.x,cuDNN 9.x 对应 CUDA 12.x,装错大版本会直接报符号找不到。
PyTorch / TensorFlow:框架在打包时就已经链接了某个特定版本的 CUDA 和 cuDNN。运行时它会去LD_LIBRARY_PATH里找对应版本的动态库。所以框架版本、CUDA 版本、cuDNN 版本三者要形成闭环。
关键认知:
nvidia-smi里的 CUDA Version 是驱动能力上限,nvcc -V里的才是你实际安装的 Toolkit 版本。这两个数字不一样是正常的,但后者不能大于前者。
1.2 主流框架的版本对照,直接抄
下面这张表是我从官方安装页和 release note 里整理出来的,涵盖了目前还在被广泛使用的组合:
| 框架版本 | 推荐 CUDA | 匹配 cuDNN | 说明 |
|---|---|---|---|
| PyTorch 2.0.x | 11.7 / 11.8 | 8.5+ | 老项目居多,稳定性好 |
| PyTorch 2.1 ~ 2.3 | 11.8 / 12.1 | 8.7 ~ 8.9 | 目前最通用的组合 |
| PyTorch 2.4 ~ 2.6 | 11.8 / 12.4 | 9.x | 新卡建议 12.4 |
| TensorFlow 2.13 ~ 2.15 | 11.8 | 8.6 ~ 8.9 | TF 对 12.x 支持较晚 |
| TensorFlow 2.16+ | 12.3 | 8.9+ | 需要配合 Keras 3 |
选版本的顺序建议是倒着选:先确定你要跑的代码用哪个框架版本(很多论文代码写死了 torch 版本),再去看这个框架版本官方推荐哪个 CUDA,最后回过头确认自己的驱动够不够。而不是反过来先装最新 CUDA,然后发现框架根本不支持。
1.3 驱动版本决定你能用哪一档 CUDA
驱动向下兼容,装新驱动能跑老 CUDA,但老驱动跑不了新 CUDA。常见驱动对应的上限:
| 驱动版本 | 支持的最高 CUDA |
|---|---|
| 470.x | 11.4 |
| 515.x | 11.7 |
| 525.x | 12.0 |
| 535.x | 12.2 |
| 545.x | 12.3 |
| 550.x | 12.4 |
如果你需要 CUDA 12.4 但驱动是 535,有两个选择:升级驱动,或者退一步用 CUDA 11.8 加对应框架版本。我个人更推荐升级驱动,因为驱动升级基本无损,而 CUDA 降级往往要重新配环境。至于搜索里常出现的 CUDA 13.0,属于比较新的版本,除非你确认框架已经明确支持,否则不建议主力环境上,踩坑成本太高。
2. 装之前,先把机器摸清楚
动手前花五分钟做体检,能省下后面两小时的排错。
2.1 三条命令看清家底
# 1. 看显卡型号和驱动支持的 CUDA 上限 nvidia-smi # 2. 看是否已经装了 CUDA Toolkit,装了哪个版本 nvcc -V # 3. 看系统里共存了哪些 CUDA ls -l /usr/local | grep cuda如果你在 WSL2 里,nvidia-smi能正常输出,但/usr/local下通常是空的,说明你只有驱动透传、没装 Toolkit。WSL 下装 CUDA Toolkit 和原生 Linux 流程一样,只是建议用官方 WSL 专用源,避免驱动被覆盖。
2.2 三种安装方式,各有各的适用场景
| 方式 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
.run文件 | 可控性强,可指定路径,可静默安装 | 需要手动处理图形界面 | 服务器、多版本共存 |
deb包 | 走包管理器,依赖自动处理 | 容易和系统驱动打架 | 单版本、图省事的桌面 |
| conda 安装 | 环境隔离彻底,不污染系统 | 占空间,路径较隐蔽 | 只需跑框架、不写 CUDA 代码 |
我个人的习惯是:系统层装一份.run版的 CUDA(比如 11.8),作为主力环境;实验性的版本用 conda 装cudatoolkit到独立 env 里。这样既不影响系统,也方便切换。
注意:conda 装的
cudatoolkit只包含运行库,不含nvcc。如果你要编译自定义算子或者跑 CUDA samples,必须用.run或deb装完整 Toolkit。
2.3 老版本 CUDA 去哪找
NVIDIA 的官方下载页默认只显示最新的几个版本。要装老版本,去 archive 页面,把地址里的版本号替换成你需要的即可。下载时优先选择带完整版本号的 local 安装包,比如cuda_11.8.0_520.61.05_linux.run,注意文件名里的第二个数字是配套驱动版本,如果比你现在驱动新,安装时记得取消勾选驱动那项。
3. CUDA Toolkit 安装实操
以 Ubuntu 22.04 上装 CUDA 11.8 为例,这套流程我在多台机器上跑过,比较稳。
3.1 .run 方式的完整步骤
# 1. 下载(版本号自己替换) wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run # 2. 校验完整性,这一步千万别省 sha256sum cuda_11.8.0_520.61.05_linux.run # 对比官方页面给出的哈希值 # 3. 赋予执行权限 chmod +x cuda_11.8.0_520.61.05_linux.run # 4. 如果有图形界面,先切到多用户模式 sudo systemctl isolate multi-user.target # 5. 静默安装,只装 Toolkit,不装驱动 sudo sh cuda_11.8.0_520.61.05_linux.run --silent --toolkit --override # 6. 装完切回图形界面 sudo systemctl isolate graphical.target关于第五步的参数,解释一下:--silent表示无交互,--toolkit表示只装 Toolkit 组件,--override表示忽略编译器版本检查——这个参数在系统 GCC 版本比 CUDA 要求的新时特别有用,否则会直接退出报错。
如果你需要跑的代码要编译 samples,那就把--toolkit换成--toolkit --samples。不过实测很多情况下 samples 里的一些例子在系统 GCC 版本较新时编不过,纯粹学习用途的话不必强求。
3.2 环境变量写对,nvcc 才能找到
安装完成后,nvcc不会自动进 PATH,需要手动加。编辑~/.bashrc:
export PATH=/usr/local/cuda-11.8/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH这里我建议写死具体版本号而不是用/usr/local/cuda这个软链接。原因是多版本共存时,软链接经常被某个安装脚本偷偷改掉,导致你的环境莫名其妙换了版本,排查起来非常费劲。写死之后,切换版本只需要改这两行并source ~/.bashrc。
改完执行:
source ~/.bashrc nvcc -V看到release 11.8就说明装好了。
3.3 Windows 下的两个细节
Windows 上安装相对简单,双击 exe 一路点,但有两个地方要留意。
第一,安装选项里会让你勾选 Visual Studio Integration。如果你没装 VS 或者版本不匹配,这一步可能报no supported version of visual studio was found。这个报错不影响 CUDA 本身使用,直接无视或者取消勾选即可,PyTorch 照样跑得起来。真要写 CUDA C++ 代码再单独处理。
第二,选择自定义安装时,把 Driver 那一项取消掉。因为安装包里自带的驱动版本可能比你现在用的旧,覆盖后反而降级了。勾选 CUDA 下的 Core、Runtime、Development、Libraries 就够了。
装完后验证:
nvcc -V # 或者看默认路径 dir "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA"3.4 多版本共存怎么管
服务器上经常需要 11.8 和 12.1 两套环境。装的时候给不同的--toolkitpath:
sudo sh cuda_12.1.0_530.30.02_linux.run --silent --toolkit --toolkitpath=/usr/local/cuda-12.1 --override然后维护/usr/local/cuda这个软链接指向当前默认版本:
sudo rm -f /usr/local/cuda sudo ln -s /usr/local/cuda-11.8 /usr/local/cuda切版本时改软链接再刷新环境变量。实测多版本之间最常见的冲突不是库本身,而是LD_LIBRARY_PATH里旧版本路径排在前面,导致运行时加载了错误版本的libcudart。所以我在每个 conda 环境的激活脚本里都会显式前置对应的 CUDA 路径。
4. cuDNN 的安装其实就三步
cuDNN 装起来比 CUDA 简单得多,本质就是拷文件。
4.1 下载与解压
登录 NVIDIA 开发者账号后下载对应版本的 cuDNN。Linux 下一般是 tar 包:
tar -xvf cudnn-linux-x86_64-8.9.7.29_cuda11-archive.tar.xz解压后目录结构里会有include/和lib/两个关键目录,包含cudnn.h和libcudnn.so.*。
4.2 拷贝文件到 CUDA 目录
cd cudnn-linux-x86_64-8.9.7.29_cuda11-archive sudo cp include/cudnn*.h /usr/local/cuda-11.8/include/ sudo cp lib/libcudnn* /usr/local/cuda-11.8/lib64/ sudo chmod a+r /usr/local/cuda-11.8/include/cudnn*.h sudo chmod a+r /usr/local/cuda-11.8/lib64/libcudnn*权限那两行别漏,a+r让所有用户可读,否则非 root 用户跑训练时会报权限拒绝。
4.3 验证 cuDNN 生效
cat /usr/local/cuda-11.8/include/cudnn_version.h | grep CUDNN_MAJOR -A 2或者写个 CUDA samples 里的deviceQuery跑一下,输出里会带 cuDNN 版本信息。更直接的办法是跑框架代码,PyTorch 能用 GPU 就说明 cuDNN 链接正常。
经验:cuDNN 9.x 的目录结构和 8.x 有变化,9.x 把部分库合并了。如果你从 8.x 升到 9.x,记得先清掉旧的
libcudnn*,否则新旧库混在一起会出现符号冲突,报错信息还特别难懂。
5. PyTorch 与 TensorFlow 的适配安装
到了这一步,前面铺的路才开始派上用场。
5.1 conda 还是 pip
我现在的做法是:用 conda 建虚拟环境,用 pip 装框架。
conda create -n pt118 python=3.10 -y conda activate pt118原因很实际——conda 源里的 PyTorch 更新往往滞后,而且有时候会把cudatoolkit一并装上,路径指向 conda 内部,和系统 CUDA 混用容易乱。用 pip 从官方源装,wheel 里自带对应 CUDA 运行库,路径清晰。
如果你实在网络环境受限,可以在
~/.pip/pip.conf里配置镜像源加速下载,这属于常规操作,不影响包本身内容。
5.2 PyTorch 的安装与自证
去 PyTorch 官网的 install 页面选择对应组合,会生成一行命令,比如:
pip install torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 --index-url https://download.pytorch.org/whl/cu118装完必须验证:
import torch print(torch.__version__) print(torch.version.cuda) # 看链接的 CUDA 版本 print(torch.cuda.is_available()) # 核心指标 print(torch.cuda.get_device_name(0))如果is_available()是 False,按这个顺序查:驱动是否正常(nvidia-smi能出结果)、装的包是不是 GPU 版(torch.version.cuda是否为 None)、LD_LIBRARY_PATH是否被别的 CUDA 污染。
5.3 TensorFlow 的安装要更谨慎
TensorFlow 对版本对应关系比 PyTorch 更敏感,装错基本必报错。安装用:
pip install tensorflow==2.15.0注意 TF 2.15 及之前,tensorflow包默认就是 GPU 版,不需要装tensorflow-gpu(这个包在新版已经废弃)。验证:
import tensorflow as tf print(tf.__version__) print(tf.config.list_physical_devices('GPU'))输出里有 GPU 设备就对了。如果只有 CPU,通常是 libcudart 或 libcudnn 版本不匹配,报错信息里会明确告诉你缺哪个版本。照着它要的版本去补对应 CUDA/cuDNN 即可。
5.4 同时装两个框架会打架吗
会。主要冲突点在 protobuf、numpy 和 cuDNN 版本上。PyTorch 和 TF 对 protobuf 的版本要求经常不一致,装在一起容易出现Descriptors cannot be created directly之类的报错。
我的建议是分成两个独立的 conda 环境,各自装一套。虽然占点磁盘,但省心。如果非要在同一环境跑,那就先装 TF 再装 PyTorch,并且锁定 protobuf 到一个两边都能接受的版本。
6. 踩坑实录与排查清单
这部分是整篇里我认为最有价值的内容,都是真金白银换来的。
6.1gzip: stdin: invalid compressed data到底怎么回事
这个报错出现在运行.run安装包时,很多人在搜索里都遇到过。原理是:.run文件本质是一个自解压的 shell 脚本,里面嵌套了 gzip 压缩的二进制数据。当 gzip 解压失败时,说明文件本身损坏或者不完整。
根本原因通常是下载过程中断,或者下载工具对响应做了错误处理,导致文件字节数不足。解决办法很简单,但很多人不走这一步:
# 看文件大小是否和官方一致 ls -lh cuda_11.8.0_520.61.05_linux.run # 校验哈希 sha256sum cuda_11.8.0_520.61.05_linux.run只要哈希对不上,就是下载问题,换网络或者重新下载,别试图用参数绕过,绕不过去的。我见过有人反复重装十几次,其实每次用的都是同一个损坏文件。
6.2 装了 GPU 版却检测不到设备
排查顺序按这个来,基本能定位:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
torch.cuda.is_available()为 False | 驱动异常 | 跑nvidia-smi确认 |
| 同上,但 nvidia-smi 正常 | 装了 CPU 版 torch | 重装 GPU 版 wheel |
| import 报找不到 libcudart | LD_LIBRARY_PATH 错 | 检查路径优先级 |
| TF 报 cuDNN 版本不符 | cuDNN 大版本错 | 按报错信息换版本 |
| 训练中途 OOM | 批大小过大 | 减小 batch 或开梯度累积 |
6.3 找不到 CUDA samples
从 CUDA 11.x 开始,samples 不再随安装包默认部署到/usr/local/cuda/samples。需要自己去 GitHub 上的cuda-samples仓库 clone,然后make编译。如果你只是用框架训练,这部分完全可以跳过,不用纠结。
6.4 几个容易忽略的经验
一是不要在装 CUDA 前乱升级系统 GCC。CUDA 对 GCC 版本有上限要求,Ubuntu 22.04 默认 GCC 11,装老版本 CUDA 时可能超出支持范围,这时候--override就派上用场了。但更稳妥的做法是装个匹配版本的 GCC 并用--compiler-bindir指定。
二是 WSL2 下不要装 Linux 驱动。WSL 的驱动由 Windows 宿主透传,重复安装 Linux 驱动会导致nvidia-smi失效。
三是 40 系显卡(比如 4060Ti)计算能力是 8.9,建议至少 CUDA 11.8 起步,老版本 CUDA 可能不认识这个架构,编译自定义算子时会报unsupported gpu architecture。这种情况需要在编译参数里加上-gencode arch=compute_89,code=sm_89。
四是迁移环境时不要直接拷/usr/local/cuda。路径里的绝对路径会被写进很多配置文件,换个目录就失效。正确做法是在新机器上按版本重装一遍,然后把 conda 环境的environment.yml导过去。
7. 我个人的版本选择习惯
折腾了这么多台机器,我现在固定一套打底组合:驱动升到最新稳定版,CUDA 用 11.8 作为主力,cuDNN 用 8.9,PyTorch 跟着官方 wheel 走,TensorFlow 单独隔一个环境装。除非项目明确要求 CUDA 12.x,否则不轻易动主力环境。
原因很朴素:11.8 这个版本的生态兼容性是目前最好的,绝大多数论文代码、开源项目都在这上面验证过,遇到问题的搜索结果也最多。新版本虽然性能上可能有提升,但对一线干活的人来说,环境一次配好、三个月不再碰,比多那百分之几的算力重要得多。
如果你手上只有一台机器,还要同时跑 TF 和 PyTorch,那就老老实实建两个 conda 环境,别嫌麻烦。省下来的排查时间,够你多跑好几轮实验了。环境这东西,稳定永远排在时髦前面。