将Pytorch模型从CPU转换成GPU的实现方法

  

最近将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的实现方法