第25章 Pytorch 如何高效使用GPU

第25章 Pytorch 如何高效使用GPU

深度学习涉及不少向量或多矩阵运算,如矩阵相乘、矩阵相加、矩阵-向量乘法等。深层模型的算法,如BP,Auto-Encoder,CNN等,均可以写成矩阵运算的形式,无须写成循环运算。然而,在单核CPU上执行时,矩阵运算会被展开成循环的形式,本质上仍是串行执行。GPU(Graphic Process Units,图形处理器)的众核体系结构包含几千个流处理器,可将矩阵运算并行化执行,大幅缩短计算时间。随着NVIDIA、AMD等公司不断推动其GPU的大规模并行架构,面向通用计算的GPU已成为加速可并行应用程序的重要手段。得益于GPU众核(many-core)体系结构,程序在GPU系统上的运行速度相较于单核CPU每每提高几十倍乃至上千倍。
目前,GPU已经发展到了较为成熟的阶段。利用GPU来训练深度神经网络,能够充分发挥其数以千计计算核心的能力,在使用海量训练数据的场景下,所耗费的时间大幅缩短,占用的服务器也更少。若是对适当的深度神经网络进行合理优化,一块GPU卡至关于数十甚至上百台CPU服务器的计算能力,所以GPU已经成为业界在深度学习模型训练方面的首选解决方案。
如何使用GPU?如今不少深度学习工具都支持GPU运算,使用时只要简单配置便可。Pytorch支持GPU,能够经过to(device)函数来将数据从内存中转移到GPU显存,若是有多个GPU还能够定位到哪一个或哪些GPU。Pytorch通常把GPU做用于张量(Tensor)或模型(包括torch.nn下面的一些网络模型以及本身建立的模型)等数据结构上。python

25.1 单GPU加速

使用GPU以前,须要确保GPU是可使用,可经过torch.cuda.is_available()的返回值来进行判断。返回True则具备可以使用的GPU。
经过torch.cuda.device_count()能够得到可以使用的GPU数量。
如何查看平台GPU的配置信息?在命令行输入命令nvidia-smi便可 (适合于Linux或Windows环境)。图5-13是GPU配置信息样例,从中能够看出共有2个GPU。
web

图5-13 GPU配置信息算法

把数据从内存转移到GPU,通常针对张量(咱们须要的数据)和模型。
对张量(类型为FloatTensor或者是LongTensor等),一概直接使用方法.to(device)或.cuda()便可。后端

对于模型来讲,也是一样的方式,使用.to(device)或.cuda来将网络放到GPU显存。服务器

 

25.2 多GPU加速

这里咱们介绍单主机多GPUs的状况,单机多GPUs主要采用的DataParallel函数,而不是DistributedParallel,后者通常用于多主机多GPUs,固然也可用于单机多GPU。
使用多卡训练的方式有不少,固然前提是咱们的设备中存在两个及以上的GPU。
使用时直接用model传入torch.nn.DataParallel函数便可,以下代码:网络

这时,默认全部存在的显卡都会被使用。
若是你的电脑有不少显卡,但只想利用其中一部分,如只使用编号为0、一、三、4的四个GPU,那么能够采用如下方式:数据结构

或者架构

其中CUDA_VISIBLE_DEVICES 表示当前能够被Pytorch程序检测到的GPU。
下面为单机多GPU的实现代码。
(1)背景说明
这里使用波士顿房价数据为例,共506个样本,13个特征。数据划分红训练集和测试集,而后用data.DataLoader转换为可批加载的方式。采用nn.DataParallel并发机制,环境有2个GPU。固然,数据量很小,按理不宜用nn.DataParallel,这里只是为了说明使用方法。
(2)加载数据并发

(2)把数据转换为批处理加载方式
批次大小为128,打乱数据。dom

(3)定义网络

(4)把模型转换为多GPU并发处理格式

运行结果
Let's use 2 GPUs
DataParallel(
(module): Net1(
(layer1): Sequential(
(0): Linear(in_features=13, out_features=16, bias=True)
)
(layer2): Sequential(
(0): Linear(in_features=16, out_features=32, bias=True)
)
(layer3): Sequential(
(0): Linear(in_features=32, out_features=1, bias=True)
)
)
)
(5)选择优化器及损失函数

(6)模型训练,并可视化损失值。

运行的部分结果
In Model: input size torch.Size([64, 13]) output size torch.Size([64, 1])
In Model: input size torch.Size([64, 13]) output size torch.Size([64, 1])
Outside: input size torch.Size([128, 13]) output_size torch.Size([128, 1])
In Model: input size torch.Size([64, 13]) output size torch.Size([64, 1])
In Model: input size torch.Size([64, 13]) output size torch.Size([64, 1])
Outside: input size torch.Size([128, 13]) output_size torch.Size([128, 1])
从运行结果能够看出,一个批次数据(batch-size=128)拆分红两份,每份大小为64,分别放在不一样的GPU上。此时用GPU监控也可发现,两个GPU都同时在使用。

(7)经过web查看损失值的变化状况

图5-16 并发运行训练损失值变化状况
图形中出现较大振幅,是因为采用批次处理,并且数据没有作任何预处理,对数据进行规范化应该更平滑一些,你们能够尝试一下。

单机多GPU也可以使用DistributedParallel,它多用于分布式训练,但也能够用在单机多GPU的训练,配置比使用nn.DataParallel稍微麻烦一点,可是训练速度和效果更好一点。具体配置为:

单机运行时使用下面方法启动

 

25.3使用GPU注意事项

使用GPU能够提高咱们训练的速度,若是使用不当,可能影响使用效率,具体使用时要注意如下几点:(1)GPU的数量尽可能为偶数,奇数的GPU有可能会出现异常中断的状况;(2)GPU很快,但数据量较小时,效果可能没有单GPU好,甚至还不如CPU;(3)若是内存不够大,使用多GPU训练的时候可经过设置pin_memory为False,固然使用精度稍微低一点的数据类型有时也效果。

相关文章
相关标签/搜索