一、核心原因
无效 GPU 设备编号,代码指定的 GPU 序号不存在,常见场景:
- 机器只有 0 号单卡,代码强制使用
device=1 / cuda:1 CUDA_VISIBLE_DEVICES环境变量限制可用卡,代码仍写原物理卡号- 多卡训练脚本写死 GPU ID,换单卡机器未修改
- Accelerate/Hugging Face 自动分配设备逻辑冲突
二、快速排查步骤
1. 先查看本机实际可用 GPU
bash
运行
# 查看显卡数量与编号
nvidia-smi
# pytorch 内打印可用设备
python -c "import torch; print(torch.cuda.device_count()); print([i for i in range(torch.cuda.device_count())])"
输出 device_count=1 则仅支持 cuda:0,访问 cuda:1 直接报该错。
2. 三种修复方案(按推荐优先级)
方案 1:自动适配,不硬编码 GPU 编号(推荐)
不要写死 cuda:1,自动取第 0 张卡:
python
运行
import torch
# 自动判断有无GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 等价简写
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 模型/数据移到设备
model = model.to(device)
data = data.to(device)
方案 2:环境变量限制可见 GPU(多卡机器筛选指定卡)
运行脚本前限定只使用 0 号卡,所有代码里的 cuda 编号会重新映射:
bash
运行
# linux/mac
export CUDA_VISIBLE_DEVICES=0
python train.py
# windows cmd
set CUDA_VISIBLE_DEVICES=0
python train.py
# windows powershell
$env:CUDA_VISIBLE_DEVICES="0"
python train.py
若设
CUDA_VISIBLE_DEVICES=2,3,代码里cuda:0实际对应物理 2 号卡。
方案 3:修复 Accelerate 相关报错(你堆栈含 AcceleratorError 专用)
使用 accelerate launch 时报错:
- 重新生成配置文件,匹配本机显卡数量
bash
运行
accelerate config
按提示选择:单 GPU、仅 cuda:0、不使用多卡分布式;
2. 启动时强制指定设备:
bash
运行
CUDA_VISIBLE_DEVICES=0 accelerate launch train.py
三、调试异步 CUDA 报错(日志提示的两种调试手段)
1. 同步捕获 CUDA 错误(精准定位报错行)
bash
运行
CUDA_LAUNCH_BLOCKING=1 python train.py
开启后 CUDA 操作同步执行,报错堆栈会精确到出错代码行,不再错位。
2. 开启设备断言,捕获显存 / 越界问题
bash
运行
TORCH_USE_CUDA_DSA=1 CUDA_LAUNCH_BLOCKING=1 python train.py
适合内核越界、非法内存访问类底层 CUDA 错误。
四、高频踩坑示例
错误写法(单卡机器必崩)
python
运行
device = torch.device("cuda:1") # 机器只有0号卡
分布式脚本坑
多卡训练代码写死 local_rank=1,放到单卡服务器直接报错,改用自动 rank 获取:
python
运行
import os
local_rank = int(os.environ.get("LOCAL_RANK", 0))
device = torch.device(f"cuda:{local_rank}")
五、兜底方案:无 GPU 自动切 CPU
python
运行
import torch
if torch.cuda.is_available():
device = torch.device("cuda:0")
else:
device = torch.device("cpu")
print(f"using device: {device}")
正文完
可以使用微信扫码关注公众号(ID:xzluomor)