最近一直在尝试着分布式深度学习的架构,主要的原因一方面是几台机子全是1060卡,利用深度网络在较大数据样本上训练的效率极其低下,所以尝试着将几台机子做成分布式,看看能否提高训练效率;第二方面是有人习惯使用tensorflow,有人习惯使用keras,也有人喜欢使用pytorch等,虽然这些框架各自都有分布式的实现,但总的来说不能统一到一个平台上,造成使用上有不好的体验。在查资料的时候正好看到了horovod这个框架,它是集成了多个深度框架的一个统一平台,搭建和使用起来都比较方便,所以打算尝试基于horovod搭建一个分布式环境,供后期使用。可惜没有使用docker去部署,其中配置的过程中遇到不少坑,还好都解决了。
一.分布式中的ps架构和ring-allreduce架构
1.ps架构
在Parameter server架构(PS架构)中,集群中的节点被分为parameter server和worker两类。其中parameter server收集、更新和存放模型的参数,而worker负责计算模型参 数的梯度。在每个迭代过程中,ps聚合所有worker传回的梯度,然后更新参数,并将新的参数广播给worker。缺点是集群通信不均衡问题,类似木桶效应。
ps架构同步随机梯度下降SGD如下图:
2.ring-allreduce架构
在Ring-allreduce架构中,各个设备都是worker,并且形成一个环,如上图所示,没有中心节点来聚合所有worker计算的梯度。在一个迭代过程,每个worker完成自己的mini- batch训练,计算出梯度,并将梯度传递给环中的下一个worker,同时它也接收从上一个worker的梯度。对于一个包含N个worker的环,各个worker需要收到其它N-1个worker的梯度 后就可以更新模型参数。其实这个过程需要两个部分:scatter-reduce和allgather,百度开发了自己的allreduce框架,并将其用在了深度学习的分布式训练中。如下图。
相比PS架构,Ring-allreduce架构有如下优点:
a. 带宽优化,因为集群中每个节点的带宽都被充分利用。而PS架构,所有的worker计算节点都需要聚合给parameter server,这会造成一种通信瓶颈。parameter server的带宽瓶颈 会影响整个系统性能,随着worker数量的增加,其加速比会迅速的恶化。
b.此外,在深度学习训练过程中,计算梯度采用BP算法,其特点是后面层的梯度先被计算,而前面层的梯度慢于前面层,Ring-allreduce架构可以充分利用这个特点,在前面层梯 度计算的同时进行后面层梯度的传递,从而进一步减少训练时间。在百度的实验中,他们发现训练速度基本上线性正比于GPUs数目(worker数)。
二.准备工作:
1.一开始是利用虚拟机虚拟了三台机子进行了cpu版的成功测试,可惜GPU无法用在虚拟环境上。
2.后来弄了三两台真实的物理机,将原windows都改为linux系统。
a.安装nvidia驱动
b.安装cuda
c.安装cudnn
d.安装pytorch和tf
e.两台机子ssh相互免密码登录
f.nfs共享文件系统(将脚本和样本放在这里),共它机器挂载在此目录下
g.openmpi的安装配置
h.nccl的安装配置
i.horovod的安装配置
(我这里使用的版本是:ubuntu16.0.4、nvidia384.130、cuda9.0、cudnn7.6.4、pytorch1.1.0、tf1.12、nccl2(nccl2.x版本为多机多卡)、openmpi4.0.0…)