pytorch DataParallel理解及易犯错误(逻辑上感觉没问题,但是返回时候却出错)

本文只针对单机多GPU使用dataparallel进行加速运算。

写在前边: dataparallel只存在于继承了nn.Modules类的forward()计算中。
大致流程如下:

import torch

model = Net() #初始化模型
for i, (input_datas, label_datas) in enumerate(data_loader):
	#step 1: 数据放到GPU上
	input_datas = input_datas.cuda() #默认是 gpu:0
	label_datas = label_data.cuda() # 默认是 gpu:0
	#step 2: 模型用DataParalle封装
	model = torch.nn.DataParalle(model) # 此步会把模型复制N份,N为你机器可用的GPU数
	output, state = model(input_datas) # 注意此处这样写会有问题
		


class Net(torch.nn.Modules):
	...
	def forward(self, ...):
		#模型计算逻辑
		output, state = lstm(input, state)
		return output, state

上述代码如果在单张卡上没有任何问题,但是当我们想要通过DataParallel进行加速计算,就会报错。 仔细分析,DataParallel会把模型复制N份,把输入数据平均划分为N份, 同样的在模型进行完forward计算后会返回计算结果。此时需要注意!!!因为模型是在N个GPU上分别进行计算得到结果,在最后返回的时候,会把这N个GPU的结果进行concat 然后返回,所以返回的state并不是我们想要的结果,而是N个GPU所以的state进行了concat,因此会发现维度不一致问题。 这是需要非常小心的。

如何才能正确的进行并行计算呢,直觉上 只要我们不在最终返回的时候(main函数中)返回state就可以避免这个错误了。 具体我们可以在另外一个类的forward()中调用Net()模型, 此时这两个类都通过DataParallel进行了封装,都是N份,所以其维度都是N倍, 执行完lstm后就只返回outputs就可以了。

常见问题二:

RuntimeError: Expected tensor for argument #1 ‘input’ to have the same device as tensor for argument #2 ‘weight’; but device 1 does not equal 0 (while checking arguments for cudnn_convolution)
此问题是因为在使用DataParallel时候 数据和参数不在一个GPU上导致的,看提示说明data分配到了gpu:1上,而参数在gpu:0上。 主要我们在 data.cuda()的时候指定合适的GPU就可以了, 比如此处data.cuda(0) 就可以了。其实data.cuda()默认就是gpu:0。

感谢苏璐岩~

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值