之前用pytorch尝试写了个文本生成对抗模型seqGAN,相关博文在这里。
在部署的时候惊喜地发现有多块GPU可供训练用,于是很天真地决定把之前写的单GPU版本改写成DataParallel的方式(内心os:介有嘛呀)。于是开始了从入门到(几乎)放弃的踩坑之路。
为了和大家共同进步,我把自己的经验分享一下,欢迎一起来踩坑。
首先说明,我用的pytorch版本虽然不是嘎嘣新的1.0,但是是稳定版本0.4,而且这期间调研的结果,1.0版本并没有解决数据并行中所有大家遇到的问题。如果有童鞋用的1.0,可以参考这份指南。
另外说明,这份指南适合已经有一定pytorch经验的童鞋。指南的重点是介绍自定义神经网络在DataParallel模式下的工作方式,另外涉及少量自定义RNN类网络的结构。
torch tensor类型
当使用单device环境时,对tensor类型的设置虽然重要但并不致命。因为不涉及tensor的拆分,所以基本只要使用各种pytorch默认设置就行了。但是当涉及数据并行,就需要更了解模型不同位置需要的不同tensor类型。
pytorch的tensor有两个大类:cpu和cuda tensor。每个类都对应了不同的数据类型,具体列表在这里和这里。
在生成tensor时,可以选择通过定义device直接在指定的设备上生成:
tensor = torch.tensor([2, 4], dtype=torch.float64, device=torch.device('cuda'))
这段代码会在GPU上生成一个值为[2.,4.],大小为 1行 x 2列,数据类型为64位浮点型的tensor。
也可以先在CPU上生成,再放到GPU上:
tensor = torch.tensor([2, 4], dtype=torch.float64).to(torch.device('cuda'))
或者:
tensor = torch.tensor([2, 4], dtype=torch.float64).cuda()
也可以直接指定生成类型(cpu或者cuda tensor):
tensor = torch.DoubleTensor([2, 4])
会直接生成一个cpu类型的tensor,
tensor = torch.cuda.DoubleTensor([2, 4])
会直接生成一个cuda类型的tensor。
转换tensor的类型(cpu/cuda,数据类型),还可以用:
tensor = torch.cuda.DoubleTensor([2, 4]).type(torch.LongTensor)
torch.tensor接受已经存在的数据(在我们的例子中是[2,4]这个列表),并且会生成一份copy。如果需要从比如numpy类型的数组直接生成torch.tensor,而不需要copy,可以用:
tensor = torch.as_tensor(np.array([2,4