PyTorch下,使用list放置模块,导致计算设备不一的报错

报错

在复现 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    
相关推荐
Polar__Star几秒前
PHP新手如何评估AI成本_预算控制方法【教程】
jvm·数据库·python
m0_493934538 分钟前
TensorFlow如何监控内存使用情况_结合tf.summary记录关键指标信息
jvm·数据库·python
Polar__Star17 分钟前
Go语言中--=运算符详解:位右移赋值操作的原理与实践
jvm·数据库·python
不考研当牛马18 分钟前
python 第21课 基础完结(UDP套接字)
开发语言·python·udp
qq_1898070318 分钟前
Navicat导出JSON数据为空如何解决_过滤条件与权限排查
jvm·数据库·python
2301_8135995520 分钟前
HTML表单能嵌套吗_表单嵌套限制与替代方案【解答】
jvm·数据库·python
yejqvow1223 分钟前
如何使用可视化查询生成器_免敲代码的多表JOIN配置
jvm·数据库·python
2301_8152795224 分钟前
学生党预算有限怎么选HTML函数工具_低配高性价比教程【教程】
jvm·数据库·python
@hhr29 分钟前
使用java对接火山方舟doubao-seedance-1.5-pro 模型进行视频生成
java·python·音视频
廋到被风吹走30 分钟前
【LangChain4j】Java 生态中最灵活、功能最强大的纯 Java 大模型应用开发框架(支持声明式@AiService与复杂RAG/Agent)
java·开发语言·python