如果你基于pytorch训练模型,然后,你想加快训练速度,增大batch_size,或者,你有一台配置多张显卡的机器,还是说你有多台带显卡机器,你想利用起来,分布式训练你的模型,那这篇文章对你有点用。
    基于以上的需求,我趟了一遍,记录下我遇到的坑都有哪些,怎么跨过去。
    先看一下我主要的工具:anaconda,apex,horovod。就这三个。
    接下来的工作,全部在conda环境内完成,所以安装一个最新版的conda,然后创建一个新的环境,并且激活这个环境。
    在这个全新的环境里面,安装模型训练需要的所有package。
    三种配置conda新环境的方法:
    a.最最简单的办法,直接拷贝 path_to_conda/anaconda3/envs下面的环境,移植到新机器对应环境下。但是这个方法有前提条件:首先是,最好新旧机器的硬件配置、系统版本是一样的;第二是环境内的package的安装过程不需要配置额外参数。
    b.导出conda环境,在新机器上创建。显然这种方式的前提和第一种相似。
    c.当环境无法移植进来时,只能一个一个安装
    安装好环境后建议检查以下cuda和pytorch版本是否匹配,在python脚本内使用以下方法检查:
    Apex是Nvidia开发维护的工具,使用简便的API实现混合精度训练和分布式训练根据以下链接安装apex:
    此处,需要确定pip的路径,必须是你想要的env内的pip,不然可能会安装到base env内。一种简单的办法是path_to_conda/anaconda3/envs/bin/pip安装,前提是你的环境装上了pip。以上链接给出了混合精度和分布式的example,按照例子,增加几行代码即可。
    启动分布式训练的命令:
    如果你要指定使用某几张显卡:
    Apex内的混合精度训练amp使用起来后,可以看到同样的数据,同样的batch size时,
显存消耗减少到原来的60%,同时GPU-Util保持在较高值。在2080Ti的机器,batch size原来至多能达到12,使用apex.amp后可以达到24,效果显著。
    而Apex的分布式训练DistributedDataParallel可以使模型在单机多卡上分布均匀的训练,同时GPU-Util保持在较高值。
ubuntu怎么安装python    另外,apex的分布式我只用到了单机多卡的训练,官方仅给出了单机多卡的训练方式,未知是否可以以及如何配置多机多卡训练。
    选择horovod是因为它是目前多机多卡训练性能最优的工具(其实是尝试了pytorch自带的分布式工具失败后,调转头。)
    关于尝试pytorch自带方法
    选用NCCL后端,遇到
    追溯bug查到源码
    无法往下追溯。
    切换gloo后端,遇到问题:
    这两个问题都没有解决,促使我回头去整horovod。
    按照以上链接指引,安装horovod。首先是要安装Open MPI,第一次安装直接按照官方文档:
    运行分布式训练的时候,遇到问题:
    根据以下horovod的troubleshooting文档(仔细阅读,帮你避坑)
    重新安装:
    重新安装openMPI后需要重新安装horovod。
    这里概要了代码所需要的修改步骤。
    详细阅读这个文档,可以对分布式的常用变量和步骤有所了解后,你应该可以知道以下的启动命令怎么设置了。
    这条命令意思是:要在四台机器上启动分布式,server替换为对应机器的IP,‘:’后面表示该机器配备了几张显卡, ‘-np’表示总共起几个进程,相应也即是几张显卡。
    确认一点我之前的疑问:horovod可以自动去启动从机内正确的conda环境下的python运行代码。这显然是有前提的:所用的机器配置和环境必须一模一样。
    所以,只要在主机的运行conda envs内,运行以上命令即可。这一点相比pytorch的分布式,需要在每台机器启动命令,方便的多。不过horovod需要你告诉它训练脚本的绝对路径,以及代码内也不要使用相对路径。
    ubuntu下,ifconfig查看网络接口名称,使用内网地址对应的网络名称,我的是enp0s31f6,设置环境变量:
    可以多机多卡运行代码。
    这两者可以一起用,其实说的是apex.amp和horovod搭配使用。这样会让你单机减少显存开销同时多机一起训练,双剑合璧的感觉。
    用法和很简单,先初始化 horovd优化器,再初始化amp优化器,截止目前为止,两个工具的东家并没有官方地相互支持。因此这两个优化器并不能完美兼容,在接下来的训练过程中,horovod优化器需要调用的成员变量amp优化器并没有。
    horovod开发者在 git issue上给了以下方案:
    我的网络环境配置是千兆交换机,1000Mb/s带宽,也就是理论每秒最多达到125MB/s带宽。实测大约能达到80MB/s。在horovod运行时,节点机器之间来回传输数据速度大约是60MB/s,一个网络模型有250MB,因此每一个batch传输一次数据,完成all_reduce,就需要4-5秒时间。这样训练过程,显卡大量时间闲置,等待数据。
    解决办法有三种:
    a.性能最优:更改硬件,将多个显卡放在同一台主机。省去传输时间开销。
    b.使用万兆交换机,1G带宽网卡,提高数据传输效率。
    c.代码内修改不同机器之间权重的同步频率,由每个batch同步改为 N个batch后同步。
验证 horovod优化器内参数backward_passes_per_step是控制多个batch才做一次all_reduce,但是不能控制数据回传频率。因此该方案还需要研究下怎么做。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。