pytorch 单机多GPU训练RNN遇到的问题

本文深入探讨使用DataParallel进行多GPU训练时常见的两大问题:模型无法识别自定义模块及隐藏状态未正确分配至多GPU。文章详细解释了问题成因,并提供了解决方案,包括如何正确访问封装后的模型属性及在RNN网络中确保状态张量按GPU数量正确拆分。

在使用DataParallel训练中遇到的一些问题。

1.模型无法识别自定义模块。

preview

如图示,会出现如AttributeError: 'DataParallel' object has no attribute 'xxx'的错误。

原因:在使用net = torch.nn.DataParallel(net)之后,原来的net会被封装为新的net的module属性里。

解决方案:所有在net = torch.nn.DataParallel(net)后调用了不是初始化与forward的属性,需要将net替换为net.module。

2.隐藏状态不被拆分到多GPU里。

这种错误常出现在RNN以及衍生网络的训练中,原因是这种网络的定义常常使用两个nn.module类。其中一个是RNN,一个是RNNcell。

错误的形式为RNN的前向传播中的张量维度错误,具体来说是输入的无标签数据被按照batchsize与使用的GPU数量拆分到了不同的GPU中而隐藏状态与细胞状态没有。通常情况下,每个GPU计算batchsize/GPU数量的数据。但是由于使用了RNNcell类的形式,会定义self.cellstate与self.hiddenstate作为RNN类的属性。

原因:在使用DataParallel时,pytorch会把forward函数参数里同一个batch的数据拆分到不同GPU里,而不会拆分形如self.xx的类的属性拆分掉。如果检查属性量的device,可以发现它们初始化在cuda:0中后没有改变设备号。

解决方案:所有需要拆分的量,在forward函数中作为形参与返回值。在RNN中,要注意的问题还有一些。比如为了解决这个问题,隐藏状态常常被optimizer每次传入RNN的forward。此时,隐藏状态的初始化要在每一个epoch的开始,而不可以和optimizer在一起。这一细节问题网络上有的资料没有避免。

参考资料:

https://www.zhihu.com/question/67726969

https://link.zhihu.com/?target=https%3A//senyang-ml.github.io/2019/07/20/pytorch-multigpu/

https://link.zhihu.com/?target=https%3A//blog.youkuaiyun.com/yuuyuhaksho/article/details/87560640

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值