多GPU环境下Jupyter模型训练遇RuntimeError:参数设备不匹配
解决DataParallel设备不匹配的RuntimeError问题
咱们先拆解下你遇到的问题根源:
你原本想在物理GPU2上运行Notebook,但操作里有两个关键冲突点:
- 你设置了
export CUDA_VISIBLE_DEVICES=0,1,2,3,这意味着代码里的cuda:0对应物理GPU0,cuda:2对应物理GPU2; - 使用
nn.DataParallel(model, device_ids=[0,1,2,3])时,DataParallel的核心规则是要求模型参数必须先放在device_ids列表的第一个设备(也就是这里的cuda:0),但你随后又把模型to(device)(也就是cuda:2),导致模型参数跑到了cuda:2,和DataParallel的要求冲突,所以触发了报错。
解决方案:两种方式任选其一
方式一:调整环境变量,让物理GPU2成为代码中的主设备(推荐)
如果你确实想让物理GPU2作为这个Notebook的主设备来跑,修改环境变量,把物理GPU2放在CUDA_VISIBLE_DEVICES的第一位:
export CUDA_VISIBLE_DEVICES=2,0,1,3
这样在代码里:
cuda:0就对应物理GPU2(你的目标设备)cuda:1对应物理GPU0,cuda:2对应物理GPU1,cuda:3对应物理GPU3
然后代码里做如下调整:
# 现在cuda:0就是物理GPU2,直接用这个作为主设备 device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') # 验证设备信息 print(device, torch.cuda.device_count(), torch.cuda.current_device()) # 加载/创建模型后,先把模型放到主设备cuda:0 model = model.to(device) # 再用DataParallel指定要用到的所有可见设备(对应物理GPU2,0,1,3) model = nn.DataParallel(model, device_ids=[0,1,2,3])
注意:一定要先执行
model.to(device),再套DataParallel,顺序不能反!
方式二:不修改环境变量,调整代码适配DataParallel规则
如果你不想改环境变量,那必须让模型参数先放在device_ids的第一个设备(也就是cuda:0,对应物理GPU0),但这样主设备就变成了物理GPU0,可能不符合你的初衷:
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') model = model.to(device) model = nn.DataParallel(model, device_ids=[0,1,2,3])
如果非要让物理GPU2参与计算但主设备是cuda:0,也可以把device_ids设为[0,2](只用到物理GPU0和2),但主设备仍为cuda:0。
验证是否生效
调整后,可以运行这段代码确认设备状态:
print("当前主设备索引:", torch.cuda.current_device()) print("模型参数所在设备:", next(model.parameters()).device)
如果输出的设备和你期望的主设备一致,就没问题了。
内容的提问来源于stack exchange,提问作者vpap
相关产品推荐
相关产品推荐

