报错
在复现 Transformer 代码的训练阶段时,发生报错:
bash
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
解决方案
通过next(linear.parameters()).device
确定 model 已经在 cuda:0 上了,同时输入 model.forward()
的张量也位于 cuda:0。输入的张量没什么好推敲的,于是考虑到模型具有多层结构,遂输出每层结构的设备信息,model.encoder
-> model.encoder.sublayer[0]
··· ···
测试发现,model.encoder.sublayer[0]
之后的模块的设备信息均位于 cpu,原因是构造这部分模块时,由于需要多个相同的模块,使用了 list 来存放模块:
python
# module: 需要深拷贝的模块
# n: 拷贝的次数
# return: 深拷贝后的模块列表
def clones(module, n: int) -> list:
return [copy.deepcopy(module) for _ in range(n)]
显然 list 不支持 GPU,需要用 PyTorch 提供的代替:
python
def clones(module, n: int):
return nn.ModuleList([copy.deepcopy(module) for _ in range(n)])
ModuleList
把子模块存入列表,能像 Python 里普通的列表被索引,最重要的是能使内部的模块被正确注册,并对所有的 Module
方法可见。[Source]
成功解决!
相关环境
bash
python 3.11.7 he1021f5_0
pytorch 2.1.2 py3.11_cuda12.1_cudnn8_0