1 为什么需要分布式深度学习
两大最主要的原因:
数据量在爆炸式增长。
模型复杂度不断增加。
大规模数据以及大型的神经网络结合在很多机器学习的任务上带来了超凡的表现。在训练深度学习模型的时候,当数据以及参数量变大的时候计算资源是决定我们算法迭代速度的关键要素之一。
“Methods that scale with computation are the future of AI.”
2 分布式训练的基本问题
2.1 DML(Distributed Machine Learning)架构分类
(1) 基于参数服务器的架构(PS)
基于PS架构是最常用的,最经典的Tensorflow、MXNet都是支持PS架构,优势显而易见,被多数主流框架支持;部署简单;弹性扩展好;鲁棒性强。劣势是容易产生中心化瓶颈。
(2) 基于Mesh的架构
基于Mesh负载更加均衡,但扩展性比较差。
(3) 基于Ring的架构
基于Ring这个架构带宽最优,意思是如果给定这样带宽资源,同步效率不可能做得比Ring更高,所以大家都很认可它。劣势是鲁棒性差,比如把所有的节点连成一个圈,只要有一个节点断掉,这个工作流就没有办法进行,鲁棒性很差。
2.2 参数同步模式
BSP同步
优势在于每一个worker下一次开始都能拿到最新的全局参数,意味着同步迭代质量很高,但劣势也很明显,那些跑的快的worker要等慢的worker,导致计算资源很大程度被浪费。
ASP异步
迭代质量偏低,本来BSP运行100次、200次就可以收敛,但ASP需要运行300次、400次,甚至异构性很强的话,这种情况有可能就不收敛。
SSP折中
允许同步的过程中采用旧的参数进行同步,但旧的参数能够旧到什么程度必须有一个阈值。如果认为比我慢一次迭代的参数,接受它。
2.3 数据/模型并行模式
数据并行是把数据切成不同的份,分别放到不同的节点上。如这里有三个节点,每个节点能到一个完整的模型实例,数据有100G,每一个切成33G,每个节点一份一份读,读完以后大家同步,同步完成以后训练,训练以后再读。这种模式也是目前最经典的训练,在以往数据量没有这么大,模型也没有这么复杂,大家都倾向于用这种方式进行训练。现在随着数据量变大、模型变大,可能大家开始考虑采用一种模型并行方式。
1、同步开销:对于数据来讲,每次迭代要进行同步参数量,就是N个模型的参数,这个参数会很大,一个VGG模型是582兆,训练4个就是2-3个G,如果带宽能力跟不上的话,仅通信就可以占很大的比例。对于模型并行传输只是每两个工作节点之间的边缘层,每个迭代只需要往外传几十兆的数据。
2、GPU利用率:对于一些经典模型,其实GPU利用率并不会很高,如图想说明的意思是在Batch Size为16个情况下,有大约一半时间GPU的利用率达不到50%,也就是说GPU相当一部分计算资源处于空闲,这是目前机器学习的一个现状。如果想把GPU利用率提高,只要增加Batch Size不就可以了,但是GPU memory又有问题。如果在数据并行下,Batch Size超过32,达到64,这个GPU memory肯定会不足。但如果对于模型并行来讲,GPU memory constraints小很多。
3、负载均衡:模型并行是不如数据并行的。负载均衡如果没有做好,如何调节负载均衡?就是Straggler问题(落后节点)如何解决,这一点模型并行比数据并行好很多,因为模型并行的负载均衡通过模型迁移实现,数据并行的负载均衡通过数据迁移实现。
4、I/O扩展性:同样地,模型模型不如数据并行。并且如果想充分利用GPU算力,需要给足够CPU的核技术预处理,否则GPU没有办法被打满。根据实验,基于NVCaffee进行训练,训练AlexNet模型,打满一块Tesla P100 GPU需要消耗-12CPU核,训练ResNet-18,打满P100需要消耗-7CPU核。
2.4 新型加速技术的应用
机器学习有三方面内容要解决:计算、通信、存储。目前存储还不是什么瓶颈,大家都在考虑计算和通信。
过去GPU算力提升35倍,但反观通信,五年前是1-10T,现在还是1-10T,再往后走计算还会发展的越来越快,通信很难跟上计算的步伐,由此得出未来想要加速大规模分布式机器学习应该在通信上发力。
目前通信的瓶颈主要出现在Linux内核中,常见的加速方法:
1、可以跨过内核,就是英特尔的DPDK方案
优势:跨内核,用户态可以直接操作裸包。
劣势:Polling开销,需要用户态实现拆包和封装逻辑。
2.直接把内核处理逻辑offload到网卡设备,也不走内核,即RDMA方案。
优势:零拷贝,硬件实现拆封包逻辑。
劣势:编程复杂,PFC拥塞控制问题。
2.5 未来优化方向
针对以上已有的问题/瓶颈,关于未来优化的发展方向如下:
层次化的架构设计优化;
更加自适应的拓扑感知算法;
迭代速度与迭代质量如何折中,BSP、ASP、SSP优化选型;
模块化同步方案优化,如做不到每个节点进行参数同步,肯定要先分组,然后有效组织;
以及最后,灵活并行度,数据/模型并行搭配使用。
3 当前流行的分布式深度学习框架-Horovod
3.1 Horovod特点
Horovod是基于环形All-reduce通信的同步SGD算法的开源分布式训练框架,支持TensorFlow、PyTorch以 及 Keras。它使用bandwidth-optimal通信协议,建议使用RDMA (RoCE、InfiniBand) 高速网络。
Horovod可以无缝与TensorFlow集成,安装也可以经过pip一键完成。
另外,它的设计灵感来自Baidu、Facebook等研究成果,名字来源于俄罗斯传统民间舞蹈,参加者手牵手围成一圈跳舞。
3.2 Horovod技术栈
3.3 Horovod使用
初步代码流程
hvd.init() # 初始化Horovod
config.gpu_options.visible_device_list = str(hvd.local_rank()) # 向每个TensorFlow进程分配一个GPU
opt=hvd.DistributedOptimizer(opt) # 使用Horovod优化器包裹每一个常规TensorFlow优化器,Horovod优化器使用ring-allreduce平均梯度
hvd.BroadcastGlobalVariablesHook(0)# 将变量从第一个流程向其他流程传播,以实现一致性初始化。如果该项目无法使用 MonitoredTrainingSession,则用户可以运行hvd.broadcast_global_variables(0)替换
使用现况
Horovod是社区使用最广泛的分布式深度学习框架,是Uber开发并开源的一套先进的分布式系统,它并不依赖于某个框架,而是采用目前业界广泛认可的基于环形All-reduce通信的同步SGD算法,通过计算与通信异步、梯度合并、梯度压缩等设备间通信优化手段,完成allreduce、allgather等集体操作通信工作。这一特性使得Horovod可以非常方便地与主流深度学习框架TensorFlow、PyTorch、 MXNet等进行匹配(在Tensorflow上使用最多),在大规模GPU集群上的训练性能远高于原生框架的训练性能,提供非常高效的分布式训练性能加速。Horovod的另一大优点在于其提供的接口极为简单,用户只需修改几行代码,就可实现显著的训练性能提升。
3.4 Horovod相对优势
优势主要在性能方面,由Benchmark图可以看出相较于分布式TensorFlow,Horovod在通等硬件配置下,的确性能高得多,甚至逼近了理论理想峰值。
另外Horovod的通过RDMA优化,可以更加进一步提升部分场景下的性能。
参考资料
另,特别感谢露露露大文同学的资料整理与支持!