原帖使用 Windows 10、Python 3.7 和 PyTorch 1.2.0;包列表还包含 cpuonly。调用 CUDA 时出现:
AssertionError: Torch not compiled with CUDA enabled
分清三个不同的 CUDA 版本信息
系统里的 nvcc 对应开发工具链,nvidia-smi 显示驱动及其支持的 CUDA 上限,torch.version.cuda 则说明当前 PyTorch 包的构建信息。三者不必逐字相同。原帖同时列出了 cudatoolkit 与 cpuonly,恰好说明“装过 CUDA 工具包”不足以判断 torch 是哪种构建。
先查导入结果,再看安装记录,可以避免反复重装驱动却一直使用 CPU 包。
安装了系统 CUDA Toolkit,并不能把 CPU 版 torch 变成 CUDA 版。在发生 .cuda() 之前检查实际导入的包:
import sys
import torch
print("josh050608")
print("python:", sys.executable)
print("torch:", torch.__version__, torch.__file__)
print("build CUDA:", torch.version.cuda)
print("available:", torch.cuda.is_available())
若 torch.version.cuda is None,当前就是没有 CUDA 支持的构建。若它有版本号但 is_available() 为 False,则转查 NVIDIA 驱动、GPU 可见性与容器权限,不能再把原因定成 CPU 构建。
复现原帖旧环境时,官方历史页给出的 1.2.0/CUDA 10.0 Conda 组合如下。先建一个独立的 Python 3.7 环境,再在已激活的环境执行,避免既有 cpuonly 约束影响解析:
conda create -n torch120 python=3.7
conda activate torch120
conda install pytorch==1.2.0 torchvision==0.4.0 cudatoolkit=10.0 -c pytorch
这只是历史复现组合。新项目应按官方选择器选择受支持的 Python、驱动和构建,不应把旧命令当作最新推荐。没有兼容 NVIDIA GPU 时,应保留 CPU 执行路径:device = torch.device('cuda' if torch.cuda.is_available() else 'cpu'),并使用 model.to(device) 和 inputs.to(device)。
最后重新启动 Python,重复检查,并用 torch.ones(1, device='cuda') 验证真正的 CUDA 分配。
检查结果对应哪条修复路线
| build CUDA | available | 应当继续检查什么 |
|---|---|---|
| None | False | 当前 torch 无 CUDA 支持;核对解释器后换适合平台的构建 |
| 有版本号 | False | 驱动、GPU 可见性、容器设备映射;此时不等于装了 CPU 包 |
| 有版本号 | True | 先做小分配,再回到仓库中检查硬编码的设备编号 |
在原来启动仓库的同一终端执行 python -m pip show torch;Conda 用户再执行 conda list pytorch、conda list cpuonly。这一步看的是包的来源和约束,不应混着执行多套历史安装命令。若选择新建环境,应先在新环境验证小程序成功,再让 IDE、Notebook 和仓库入口一起切过去。
下面是安装检查通过后的最小计算,不加载模型,不下载数据。它会明确拒绝静默退回 CPU,适用于“本来就要求使用 CUDA”的验证:
import torch
if torch.version.cuda is None:
raise RuntimeError("当前导入的是无 CUDA 支持的 torch 构建")
if not torch.cuda.is_available():
raise RuntimeError("构建支持 CUDA,但本进程尚不能使用 GPU")
x = torch.arange(4, dtype=torch.float32, device="cuda")
y = x.square()
torch.cuda.synchronize()
assert y.device.type == "cuda"
assert y.cpu().tolist() == [0.0, 1.0, 4.0, 9.0]
print("device:", torch.cuda.get_device_name(0), y.device)
若项目允许 CPU,则同时迁移模型、输入和目标,替换仓库中直接写死的 .cuda()。只修改一个 device 变量,不会自动改变其他文件中的 .cuda() 调用。历史环境的 1.2.0 组合适合复现旧项目;新 Python 不能直接照装旧 wheel,具体支持范围以目标版本的官方发行记录为准。
参考:原始求助帖;技术依据:PyTorch 历史安装组合、PyTorch 官方安装指南、PyTorch CUDA 语义(2.5)。