如何解决PyTorch训练时检测到cpu和cuda:0两个设备的报错
报错根因分析
- 核心问题出在你多次主动将模型从CUDA迁移到CPU,却没有在训练前迁回CUDA,导致模型参数和输入张量设备不匹配:
- 初始化
best_model时,你调用了model.cpu().state_dict().copy(),这行代码会直接把原本已经通过.to(device)迁移到CUDA的模型整体转回CPU,后续训练时输入张量在CUDA、模型参数在CPU,自然触发设备不匹配报错 - 每次更新
best_model时,你又调用了model.cpu().state_dict().copy(),每执行一次就会把模型转回CPU一次,即使你之前临时修复了设备问题,下一轮训练还是会触发报错 - 代码中
out = model(batch_x.to(device)).cuda()属于多余操作,模型在哪个设备上,前向输出自然就在哪个设备上,额外加.cuda()不会解决问题,反而可能在模型已经在CPU的情况下引入新的设备不匹配
- 初始化
修复方案
- 修改最佳模型初始化逻辑,不要直接改变原模型的设备,仅将模型参数的副本迁移到CPU保存即可:
# 原错误代码:best_model = model.cpu().state_dict().copy() # 替换为 best_model = {k: v.cpu().clone() for k, v in model.state_dict().items()}
- 同理修改最佳模型保存逻辑,不要调用
model.cpu()改变原模型设备:
# 原错误代码:best_model = model.cpu().state_dict().copy() # 替换为 best_model = {k: v.cpu().clone() for k, v in model.state_dict().items()}
- 删除多余的
.cuda()调用,修改前向传播代码:
# 原错误代码:out = model(batch_x.to(device)).cuda() # 替换为(batch_x已经提前转到device了,不需要重复转) out = model(batch_x)
- 可以在训练循环开始前加一行确认模型设备的代码,避免意外:
print(f"模型当前设备:{next(model.parameters()).device}")
额外优化建议
你当前的测试集准确率计算逻辑存在错误:每个测试batch都会覆盖test_acc的值,最终保存的test_acc只是测试集最后一个batch的准确率,而非整个测试集的准确率,建议修改为累计所有样本的正确数后再计算准确率:
with torch.no_grad(): correct = 0 total = 0 for batch_x, batch_y in test_loader: batch_x = batch_x.to(device) batch_y = batch_y.to(device) out = model(batch_x) correct += (torch.argmax(out, 1) == batch_y).sum().item() total += batch_y.size(0) test_acc = correct / total
内容的提问来源于stack exchange,提问作者occupymars
相关产品推荐
相关产品推荐

