PyTorch调用.to(device)GPU训练时mat2张量CPU/GPU不匹配报错如何解决
这个RuntimeError本质是执行矩阵乘法操作时,参与计算的两个张量分别位于CPU和GPU,设备不匹配。你已经迁移了输入数据和模型主体,但存在遗漏的张量未同步到GPU。
排查步骤
- 优先检查自定义
Transformer类内部的张量:绝大多数这类问题都是模型内部的非参张量(比如位置编码、注意力掩码、固定偏置等)没有随模型一起迁移导致的。很多人编写自定义层时,会直接在__init__或forward中直接生成CPU侧的张量,既没有封装为nn.Parameter,也没有注册为模型缓冲区,调用.to(device)时这类张量不会自动迁移。 - 可在前向传播入口逐行打印参与运算的张量的
device属性,快速定位残留的CPU张量,比如在t(X)执行前打印X.device,在Transformer的forward方法中逐行打印用到的内部张量的device。 - 检查模型参数是否全部迁移成功:初始化模型后执行以下代码确认所有参数都在GPU上:
for name, param in t.named_parameters(): print(f"{name}: {param.device}")
解决方法
- 模型内部的固定非更新张量全部注册为缓冲区:比如位置编码这类不需要训练但需要随模型迁移的张量,不要直接赋值,使用
register_buffer注册:
# 错误写法 self.pos_encoding = torch.randn(seq_len, hidden_dim) # 正确写法 self.register_buffer('pos_encoding', torch.randn(seq_len, hidden_dim))
注册后的缓冲区张量会在调用.to(device)时自动迁移设备。
- 前向传播过程中动态生成的临时张量,生成时直接指定和模型参数同设备:比如注意力掩码这类运行时生成的张量,生成时绑定模型所在设备:
# 动态获取模型当前所在设备 device = next(self.parameters()).device mask = torch.triu(torch.ones(seq_len, seq_len, device=device), diagonal=1).bool()
- 额外修复现有代码的隐藏bug:你当前计算MAPE的代码在GPU场景下会触发新报错,GPU上的张量不能直接转换为numpy数组,需要先移回CPU:
# 错误写法 train_mape = mape(np.abs((Y.detach().numpy())), net_out.detach().numpy()) # 正确写法 train_mape = mape(np.abs((Y.detach().cpu().numpy())), net_out.detach().cpu().numpy()) # 验证集的MAPE计算也做相同修改
内容的提问来源于stack exchange,提问作者M Tayib
相关产品推荐
相关产品推荐

