推荐阅读:5min~8min
主要内容:最近将Pytorch程序迁移到GPU上去的一些工作和思考 环境:Ubuntu 16.04.3 Python版本:3.5.2 Pytorch版本:0.3.0
大家知道,在深度学习中使用GPU来对模型进行训练是可以通过并行化其计算来提高运行效率,这里就不多谈了。
最近申请到了实验室的服务器来跑程序,成功将我简陋的程序改成了“高大上”GPU版本。
看到网上没有太多这方面的介绍(TensorFlow的倒是不少~),这里决定将我的一些思考和工作记录下来。
由于我使用的是Pytorch写的模型,网上给出了一个非常简单的转换方式: 对模型和相应的数据使用.cuda()处理。通过这种方式,我们就可以将内存中的数据复制到GPU的显存中去。从而可以通过GPU来进行运算了。
网上说的非常简单,但是实际使用过程中还是遇到了一些疑惑。下面分数据和模型两方面的迁移来进行说明介绍。
1.1 判定使用GPU
下载了对应的GPU版本的Pytorch之后,要确保GPU是可以进行使用的,通过`torch.cuda.is_available()`的返回值来进行判断。返回`True`则具有能够使用的GPU。
通过`torch.cuda.device_count()`可以获得能够使用的GPU数量。其他就不多赘述了。
常常通过如下判定来写可以跑在GPU和CPU上的通用模型:
if torch.cuda.is_available(): ten1 = ten1.cuda() MyModel = MyModel.cuda()
数据方面常用的主要是两种 —— Tensor和Variable。实际上这两种类型是同一个东西,因为Variable实际上只是一个容器,这里先视其不同。
2.1 将Tensor迁移到显存中去
不论是什么类型的Tensor(FloatTensor或者是LongTensor等等),一律直接使用方法.cuda()即可。
例如:
ten1 = torch.FloatTensor(2)
>>>> 6.1101e+24 4.5659e-41 [torch.FloatTensor of size 2] ten1_cuda = ten1.cuda()
>>>> 6.1101e+24 4.5659e-41[torch.cuda.FloatTensor of size 2 (GPU 0)]
其数据类型会由`torch.FloatTensor`变为`torch.cuda.FloatTensor (GPU 0)`这样代表这个数据现在存储在
`GPU 0`的显存中了。
如果要将显存中的数据复制到内存中,则对cuda数据类型使用`.cpu()`方法即可。
2.2 将Variable迁移到显存中去
在模型中,我们最常使用的是Variable这个容器来装载使用数据。主要是由于Variable可以进行反向传播来进行自动求导。
同样地,要将Variable迁移到显存中,同样只需要使用`.cuda()`即可实现。
这里笔者先前有一个小疑问,对Variable直接使用`.cuda`和对Tensor进行`.cuda`然后再放置到Variable中结果是否一致呢。答案是肯定的。
ten1 = torch.FloatTensor(2)
>>> 6.1101e+24 4.5659e-41 [torch.FloatTensor of size 2]
ten1_cuda = ten1.cuda()
>>>> 6.1101e+24 4.5659e-41 [torch.cuda.FloatTensor of size 2 (GPU 0)]
V1_cpu = autograd.Variable(ten1)>>>> Variable containing: 6.1101e+24 4.5659e-41 [torch.FloatTensor of size 2]
V2 = autograd.Variable(ten1_cuda)
>>>> Variable containing: 6.1101e+24 4.5659e-41 [torch.cuda.FloatTensor of size 2 (GPU 0)]
V1 = V1_cpu.cuda()>>>> Variable containing: 6.1101e+24 4.5659e-41 [torch.cuda.FloatTensor of size 2 (GPU 0)]
最终我们能发现他们都**能够达到相同的目的**,但是他们完全一样了吗?我们使用`V1 is V2`发现,结果是否定的。
对于V1,我们是直接对Variable进行操作的,这样子V1的`.grad_fn`中会记录下创建的方式。因此这二者并不是完全相同的。
转自:机器学习算法与自然语言处理
完整内容请点击“阅读原文”