本文是《AI工程师踩坑实录》系列第 1 篇。这个系列每篇文章对应一个真机复现过的坑,报错原文、环境版本、排查过程全部来自我这台 GTX 1660 Ti 的老笔记本,不搬运网上结论。
本篇配套的三份脚本(环境自检、GPU 验证、CPU 与 GPU 基准测试)和一份环境避坑清单,放在了同名公众号关注不迷路。

这个坑是本系列的第一篇,我在自己这台 GTX 1660 Ti 的老笔记本上完整复现了一遍。复现完我才承认,nvidia-smi 那一行我理解错了好几年。

你八成也这么理解过。驱动装了,CUDA 也装了,PyTorch 也装了,代码一跑,GPU 死活不上,重装三遍,心态崩了。看一眼 nvidia-smi,右上角写着 CUDA Version 13.0,嗯,CUDA 好好的,那问题出在哪?

问题就出在,这一行从来就没有「你已经装了 CUDA 13.0」这个意思。

一、同一台电脑,三个 CUDA 数字当场打架

先看我这台机器的实测。2019 年的机械革命,i7 加 GTX 1660 Ti,Win11,驱动 580.88。

下面三张截图,是同一台电脑、同一个下午、前后五分钟之内跑出来的。

第一处,nvidia-smi 右上角,CUDA Version 13.0。

nvidia-smi 真实输出,右上角 CUDA Version 13.0

第二处,我去查所谓的「已安装 CUDA」,敲 nvcc -V,系统直接告诉我没这个命令。

nvcc -V 找不到命令,这台机器根本没装 CUDA Toolkit

第三处,进 Python 问 PyTorch 本人,torch.version.cuda 打出来是 None,is_available 是 False。

PyTorch 自己招了,这是 CPU 版,没有 CUDA

13.0、没装、None。三个数字,三个说法。你要是按第一个数字去装环境,注定越装越乱。

二、三个数字,各管一层

把这三层关系画成一张图,你看一遍就忘不掉了。

驱动、Toolkit、框架编译版本的三层关系

逐层拆开讲。

第 1 层是显卡驱动。nvidia-smi 右上角那个 CUDA Version,是驱动能支持的 CUDA 最高版本。类比一下,它相当于驾驶证上的最高准驾车型,说明你有资格开到哪一级,不代表你名下真有那辆车。我驱动是 580.88,它能带 CUDA 13.0 的程序,仅此而已。

第 2 层是 CUDA Toolkit,就是 nvcc 编译器那一套。它是给写 CUDA C++ 代码的人用的,你要自己编译算子、编 apex、编 flash-attention,才需要它。只是跑 PyTorch 训练的话,它装不装都行。我这台机器压根没装,nvcc 命令都找不到,下面第五节你会看到,GPU 照样跑得飞快。

第 3 层才是 PyTorch 本身。你在 pip 装的那个 wheel,编译的时候就绑定了一份 CUDA 运行时,全部打包在安装包里。torch.version.cuda 打出来什么,你实际用的就是什么。这一层才决定 GPU 能不能用。

所以那句流传很广的判断句可以改成这样,驱动给上限,Toolkit 是编译用的,wheel 才做主。

三、我是怎么一步步踩进去的

复盘一下踩坑全过程,你对号入座看看自己是卡在哪一步。

我新建了个干净的虚拟环境,pip install torch,一气呵成,1.7 分钟装完,心里还很得意。

然后写了个五行的检查脚本,跑了一下。

检查脚本输出,torch 2.15.0+cpu,version.cuda 是 None

这里有个细节。torch.version 后面跟着一个 +cpu 的尾巴。问题就出在这个尾巴上,Windows 下从 PyPI 默认源装 torch,拿到的就是 CPU 版。CUDA 支持?没有的事。

当时的我没注意到这个尾巴,还以为环境没问题,直接把数据搬到显卡上。

CPU 版调用 .cuda() 的真实报错

报错原文,我原样贴出来,搜到这篇文章的人大概率就是被它带过来的。

AssertionError: Torch not compiled with CUDA enabled

翻译成人话,你装的这个 PyTorch 编译的时候就没带 CUDA。跟你的驱动没关系,跟你的显卡没关系,重装一百遍驱动也没用。

很多人到这一步就开始怀疑人生,卸载驱动、装 CUDA Toolkit、重装系统,一路折腾两三天。方向从第一步就错了。

四、修好它,选对轮子就行

思路想通了,修复就一件事,把 CPU 版的 wheel 换成带 CUDA 的 wheel。

选哪个 CUDA 版本的轮子,三条依据,按顺序核对。

  1. 看显卡算力。1660 Ti 是 Turing 架构,算力 7.5,这几年主流的 cu12x 轮子都编进了 sm_75 的编译目标,随便挑。
  2. 看驱动上限。nvidia-smi 显示 13.0,说明驱动能带 CUDA 13.0 及以下的运行时。装 cu126 的轮子,完全在能力范围内,驱动向下兼容,不用担心。
  3. 看官方源里有什么。去 download.pytorch.org 对着版本列表挑,py3.12、win_amd64、带 +cu126 的轮子,对上号再装。

安装过程我截了张实图,2.6 GB 的轮子,实打实下载下来的。

下载 cu126 轮子的真实进度

这里补一句大实话。我一开始装的是默认源里最新的 2.15.0,它是纯 CPU 版,而官方 cu 源里当时还没有 2.15 对应的 Windows CUDA 轮子,所以我退到了 2.9.1+cu126。版本号不用跟我对齐,方法对齐就行,先看源里有什么,再定版本。

装完重跑验证脚本,全部对上了。

修复后验证输出,2.9.1+cu126,is_available True

五、跑个真实测试给你看

光看 True 没有体感,我做了一组真实基准,4096×4096 的浮点矩阵乘法,CPU 和 GPU 各跑 5 轮取最快值,同一台机器,前后脚测的。

基准测试的真实终端输出

CPU 与 GPU 实测耗时对比

真实数据放在这(完整测试脚本在同名公众号,你可以拿自己机器跑一遍)。

项目 CPU(i7-9750H) GPU(GTX 1660 Ti)
4096×4096 矩阵乘法 600.9 毫秒 32.6 毫秒
提速倍数 1 倍基准 18.4 倍

1660 Ti 是 2019 年的入门卡,就这个表现。你环境装对了,老卡也有老卡的活法。

六、常见问题 3 连

这篇容易绕晕人的三个问题,我提前替你问了,一并答了。

1. 不装 CUDA Toolkit 到底能不能训练?

能。PyTorch 的 wheel 里打包了 CUDA 运行时,训练、推理都不需要 Toolkit。哪天你要自己编译 CUDA 扩展了,再去装 nvcc 也不迟。

2. 驱动显示 13.0,装 cu126 会不会版本不匹配?

不会。nvidia-smi 给的是驱动上限,框架用的 CUDA 只要不超这个上限就行。13.0 的驱动跑 12.6 的运行时,是向下兼容的正常状态。反过来的方向才要小心,驱动太老带不动新轮子,升级驱动就好。

3. 我怎么知道自己的显卡该装哪个?

两步。先查显卡算力(官网有一张对照表),再确认轮子的编译目标里有它。验证装完用 get_arch_list() 看一眼就行,我的 1660 Ti 装完 cu126 后,列表里明明白白有 sm_75。这两个查法我都写进资源包的自检脚本里了。

七、本篇小结

三条带走。

  1. nvidia-smi 右上角的 CUDA Version 是驱动上限,不是你装的版本。
  2. 跑 PyTorch 不需要 CUDA Toolkit,torch.version.cuda 才是真实生效的那个数字。
  3. torch.version 带 +cpu 尾巴就别折腾了,换对轮子,五分钟的事。

本篇坑卡片

字段 内容
坑名 nvidia-smi 显示的 CUDA 版本被当成已装版本
报错原文 AssertionError: Torch not compiled with CUDA enabled
环境 Win11,驱动 580.88(CUDA 上限 13.0),GTX 1660 Ti 6GB,Python 3.12
复现步骤 PyPI 默认源安装 torch → 运行检查脚本 → version.cuda 为 None → 调 .cuda() 报错
根因 Windows 下 PyPI 默认源给的是 CPU 版 wheel,与驱动和显卡无关
解法 换装官方 cu 源的 CUDA 轮子(按显卡算力 + 驱动上限 + 源内可用版本选择)
避坑建议 装完先看 version 尾巴,+cpu 直接换轮子,别动驱动
可信度 本机验证
版本时间戳 2026-11-04,torch 2.15.0+cpu → 2.9.1+cu126

专栏导航

篇次 主题 状态
1 nvidia-smi 显示的 CUDA 版本到底是不是你装的那个 ✅
2 torch.cuda.is_available() 一直是 False,一条命令定位断点 待发
3 标签和图像没对齐,模型一直在学噪声 待发
4 loss 变 NaN,用 hook 逐层定位 待发
5 DataLoader 卡死在第一个 batch,Windows 多进程的坑 待发
6 装了两套 CUDA 还在串,PATH 与优先级的真相 待发
7 数据泄漏:预处理做在了划分之前 待发
8 RAG 答一半开始编,检索阈值与拒答机制实操 待发
9 随机种子都设了,结果还是不可复现 待发
10 相似度全是 0.9:向量没归一化 待发
11 开了混合精度就 NaN,GradScaler 到底在做什么 待发
12 loss 不降反升,先别怀疑模型结构 待发
13 训练降验证不降:先查数据再谈正则 待发

说明:no kernel image(需新架构显卡)、WSL2 装驱动、docker --gpus 三题本机暂不支持真实复现,按「跑不出来就换题」原则暂缓,后续具备条件再补番外篇。第二季余下选题(top-k 拐点、Tokenizer 截断、ONNX 对不上等)陆续更新。

说明:no kernel image(需新架构显卡)、WSL2 装驱动、docker --gpus 三题本机暂不支持真实复现,按「跑不出来就换题」原则暂缓,后续具备条件再补番外篇。


下一篇预告,《torch.cuda.is_available() 一直是 False?一条命令定位断点》,把驱动、配置、框架三层挨个排除,一个隐蔽到没有报错的断点也在这一篇。


版权说明,本文报错原文与实验数据均来自本人真机复现,读者可学习使用,禁止转售或整篇搬运。

posted on 2026-11-07 11:21  大雾的小屋  阅读(0)  评论(0)    收藏  举报