前言

在数据越来越多的时代,随着模型规模参数的增多,以及数据量的不断提升,使用多GPU去训练是不可避免的事情。Pytorch在0.4.0及以后的版本中已经提供了多GPU训练的方式,本文简单讲解下使用Pytorch多GPU训练的方式以及一些注意的地方。

这里我们谈论的是单主机多GPUs训练,与分布式训练不同,我们采用的主要Pytorch功能函数为DataParallel而不是DistributedParallel,后者为多主机多GPUs的训练方式,但是在实际任务中,两种使用方式也存在一部分交集。

使用方式

使用多卡训练的方式有很多,当然前提是我们的设备中存在两个及以上的GPU:使用命令nvidia-smi查看当前Ubuntu平台的GPU数量(Windows平台类似),其中每个GPU被编上了序号:[0,1]:

在我们设备中确实存在多卡的条件下,最简单的方法是直接使用torch.nn.DataParallel将你的模型wrap一下即可:

net=torch.nn.DataParallel(model)

这时,默认所有存在的显卡都会被使用。

如果我们机子中有很多显卡(例如我们有八张显卡),但我们只想使用0、1、2号显卡,那么我们可以:

net=torch.nn.DataParallel(model,device_ids=[0,1,2])

或者这样:

很简单的操作,这样我们就可以比较方便地使用多卡进行训练了。

另一种方法

在前言中提到过,另一种方法DistributedParallel,虽然主要的目标为分布式训练,但也是可以实现单主机多GPU方式训练的,只不过比上一种方法稍微麻烦一点,但是训练速度和效果比上一种更好。

为什么呢?

请看官方相关介绍:

nccl backend is currently the fastest and highly recommended backend to be used with Multi-Process Single-GPU distributed training and this applies to both single-node and multi-node distributed training

好了,来说说具体的使用方法(下面展示一个node也就是一个主机的情况)为:

上述的命令和我们平常的命令稍有区别,这里我们用到了torch.distributed.launch这个module,我们选择运行的方式变换为python -m,上面相当于使用torch.distributed.launch.py去运行我们的YOUR_TRAINING_SCRIPT.py,其中torch.distributed.launch会向我们的运行程序传递一些变量。

为此,我们的YOUR_TRAINING_SCRIPT.py也就是我们的训练代码中这样写(省略多余代码,只保留核心代码):

我们要注意,上述代码在运行的过程中产生了很多个,具体多少个取决你GPU的数量,这也是为什么上面需要torch.cuda.set_device(args.local_rank)设定默认的GPU,因为torch.distributed.launch为我们触发了n个YOUR_TRAINING_SCRIPT.py进程,n就是我们将要使用的GPU数量。

有一点想问的,我们每次必须要使用命令行的方式去运行吗?当然也可以一键解决,如果我们使用Pycharm,只需要配置成下面这样就可以了:

单显卡与DataParallel多显卡训练对比

最近两天训练一个魔改的mobilenetv2+yolov3,同样的优化方法同样的学习率衰减率,所有的参数都相同的情况下,发现单显卡训练的方式竟然比多显卡训练的方式收敛更快。

配置为两张1080Ti,使用Pytorch的版本为1.0.0。下图红线为使用一张1080Ti训练的情况,蓝线为使用两张1080Ti训练的情况,batchsize每张显卡设置为10,也就是说,使用两张显卡训练时的batchsize为单张显卡的两倍,同一个step时,双卡走的步数为单卡步数的两倍。这里使用的多卡训练方式为DataParallel。

但是下图可以看到,在双卡相同step的情况下,虽然红色曲线的损失相较蓝色下降的稍微慢一些,但是到了一定时候,两者的损失值会相交(此时未达到最低损失点),也就是说使用双卡和单卡训练时候loss损失收敛的速度是一样的。

更奇怪的是,下图中,在验证集中,单显卡虽然没有双显卡的准确度曲线增长迅速,但是到了某一点,单显卡的曲线会超过双显卡训练的精度,也就是说,单卡训练在前期没有双卡训练效果显著,但是到了训练中期效果就会优于双卡。

(上述两个图为训练早期和中期的展示,并没有完全训练完毕)关于为什么会这样的情况,有可能是因为训练中期所有的激活值更新幅度不是很明显(一般来说,权重值和激活值更新幅度在训练前期比较大),在不同GPU转化之间会损失一部分精度?。当然这仅仅是猜测,博主还没有仔细研究这个问题,待有结论时会在这里进行更新。

注意点

多GPU固然可以提升我们训练的速度,但弊端还有有一些的,有几个我们需要注意的点:

多个GPU的数量尽量为偶数,奇数的GPU有可能会出现中断的情况

选取与GPU数量相适配的数据集,多显卡对于比较小的数据集来说反而不如单个显卡训练的效果好

多GPU训练的时候注意机器的内存是否足够(一般为使用显卡显存x2),如果不够,建议关闭pin_memory(锁页内存)选项。

采用DistributedDataParallel多GPUs训练的方式比DataParallel更快一些,如果你的Pytorch编译时有nccl的支持,那么最好使用DistributedDataParallel方式。

关于什么是锁页内存:

pin_memory就是锁页内存,创建DataLoader时,设置pin_memory=True,则意味着生成的Tensor数据最开始是属于内存中的锁页内存,这样将内存的Tensor转义到GPU的显存就会更快一些。

主机中的内存,有两种存在方式,一是锁页,二是不锁页,锁页内存存放的内容在任何情况下都不会与主机的虚拟内存进行交换(注:虚拟内存就是硬盘),而不锁页内存在主机内存不足时,数据会存放在虚拟内存中。显卡中的显存全部是锁页内存,当计算机的内存充足的时候,可以设置pin_memory=True。当系统卡住,或者交换内存使用过多的时候,设置pin_memory=False。因为pin_memory与电脑硬件性能有关,pytorch开发者不能确保每一个炼丹玩家都有高端设备,因此pin_memory默认为False。

pytorch指定用多张显卡训练_Pytorch中多GPU训练指北相关推荐

  1. pytorch指定用多张显卡训练_Pytorch多GPU训练

    Pytorch多GPU训练 临近放假, 服务器上的GPU好多空闲, 博主顺便研究了一下如何用多卡同时训练 原理 多卡训练的基本过程 首先把模型加载到一个主设备 把模型只读复制到多个设备 把大的batc ...

  2. Yolov5如何在训练意外中断后接续训练

    Yolov5如何在训练意外中断后接续训练 1.配置环境 2.问题描述 3.解决方法 3.1设置需要接续训练的结果 3.2设置训练代码 4.原理 5.结束语 1.配置环境 操作系统:Ubuntu20.0 ...

  3. Pytorch中多GPU训练指北

    前言 在数据越来越多的时代,随着模型规模参数的增多,以及数据量的不断提升,使用多GPU去训练是不可避免的事情.Pytorch在0.4.0及以后的版本中已经提供了多GPU训练的方式,本文简单讲解下使用P ...

  4. 计算机视觉之pytorch图片数据转换、增广、增强及多GPU训练

    计算机视觉之pytorch图片数据转换.增广及多GPU训练 一.数据增强 1.1 图片数据增强方式 二.代码实现 2.1 数据增强方法 2.2.1 水平方向随机翻转torchvision.transf ...

  5. 论文阅读|训练过程中动态改变训练方案的Dynamic R-CNN

    目录 论文相关信息 Abstract. 1 Introduction 2 Related Work 3 Dynamic Quality in the Training Procedure 3.1 Pr ...

  6. matlab中的神经网络训练,MATLAB中的神经网络训练

    我试图向前馈送反向传播,但是在网络训练之后,当模拟和打印模拟输出时,我看不到任何靠近目标的值,但它只是一个数字. 代码如下.什么是错,什么是问题? 前馈反向传播: >> load('E:/ ...

  7. Yolov8如何在训练意外中断后接续训练

    1.错误尝试 在训练YOLOv8的时候,因为开太多其他程序,导致在100多次的时候崩溃,查询网上相关知识如何接着训练,在yolo5中把resume改成True就可以. 在yolov8中也这样尝试,将u ...

  8. pytorch多GPU训练实例与性能对比

    以下实验是我在百度公司实习的时候做的,记录下来留个小经验. 多GPU训练 cifar10_97.23 使用 run.sh 文件开始训练 cifar10_97.50 使用 run.4GPU.sh 开始训 ...

  9. MinkowskiEngine多GPU训练

    MinkowskiEngine多GPU训练 目前,MinkowskiEngine通过数据并行化支持Multi-GPU训练.在数据并行化中,有一组微型批处理,这些微型批处理将被送到到网络的一组副本中. ...

最新文章

  1. linux php环境升级,php5.6升级到php7.1.10(Linux环境)
  2. PCL安装与环境变量配置(Win10)
  3. 【CyberSecurityLearning 29】Linux下命令帮助、压缩、vim、软件安装
  4. 云应用基础技术成熟需七年时间
  5. 安卓学习日记:初识Android Studio · java环境配置和AS安装
  6. 完善获取数据库数据的写法
  7. 小白都能看懂的缓存入门
  8. vue watch的监听
  9. python强转字符串_在Python 3中将Exception转换为字符串
  10. 在Mac上将WebP图像批量转换为JPG的方法
  11. 复旦大学计算机a类专业,如何看待浙大A类学科39个,全国第一,录取分却比复旦、上交低?...
  12. 修改OpenJDK字体渲染,无可见改进
  13. 圣剑传说 玛娜传奇(Legend of Mana)(LOM)全防具取得方法
  14. 医疗行业能否成功入场直播带货?
  15. 为什么你的广告投放效果不好?这5点做到了吗?
  16. 5、流程变量Variables
  17. github简易教程
  18. 波浪下划线怎么设置_波浪线符号(word小技巧)
  19. 怎样运用EDIUS中的色彩平衡滤镜较色
  20. 使用PCL库将KITTI数据集可视化

热门文章

  1. Go 高性能编程技法
  2. 致谢!LF AI Day
  3. select、poll、epoll之间的区别(搜狗面试)
  4. H.264视频RTP负载格式/NALU的类型
  5. 从Google Mesa到百度PALO(数仓)
  6. 大剑无锋之SpringBoot和Spring的区别
  7. Spark _16 _SparkUIMaster HA
  8. 海量数据处理:如何从10亿个数中,找出最大的10000个数?(top K问题)
  9. 【Java多线程】实现Runnable接口方式 / 继承Thread类方式;使用synchronized锁实现线程安全;线程安全的懒汉式单例模式;死锁问题示例
  10. Echarts多个坐标轴多组/一组数据 - 温度降水量示例