torch.cuda.is_available() 返回 True 仅表示 PyTorch 可用 GPU,不保证实际调用;必须结合 nvidia-smi 观察 GPU 利用率与显存变化、检查张量 .device 属性、以及 torch.cuda.memory_allocated() 内存增量三者验证。

torch.cuda.is_available() 返回 True 并不等于 Python 正在调用 GPU 算力——它只说明 PyTorch 能用 GPU,但实际训练或推理时仍可能全程跑在 CPU 上。验证是否“成功调用”,必须观察运行时行为,而非仅检查可用性。
为什么 torch.cuda.is_available() 不能作为调用证据
这个函数只做静态检查:驱动加载了没、CUDA 运行时库找得到没、PyTorch 编译时链接的 CUDA 版本是否匹配。它完全不关心你的模型和数据有没有真正上 GPU。
- 常见假阳性场景:
model = MyNet().cuda()写了,但input_tensor忘了.to("cuda"),整个 forward 就在 CPU 上默默执行 - 更隐蔽的问题:混合设备(部分张量在 CPU、部分在 GPU),触发
RuntimeError: Expected all tensors to be on the same device,但若没报错,就可能因隐式拷贝回退到 CPU -
.cuda()调用本身不报错,不代表显存真被占用——比如小张量可能被 PyTorch 放进 CPU 缓存再懒加载,nvidia-smi看不到显存上涨
用 nvidia-smi 实时观察 GPU 利用率和显存
这是最直接、不可绕过的验证手段。它不依赖 Python 代码逻辑,而是从系统层看硬件是否真在干活。
- 开一个终端,持续运行:
nvidia-smi -l 1(每秒刷新一次) - 然后运行你的训练脚本(哪怕只是单步 forward)
- 重点看两列:
GPU-Util(利用率)是否跳升到 20%+;Memory-Usage是否明显增加(比如从 100MB → 2GB) - 如果
GPU-Util长期为 0%,而 CPU 使用率很高,基本可断定没走 GPU
在 Python 中确认张量和模型设备一致性
光靠 .cuda() 或 .to("cuda") 不够,必须逐层检查关键对象的实际设备位置。
立即学习“Python免费学习笔记(深入)”;
- 检查模型:
next(model.parameters()).device—— 返回device(type='cuda', index=0)才算真上去了 - 检查输入/标签:
input_tensor.device和target_tensor.device必须都是cuda - 检查中间输出:
output = model(input); print(output.device),避免 forward 中途掉回 CPU - 别信
model.to("cuda")的返回值——它原地修改模型,但不抛异常,也不校验子模块是否都生效(比如自定义nn.Module里漏写了self.linear = self.linear.to(device))
用 torch.cuda.memory_allocated() 检测隐式分配
小规模计算可能不触发明显 GPU-Util 波动,但会真实申请显存。这个 API 能捕捉到“静默上卡”行为。
- 在关键操作前加:
print(torch.cuda.memory_allocated() / 1024**2)(单位 MB) - 执行矩阵乘、
model(input)后再打一次,差值 > 50MB 基本可确认有 GPU 计算发生 - 注意:
torch.cuda.empty_cache()会清空缓存但不释放已分配内存,所以对比时别穿插它 - 该值只反映当前活跃内存,不是峰值;要看历史最大值用
torch.cuda.max_memory_allocated()
真正的验证难点不在“能不能”,而在“有没有”。很多问题出在设备分散、隐式拷贝、或调试时用了小 batch 导致 GPU 利用率太低而被忽略。最稳妥的做法是三者并用:nvidia-smi 看硬件响应 + .device 属性查对象归属 + memory_allocated() 量化内存变化。任何单一指标都可能撒谎。


















