Pytorch多GPU计算之torch.nn.DataParallel()

Pytorch 专栏收录该内容
11 篇文章 1 订阅

pytorch中的GPU操作默认是异步的,当调用一个使用GPU的函数时,这些操作会在特定设备上排队但不一定在稍后执行。这就使得pytorch可以进行并行计算。但是pytorch异步计算的效果对调用者是不可见的。

但平时我们用的更多其实是多GPU的并行计算,例如使用多个GPU训练同一个模型。Pytorch中的多GPU并行计算是数据级并行,相当于开了多个进程,每个进程自己独立运行,然后再整合在一起。

注:多GPU计算的前提是你的计算机上得有多个GPU,在cmd上输入nvidia-smi来查看自己的设备上的GPU信息。

1. 多GPU计算的简单例子

一般我们使用torch.nn.DataParallel()这个函数来进行接下来我将用一个例子来演示如何进行多GPU计算。

net = torch.nn.Linear(10,1)
print(net)
print('---------------------')
net = torch.nn.DataParallel(net, device_ids=[0,3])
print(net)

#######################
##以下是输出:

Linear(in_features=10, out_features=1, bias=True)
---------------------
DataParallel(
  (module): Linear(in_features=10, out_features=1, bias=True)
)

可以看到torch.nn.DataParallel()包裹起来了。然后我们就可以使用这个net来进行训练和预测了,它将自动在第0块GPU和第3块GPU上进行并行计算,然后自动的把计算结果进行了合并。

2. 多GPU计算减少了程序运行的时间?

很多同学发现在进行多GPU运算时,程序花费的时间反而更多了,这其实是因为你的batch_size太小了,因为torch.nn.DataParallel()这个函数是将每个batch的数据平均拆开分配到多个GPU上进行计算,计算完再返回来合并。这导致GPU之间的开关和通讯过程占了大部分的时间开销。

大家可以使用watch -n 0.1 nvidia-smi这个命令来查看每0.1s各个GPU的运行情况,如果发现每个GPU的占用率均低于50%,基本可以肯定你使用多GPU计算所花的时间要比单GPU计算花的时间更长了。

博主使用GoogleNet来测试了多GPU计算的性能,本次测试的代码可以在这里找到。博主设置的batch_size为512。
下面直接上实验结论:
1个GPU,平均每轮30.8s:
在这里插入图片描述
2个GPU,平均每轮21.2s:
在这里插入图片描述
可以看出多GPU显著缩短了计算时间。

3. 如何保存和加载多GPU网络?

Pytorch模型保存和加载的方法,可以看我的这篇博客。在这里不做详细的介绍了,这里只展示如何来保存和加载多GPU网络,它与普通网络有一点细微的不同。废话不多说,直接上代码:

net = torch.nn.Linear(10,1)  # 先构造一个网络
net = torch.nn.DataParallel(net, device_ids=[0,3])  #包裹起来
torch.save(net.module.state_dict(), './networks/multiGPU.pt') #保存网络

# 加载网络
new_net = torch.nn.Linear(10,1)
new_net.load_state_dict(torch.load("./networks/multiGPU.pt"))

因为DataParallel实际上是一个nn.Module,所以我们在保存时需要多调用了一个net.module。

  • 8
    点赞
  • 1
    评论
  • 32
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

程序有英语 汉语 两种语言,根据操作系统环境来选择language. 修复过程分【普通修复】和【强力修复】。 XP和VISTA/WIN7下的修复操作还是有很区别的。但基于的原理是一样的。 并且因为Vista/Win7下的Smart Card 服务的scardsvr.exe可执行文件被更改为scardsvr.dll,也就没有了scardsvr的相关安装命令。我用dependency查看了下scardsvr.dll,只能看到一个入口函数。能力有限,google了一些资料也没有结果。就没分析下去了。 【普通修复】的修复过程(以XP下的修复过程讲述,vista/win7下操作请看代码): (1)检查"智能卡服务"是否为自启动。并设置其为自启动。 (2)检测服务当前状态是否为SERVICE_RUNNING,并设置其状态为运行中。 (3)检测前两步是否成功,如果成功则向用户弹出messagebox询问moveable device功能是否正常。 (4)如果功能仍abnormal,则初步判断是服务登陆账户为非"NT AUTHORITY\LocalService" ,则用CreateProcess来运行 sc.exe config SCardSvr obj= \"NT AUTHORITY\LocalService" password= "" ,改变其用户为localservice(smart card service只有在此登陆账户下才正常运行)。 (5)如果在普通修复过程中遇到服务查询不到等error时,程序自动启动强力修复来安装smart card service. 注意:普通修复中的第3,4步中有点问题,在这个地方其实最好是直接检查服务的登陆账户。然后做出相应的动作,但是我这个地方没有想到实现的办法。望前辈提示。另外就是sc的命令格式有严格的限制,编码的时候要注意等号后面首先是空格。我当时被这个空格困扰到了。 【强力修复】的修复过程(XP下的修复,vista/win7 下没有强力修复) 其实强力修复的过程就是网上流传的那个修复过程,我只不过在这个修复过程中增加了验证和配置修改。 修复过程: (1)ScardSvr.exe reinstall (2)regsvr32.exe SCardssp.dll (3)sc.exe config SCardSvr obj= \"NT AUTHORITY\LocalService" password= "" (4)通过以上三步之后,剩下的配置修改就跟普通修复过程一样了。而以上三步通过CreateProcess和WaitForSingleObject来配合控制。 应该差不了。代码是半个月前写的,一些地方可能有疏漏。 在代码实现中还有很地方需要注意,我也都在代码中做出了注释。可自行查看。 如需交流,可mailto:pencil@yeah.net MSN:pencilsoft@hotmail.com
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值