将nn.Module移至CUDA时,内部嵌套子模块未同步迁移的问题排查
问题原因与解决办法
原因分析
PyTorch的nn.Module.to()方法会自动递归处理所有通过self.xxx = 子模块实例形式注册的子模块,将它们的参数转移到指定设备。但如果你的TransformerEncoder类中没有把MultiheadAttention注册为自身的子模块(比如仅用局部变量创建,未赋值给self的属性),这个嵌套模块的参数就不会被纳入顶层模型的参数管理体系,调用model.to("cuda:0")时自然不会同步迁移它的参数。
另外错误提示提到“输入张量在CPU,模块参数在CUDA”,也有可能是输入数据没有同步转移到CUDA设备,和模块参数设备不匹配导致的。
解决办法
1. 正确注册MultiheadAttention子模块
确保在TransformerEncoder的__init__方法中,将MultiheadAttention实例赋值给self的属性(比如用self.attn或nn.ModuleList管理多层注意力),让PyTorch识别为子模块。示例代码:
class TransformerEncoder(nn.Module): def __init__(self, input_dim, num_layers, num_heads): super(TransformerEncoder, self).__init__() # 用ModuleList管理多层注意力,自动注册为子模块 self.layers = nn.ModuleList([ MultiheadAttention(input_dim, num_heads) for _ in range(num_layers) ]) # 如果是单层注意力,直接赋值: # self.attn = MultiheadAttention(input_dim, num_heads)
2. 同步输入张量到CUDA设备
在模型前向传播前,确保输入数据已经转移到CUDA,比如:
# 假设inputs是输入张量 inputs = inputs.to("cuda:0") outputs = model(inputs)
验证方法
修改后可以通过以下代码验证所有参数的设备是否一致:
for name, param in model.named_parameters(): print(f"{name}: {param.device}")
所有参数都应该显示为cuda:0。
内容的提问来源于stack exchange,提问作者SAUMYA BHANDARY
相关产品推荐
相关产品推荐

