最近将Pytorch程序迁移到GPU上去的一些工作和思考
环境:Ubuntu 16.04.3
Python版本:3.5.2
Pytorch版本:0.4.0
大家知道,在深度学习中使用GPU来对模型进行训练是可以通过并行化其计算来提高运行效率,这里就不多谈了。
最近申请到了实验室的服务器来跑程序,成功将我简陋的程序改成了“高大上“GPU版本。
看到网上总体来说少了很多介绍,这里决定将我的一些思考和工作记录下来。
由于我使用的是Pytorch写的模型,网上给出了一个非常简单的转换方式:对模型和相应的数据进行.cuda()处理。通过这种方式,我们就可以将内存中的数据复制到GPU的显存中去。从而可以通过GPU来进行运算了。
网上说的非常简单,但是实际使用过程中还是遇到了一些疑惑。下面分数据和模型两方面的迁移来进行说明介绍。
<强> 1.1判定使用GPU 强>
下载了对应的GPU版本的Pytorch之后,要确保GPU是可以进行使用的,通过torch.cuda.is_available()的返回值来进行判断。返回正确则具有能够使用的GPU。
通过torch.cuda.device_count()可以获得能够使用的GPU数量。其他就不多赘述了。
常常通过如下判定来写可以跑在GPU和CPU上的通用模型:
如果torch.cuda.is_available (): ten1=ten1.cuda () MyModel=MyModel.cuda ()
数据方面常用的主要是两种——张量和变量。实际上这两种类型是同一个东西,因为变量的实际上只是一个容器,这里先视其不同。
<强> 2.1将张量迁移到显存中去强>
不论是什么类型的张量(FloatTensor或者是LongTensor等等),一律直接使用方法.cuda()即可。
例如:
ten1=torch.FloatTensor (2) 在在在在6.1101 e + 24 4.5659 e-41 (火炬。FloatTensor大小2] ten1_cuda=ten1.cuda () 在在在在6.1101 e + 24 4.5659 e-41 [torch.cuda。FloatTensor大小2 (GPU 0)) >之前其数据类型会由torch.FloatTensor变为torch.cuda。FloatTensor (GPU 0)这样代表这个数据现在存储在
0的GPU显存中了。
如果要将显存中的数据复制到内存中,则对cuda数据类型使用.cpu()方法即可。
<强> 2.2将变量迁移到显存中去强>
在模型中,我们最常使用的是变量这个容器来装载使用数据。主要是由于变量可以进行反向传播来进行自动求导。
同样地,要将变量迁移到显存中,同样只需要使用.cuda()即可实现。
这里有一个小疑问,对变量直接使用.cuda和对张量进行.cuda然后再放置到变量中结果是否一致呢。答案是肯定的。
ten1=torch.FloatTensor (2) 在在在6.1101 e + 24 4.5659 e-41 (火炬。FloatTensor大小2] ten1_cuda=ten1.cuda () 在在在在6.1101 e + 24 4.5659 e-41 [torch.cuda。FloatTensor大小2 (GPU 0)) V1_cpu=autograd.Variable (ten1) 在在在在变量包含: 6.1101 e + 24 4.5659 e-41 (火炬。FloatTensor大小2] V2=autograd.Variable (ten1_cuda) 在在在在变量包含: 6.1101 e + 24 4.5659 e-41 [torch.cuda。FloatTensor大小2 (GPU 0)) V1=V1_cpu.cuda () 在在在在变量包含: 6.1101 e + 24 4.5659 e-41 [torch.cuda。FloatTensor大小2 (GPU 0)) >之前最终我们能发现他们都能够达到相同的目的,但是他们完全一样了吗?我们使用V1是V2发现,结果是否定的。
对于V1,我们是直接对变量进行操作的,这样子V1的.grad_fn中会记录下创建的方式,因此这二者并不是完全相同的。
<强> 2.3数据迁移小结强>
.cuda()操作默认使用GPU 0也就是第一张显卡来进行操作。当我们想要存储在其他显卡中时可以使用.cuda (& lt;显卡号数祝辞)来将数据存储在指定的显卡中。还有很多种方式,具体参考官方文档。
对于不同存储位置的变量,我们是不可以对他们直接进行计算的。存储在不同位置中的数据是不可以直接进行交互计算的。
换句话说也就是上面例子中的torch.FloatTensor是不可以直接与torch.cuda.FloatTensor进行基本运算的。位于不同GPU显存上的数据也是不能直接进行计算的。
对于变量,其实就仅仅是一种能够记录操作信息并且能够自动求导的容器,实际上的关键信息并不变量在本身,而更应该侧重于变量中存储的数据。
将Pytorch模型从CPU转换成GPU的实现方法