装机这事儿,说难也真不难,说简单吧,我见过太多人在torch.cuda.is_available()这一行上卡到怀疑人生。PyTorch 的环境安装,尤其是 CPU 版本和 GPU 版本的区别、CUDA 和 cuDNN 的搭配,网上教程互相抄、互相矛盾的情况比比皆是。有人跟着教程装完发现import torch没报错,但一跑 GPU 就报AssertionError,有人明明有显卡却一直装成 CPU 版。说到底,大部分问题不在命令本身,而在于没搞明白显卡驱动、CUDA、cuDNN 和 PyTorch 这几个东西之间到底谁依赖谁。
这篇文章把我这几年折腾环境的一套完整流程写出来,不分平台地覆盖 Windows 和 Linux,从环境侦查、CUDA/cuDNN 安装到 PyTorch 的 CPU/GPU 版本安装,再到验证与排错,每一步都讲清楚为什么这么做。适合刚入门深度学习、被环境配置劝退的新手,也适合帮同事排查装环境问题的老手——你可以直接照着步骤抄,也可以只挑自己需要的坑来看。
1. 装 PyTorch 前,先弄清楚驱动、CUDA、cuDNN 三个角色的关系
1.1 这一步没想清楚,后面全是烂账
很多人一开始就把 CUDA 理解成一个"装了就有的东西",然后照着教程一路装下去。但实际上一台机器上跟 GPU 计算相关的有四层东西:最底层是 NVIDIA 显卡驱动,它负责操作系统和 GPU 之间的通信;往上一层是 CUDA Toolkit,它是开发库和编译器套件;再往上是 cuDNN,它是针对深度学习中卷积、池化、循环网络等做了深度优化的加速库;最顶层才是 PyTorch,它把前面这些都封装成torch这个包。
打个对照,驱动是高速公路本身,CUDA Toolkit 是普通货车,cuDNN 是经过专门调校的物流车队,PyTorch 是你实际要开的货柜车。没有公路,后面全都白搭;只有公路,你又缺运输工具;有了货但运输效率低,cuDNN 就是那个提升装卸效率的关键环节。
这里有一个非常关键、也最容易被教程误导的点:你用 pip 安装的 PyTorch GPU 版本,默认就自带了 CUDA 运行时和 cuDNN 库。也就是说,普通用户想在 PyTorch 里用 GPU,系统级单独安装 CUDA Toolkit 并不是必需的。真正需要单独装 CUDA Toolkit 的场景是:你要自己编译 CUDA 扩展算子、要跑 NVIDIA 的性能分析工具、或者某些第三方库依赖系统 CUDA。这一点我后面专门展开讲,现在你只需要记住,别盲目跟着教程把几个 G 的 CUDA Toolkit 装完又删。
1.2 CPU 版和 GPU 版到底差在哪
CPU 版 PyTorch 用 CPU 做张量计算,靠的是一系列底层数学库(比如 MKL-DNN/oneDNN 这套优化),只要你的机器是常见的 x86 架构,装上就能用,没有显卡也能跑。GPU 版则在内部调用 CUDA 相关的算子,把大规模矩阵运算并行丢给 GPU 执行。差别在哪儿?举个实际例子,一个 5000×5000 的矩阵乘法,在普通 CPU 上可能几百毫秒到一两秒,在消费级显卡上只要几毫秒,训练神经网络的时候这个差距会放大到几十倍甚至上百倍。
所以判断标准很简单:纯做数据处理、用小模型做推理、或者机器上根本没有 NVIDIA 显卡,CPU 版完全够用;要训练模型,尤其是卷积网络、Transformer 这类规模较大的模型,老老实实装 GPU 版。另外提一句,苹果芯片的用户就别指望 CUDA 了,直接装 CPU 版,新版本 PyTorch 支持用torch.backends.mps走苹果自家加速。
1.3 NVIDIA 显卡之外的选择,先说清楚避免浪费时间
CUDA 是 NVIDIA 家的技术栈,AMD 显卡走 ROCm 路线,Intel 显卡有自己的一套扩展,两者在 PyTorch 的生态支持上都远不如 CUDA 完善,日常使用经常会遇到某个算子不支持。如果你手头只有 AMD 或 Intel 核显,劝你直接装 CPU 版,先把代码跑通,等到有 NVIDIA 显卡的机器上再切 GPU。这个选择不是瞧不起谁,而是生态成熟度决定的,我用 AMD 卡折腾过一周,最后时间全花在刷开源 issue 上,不值。
2. CPU 版本安装:最简单的部分也藏着几个细节
2.1 先确认 Python 版本,别装完才发现不支持
CPU 版安装虽然命令简单,但它对 Python 版本有硬性要求。PyTorch 每个版本都有对应的 Python 支持范围,比如新版本 PyTorch 通常支持 Python 3.9 到 3.12,老版本可能只支持到 3.10。我见过有人用 Python 3.13 装老版本 torch,装完一运行直接报ModuleNotFoundError。
最稳的选择是建一个独立的虚拟环境,Python 版本选 3.10 或 3.11,这两个版本兼容面最广。用 conda 的话:
conda create -n torch_cpu python=3.10 conda activate torch_cpu如果是纯 pip 环境,也可以用python -m venv venv创建。强烈建议不要直接装进系统 Python 或 base 环境,深度学习项目的依赖关系很脆弱,独立环境隔离是省心的第一步。
2.2 pip 安装命令与国内镜像加速
CPU 版最简单的装法:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu这里用--index-url是指定从 PyTorch 官方 wheel 源取包,保证拿到的是 CPU 版本。国内用户如果觉得官方源慢,可以用阿里云镜像:
pip install torch torchvision torchaudio -i https://mirrors.aliyun.com/pypi/simple这里有个容易混淆的地方:普通 PyPI 镜像站上的 torch 到底是 CPU 版还是 GPU 版,在不同平台默认情况不一样。为了不给自己埋雷,明确要 CPU 版就指定官方 CPU 源,明确要 GPU 版就指定官方对应的 cu 开头的源。别混用,混用装错版本来回卸载费的时间远超过下载慢等的那点时间。
2.3 装完别急着跑模型,先做三行验证
装好以后,打开 Python 验证:
import torch print(torch.__version__) # 例如 2.4.1+cpu print(torch.version.cuda) # CPU 版这里打印 None print(torch.backends.mkldnn.is_available()) # CPU 加速库是否可用torch.__version__末尾带+cpu说明装对了。torch.version.cuda是 None 说明这个包没有带 CUDA 运行时,符合预期。mkldnn.is_available()返回 True 说明 CPU 数学加速库正常,这种状态下跑 CPU 推理已经是 PyTorch 能给出的最佳性能。
2.4 关于 conda 安装 CPU 版的补充说明
用 conda 装 CPU 版也可以,但要注意 channel 顺序:
conda install pytorch torchvision torchaudio cpuonly -c pytorchcpuonly这个包就是用来标记不要拉取 CUDA 相关依赖的。我的实际体验是,CPU 版用 pip 装比 conda 省事,因为 conda 解析依赖有时候会顺带把 CUDA 组件也解析进来,尤其是你之前装过 GPU 版的情况下,环境容易变乱。CPU 版这种简单场景,优先 pip。
3. GPU 版本安装前的环境侦查:用命令确认能装什么
3.1 三步侦查:显卡型号、驱动版本、操作系统
GPU 版装之前,先花五分钟把环境摸清楚,能避免后面 80% 的报错。
第一步,确认有没有 NVIDIA 显卡以及驱动是否正常。Windows 在 cmd 或 PowerShell 里执行:
nvidia-smiLinux 也一样:
nvidia-smi如果提示nvidia-smi不是内部或外部命令,说明驱动没装或者没进 PATH。能正常输出的话,看表格里这几项信息:
| 信息位置 | 代表什么 | 你需要关注什么 |
|---|---|---|
| 左上角 GPU 型号 | 显卡型号 | 确认是 NVIDIA,且不是太古董的卡 |
| 右上角 Driver Version | 驱动版本 | 决定支持到多新的 CUDA |
| 右上角 CUDA Version | 驱动能支持的最高 CUDA 版本 | 注意这不是已装的 CUDA Toolkit 版本 |
第二步,确认操作系统。CUDA 不支持 macOS(截至现在都是如此),如果你在 macOS 上,直接放弃 GPU 版。Windows 和 Linux 都支持得很好,但两者驱动安装方式、环境变量配置方式有差别。Windows 系统里我建议顺便确认下 WSL 是不是 WSL2,因为很多人是在 WSL 里跑深度学习,这个后面排错章节会提到。
第三步,确认显卡代际。老显卡(比如 GTX 10 系)虽然仍然被新 CUDA 支持,但算力弱,追求性能的同学心里要有数。查看算力等级用:
nvidia-smi --query-gpu=name,compute_cap --format=csv3.2 驱动版本与 CUDA 版本的上限关系:最常见的误解
nvidia-smi右上角显示的 "CUDA Version" 是大多数人第一个理解错误的地方。它显示的是当前驱动最多支持到哪个 CUDA 版本,而不是系统里装了哪个 CUDA 版本。驱动是新版本(比如支持 CUDA 12.4),但你系统里一个 CUDA Toolkit 都没装,它照样显示一个很高的数字,这个人很有可能会误以为"我已经有 CUDA 了"。
反过来,驱动版本如果太老,支持的最高 CUDA 版本低于你 PyTorch 需要的最低版本,那就是真有问题了。不同 CUDA 版本对驱动的最低要求大致是这样:
| CUDA 版本 | Linux 驱动最低版本 | Windows 驱动最低版本 |
|---|---|---|
| 11.8 | 520.61.05 | 520.06 |
| 12.1 | 530.30.01 | 531.14 |
| 12.4 | 550.54.15 | 551.61 |
这是个近似参考,实际以 NVIDIA 官方文档为准。日常情况下,我建议把驱动更新到比较新的稳定版(比如 560 以上),这样无论选哪个 CUDA 版本的 PyTorch 都不会因为驱动太老而卡住。
3.3 驱动太老的升级姿势,Win 和 Linux 分开说
Windows 下升级驱动最省心的是去 NVIDIA 官网下载对应型号的最新驱动包,或者用厂商提供的更新工具。装的时候选"自定义安装",勾选"执行清洁安装",可以避免旧驱动残留。装完重启,再跑一次nvidia-smi确认版本号变了。
Linux 下分两种情况。桌面发行版建议优先用系统自带的驱动管理方式,Ubuntu 用户可以在"软件和更新"的"附加驱动"里选一个推荐的 NVIDIA 驱动;也可以在终端用sudo ubuntu-drivers autoinstall。如果你需要最新驱动,可以去 NVIDIA 官网下载 runfile 手动安装,但 runfile 安装方式比较粗暴,会覆盖系统自带驱动,遇到内核更新后驱动失效是常有的事,新手不建议走这条路。装完之后同样验证nvidia-smi。笔记本双显卡(独显 + 核显)用户注意,有些机器需要在 BIOS 里开启独显直连模式,或者在系统里手动指定程序用独立显卡,否则即便驱动装好,深度学习任务还是会时不时抽风。
4. CUDA 和 cuDNN 的安装实操:不只是下载文件那么简单
4.1 到底要不要装系统级 CUDA:两类用户的答案不一样
我要先泼一盆冷水:绝大多数只跑 PyTorch 的用户,真的不需要单独下载安装十几个 G 的 CUDA Toolkit。因为在你pip install torch --index-url .../cu121之后,安装包里已经包含了 CUDA 运行时库和 cuDNN。你可以直接跑torch.cuda.is_available()验证,大概率是 True。很多网上教程让你装 CUDA,一部分是历史遗留习惯(老版本 PyTorch 和源码编译时代确实需要),一部分是照搬没思考。
哪些人需要系统级 CUDA?三类:
- 要自己写 CUDA kernel 并用
nvcc编译的,比如做算子开发; - 用了需要实时编译第三方 CUDA 扩展的库,编译时找不到 nvcc 会直接报错;
- 要做性能分析,用
nsys、ncu这类 NVIDIA 工具。
你自己判断一下,不属于这三类就跳过 4.2 和 4.3,直接看第 5 节装 PyTorch。想看明白 CUDA 和 cuDNN 安装全流程的,继续往下。我会用最典型的 CUDA 12.1 + cuDNN 8.9 组合做示例。
4.2 CUDA Toolkit 安装流程(以 12.1 为例)
先去 NVIDIA 官网的 CUDA Toolkit 归档页面,选 12.1 版本,再选你的操作系统和安装方式。Windows 选 exe(local) 或 exe(network),Linux 选 runfile(local) 或 deb(local)。本地包虽然大,但安装更稳,网络包安装时要现场下载,网络不好容易中断,我推荐本地包。
Windows 安装需要注意一个坑:安装向导里默认会勾选驱动组件。如果你刚更新过驱动,一定要在"自定义"里把 Driver components 取消勾选,只保留 CUDA 相关的组件(如 Development、Runtime、Visual Studio Integration 等)。否则安装器可能把你的新驱动降级成它自带的旧驱动,装完 PyTorch 反而报 CUDA 版本不支持,这是最冤的一种情况。
Linux 用 runfile 安装:
sudo sh cuda_12.1.0_530.30.08_linux.run --toolkit --silent注意--toolkit这个参数,它告诉安装器只要 Toolkit 组件、不要覆盖驱动。如果用交互式安装,界面上勾选时同样把 Driver 那一项去掉。装完默认安装在/usr/local/cuda-12.1,/usr/local/cuda是指向它的软链接。
装完设置环境变量。Linux 在~/.bashrc里加:
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc。Windows 安装器一般会自动把CUDA_PATH环境变量配好,你也可以在"系统属性 - 环境变量"里手动确认,把C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\bin加进 PATH。后面验证用nvcc --version:
nvcc --version能打出 CUDA 12.1 的版本信息,就说明 Toolkit 装好了。
4.3 cuDNN 库的匹配规则与放置方法
cuDNN 不是像 CUDA 那样一键安装的,它本质是一堆动态库、头文件和静态库文件,需要你手动放到 CUDA 的目录里。先去 NVIDIA 开发者网站注册一个免费账号,在 cuDNN 下载页选择跟你的 CUDA 大版本匹配的版本。规则很简单:
- CUDA 11.x 配 cuDNN 8.x;
- CUDA 12.x 配 cuDNN 9.x(早期也可以配 8.9.x)。
重点关注大版本对应,小版本可以选较新的。
Windows 下载的是 zip 包,解压后有bin、include、lib三个目录。用管理员权限打开文件管理器,分别把里面的文件复制到 CUDA 安装目录对应的文件夹:
| 解压目录 | 复制到(默认路径示例) |
|---|---|
| bin 下所有内容 | C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\bin |
| include 下所有内容 | ...\CUDA\v12.1\include |
| lib 下的 x64 内容 | ...\CUDA\v12.1\lib\x64 |
Linux 下载的是tar.gz包:
tar -xzvf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz cd cudnn-linux-x86_64-8.9.7.29_cuda12-archive sudo cp include/* /usr/local/cuda/include/ sudo cp lib/* /usr/local/cuda/lib64/复制完建议更新动态库缓存:
sudo ldconfig验证是否放对位置,可以看文件有没有到位:
ls /usr/local/cuda/lib64/ | grep cudnn能看到一堆libcudnn.so相关文件就对了。Windows 下可以直接去bin目录看有没有cudnn64_8.dll或cudnn64_9.dll。这个环节最常见的错误是版本不对,比如 CUDA 12 配 cuDNN 8.0,或者复制的文件权限不对导致程序运行时找不到库。遇到libcudnn.sonot found 之类的问题,基本都是这里没配对。
4.4 系统 CUDA 装好了,但 PyTorch 依然不需要它
这一节最后再强调一遍边界:系统 CUDA/cuDNN 装好之后,PyTorch 不会主动去"检测系统 CUDA"。PyTorch 用的是自己 wheel 里捆绑的运行时,因此系统 CUDA 装不装、版本是否一致,都不会影响 PyTorch 的torch.cuda.is_available()。这也是为什么经常有人出现"系统 CUDA 版本对不上,但 PyTorch 跑得好好的"这种看似矛盾的局面。真正受系统 CUDA 影响的,只有需要 nvcc 编译的那部分场景。
5. PyTorch 的安装源选择与版本对应关系:一条命令定生死
5.1 官方安装页面与最稳的安装命令
GPU 版 PyTorch 最可靠的安装方式是直接访问 PyTorch 官网安装页面,选择好你的配置(操作系统、安装方式、CUDA 版本)后会生成一条现成的命令。以 CUDA 12.1 为例:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121后半段--index-url指向官方 wheel 源里 cu121 子目录,pip 从这里下载的就是带 CUDA 12.1 运行时的 GPU 版。国内如果下载慢,阿里云做了对应镜像,用法一样:
pip install torch torchvision torchaudio --index-url https://mirrors.aliyun.com/pytorch-wheels/cu121这里要提醒一句:不要图省事把常规 PyPI 镜像的-i参数和官方的--index-url混在一起用。pip 只会从其中一个源拉包,混用会导致你拿到默认构建,默认构建在 Linux 上可能是带 CUDA 的,在 Windows 上又可能是 CPU 的,不确定性很大。确定性优先,选一个源用到底。
5.2 PyTorch 版本与 CUDA 版本对应关系速查
PyTorch 官方为每个版本提供了多个 CUDA 构建,但可选范围随版本变化。我整理一个实用速查表,覆盖近几个主要版本:
| PyTorch 版本 | 可选 CUDA 构建 | 建议场景 |
|---|---|---|
| 1.13 | cu117 / cu118 | 老项目、老卡 |
| 2.0 - 2.1 | cu117 / cu118 / cu121 | 稳定但不新 |
| 2.2 - 2.4 | cu118 / cu121 / cu124 | 当前主流选择 |
| 2.5 及以后 | cu118 / cu124 / cu126 | 新卡、新特性 |
选择逻辑:老显卡(Pascal 架构 GTX 10 系)优先cu118;20 系、30 系、40 系用cu121或cu124都行;新到手 40 系 Super 或 50 系可以考虑cu126。值得注意的是,新 PyTorch 版本可能后续不再提供某些旧 CUDA 构建,比如更早的cu117在 2.x 版本里就找不到了,需要时得去官网历史安装页核对。
5.3 conda 安装 GPU 版与 pip/conda 混用的坑
用 conda 装 GPU 版同样可行,且 conda 能自动处理好 CUDA 依赖:
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia关键在pytorch-cuda=12.1这个包,它是由 NVIDIA 维护的 conda 包,负责拉取 CUDA 运行时和 cuDNN。如果漏了它,conda 装出来的可能只是 CPU 版,这是我觉得 conda 路线最容易翻车的地方。
pip 和 conda 混用是另一个坑。比如你先用 conda 装了 GPU 版,再用 pip 装一个对 CUDA 版本敏感的新库,pip 可能顺手把里面的libstdc++、libgomp等共享库替换成新版本,导致 conda 原来装的 PyTorch 莫名其妙崩掉。混用出问题后,最省心的解决办法不是一个个排查依赖,而是删掉环境重建。所以一个环境里,尽量用同一种安装器,pip 一条路走到底,或者 conda 一条路走到底。
5.4 锁定版本的安装技巧
生产环境或长期项目,建议把版本精确锁定。pip 下载回来的是torch==2.4.1+cu121这种带本地版本标识的包。锁版本时这样写进requirements.txt:
--extra-index-url https://download.pytorch.org/whl/cu121 torch==2.4.1+cu121 torchvision==0.19.1+cu121 torchaudio==2.4.1+cu121再用pip install -r requirements.txt安装。+cu121后缀是关键,没有它 pip 可能去普通 PyPI 拉一个不带 CUDA 的默认构建。锁版本这件事在环境迁移时尤其重要,能让你后续少掉很多头发。
6. 验证与排错:跑通示例只是第一步
6.1 torch.cuda.is_available() 返回 False 的常见原因清单
我按出现频率从高到低列一份排查清单,每次遇到False顺着这张表查,基本都能定位:
| 现象 | 原因 | 处理 |
|---|---|---|
nvidia-smi报找不到命令 | 驱动未装 | 装驱动,重启 |
nvidia-smi正常但is_available()False | 装成了 CPU 版 wheel | torch.version.cuda打印 None 即可确认,重装为 cu 后缀版本 |
| 驱动版本太老 | 不支持所需 CUDA | 升级驱动到 550+ |
| macOS 环境 | CUDA 不支持 macOS | 放弃 GPU 版,用 CPU 或 MPS |
| WSL1 环境 | GPU 穿透依赖 WSL2 | wsl --version查看,升级到 WSL2 |
| 安装源混用 | wheel 来自错误 index | 删除重装,只用一个源 |
| 老显卡配太新 PyTorch | 算力过低被新版构建放弃 | 换cu118构建或老 PyTorch 版本 |
最常用的确认命令长这样:
import torch print(torch.__version__) print(torch.version.cuda) # wheel 构建时的 CUDA 版本 print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))torch.version.cuda打印出12.1之类的值,说明你是 GPU 构建;如果不放心,再跑torch.cuda.get_device_name(0)直接看显卡型号。
6.2 用矩阵乘法和训练小模型做性能快测
is_available()返回 True 只是第一步,还得确认 GPU 真的在干活。最直接的测试是跑一个足够大的矩阵乘法,对比 CPU 和 GPU 耗时。注意:张量太小的时候 GPU 反而不如 CPU,因为数据搬运和 kernel 启动开销占比太大,这是正常现象,别误判。
import torch import time x = torch.randn(5000, 5000) # CPU 推理耗时 t0 = time.time() for _ in range(5): y = x @ x print("CPU:", time.time() - t0) # GPU 耗时(先 warmup 一次) gpu = x.cuda() _ = gpu @ gpu torch.cuda.synchronize() t0 = time.time() for _ in range(50): y = gpu @ gpu torch.cuda.synchronize() print("GPU:", time.time() - t0)torch.cuda.synchronize()这行很重要,因为 GPU 是异步执行的,不加它计时会把没有算完的等待丢掉,时间测出来虚低。跑几十次取总时间,比单次计时稳定得多。如果 GPU 时间明显比 CPU 短(通常快几十倍),环境就真的没问题了。
6.3 环境迁移与复现的注意事项
环境装好后,代码、模型、环境配置的复现同样值得认真对待。conda 用户导出环境:
conda env export -n my_env > my_env.yaml恢复:
conda env create -f my_env.yamlpip 用户按刚才 5.4 节的requirements.txt方式保存,恢复时记得带--extra-index-url。如果项目里有自定义 CUDA 算子,迁移到别的机器时要格外注意系统 CUDA 版本和 nvcc 是否就位,因为这类组件不会出现在 pip 的依赖里。想彻底省心的人会选择 Docker,官方提供的 PyTorch 镜像已经按 CUDA 和 cuDNN 版本打好了标签,拉下来就能跑,这算是环境问题的最优解,代价是你的机器要接受 Docker 这套环节。
6.4 最后说一个我实际摸索出来的小习惯
环境配置这件事,最怕的就是"装完就忘"。我现在的习惯是每个项目建一个独立环境,并在项目根目录放一个env_check.py,里面只放前面那段验证代码——版本号、CUDA 信息、设备名、一个 5 秒的矩阵乘法测试。换机器、换环境、同事接手项目的时候,先跑这个脚本,所有环境信息一眼可见,省得每次都要现场敲命令一段一段排查。
还有一个小技巧:把 Python、PyTorch、CUDA 驱动版本号记在项目的 README 里,别嫌多余。我吃过好几次亏,三个月后回来看自己的老项目,装环境时完全不记得当初用的什么组合,只能重新试错。在 README 里写一行"torch 2.4.1+cu121 / Python 3.10 / driver 550+",下次一键复现。
装 PyTorch 这件事本身不难,难的是把每一步背后的关系搞清楚,然后按确定性的流程走。如果你装的过程中卡在某一步,先跑一遍nvidia-smi确认驱动,再确认自己装的是不是对应版本的 wheel,最后再回头查环境变量。这套排查顺序能解决九成以上的问题。