在过去的几年里,进步深度学习已经推动了图像处理、语音识别和预测方面的巨大进步。在优步,我们将深度学习应用于整个业务;从自动驾驶研究到出行预测和欺诈预防,雷竞技是骗人的深度学习让我们的工程师和数据科学家能够为用户创造更好的体验。
TensorFlow由于各种原因,已成为优步设计的深层学习图书馆。首先,该框架是深度学习最广泛使用的开源框架之一,这使得新用户易于滚动。它还结合了高性能的能力,以便用低级模型细节进行修补- - - - - -例如,我们可以同时使用两种高级api,比如Keras,并使用nvidia实现自己的自定义运营商CUDA工具包。此外,TensoRFlow还有用于各种深度学习用例的端到端支持,从开展云服务器,移动应用程序,甚至自驾驶车辆生产模型的探索性研究。雷竞技是骗人的
上个月,优步工程公司推出了米开朗基罗这是一个内部的ML-as-a-service平台,它民主化了机器学习,使大规模构建和部署这些系统变得容易。在本文中,我们拉开帷幕Horovod是Michelangelo的深度学习工具包的开源组件,这使得更容易开始- - - - - -加快了- - - - - -具有Tensorflow的分布式深度学习项目。
分发
正如我们开始培训更多和更多的机器学习模型,它们的大小和数据消耗大幅度增长。在大部分情况下,模型仍然足够小,以适应服务器内的一个或多个GPU,但随着数据集的增长,培训时间也是如此,其中有时花了一周或更长时间! - 完成。我们发现自己需要一种在保持短期训练时使用大量数据的方式训练。为实现这一目标,我们的团队转向分布式培训。
我们开始测试标准分布式TensorFlow技术。在几个模型尝试后,显而易见的是,我们需要进行两次调整。
首先,在遵循文档和代码示例之后,并不总是清除所需的代码修改以分配其模型培训代码。标准分布式Tensorflow包引入了许多新概念:工人,参数服务器,tf.server(),tf.ClusterSpec (),tf.train.syncreplicasoptizizer(),和tf.train.replicas_device_setter ()举几个例子。虽然对某些场景有好处,但这也引入了难以诊断的bug,从而减慢了培训速度。
第二个问题是关于优步规模下的计算所带来的挑战。在运行了一些基准测试之后,我们发现我们无法让标准的分布式TensorFlow扩展到我们需要的服务。例如,在128个gpu上进行培训时,由于扩展效率低下,我们损失了大约一半的资源。
当我们运行标准的TensorFlow时基准测试套件在128个NVIDIA Pascal GPU上(如图1所示),我们发现Inception V3和ResNet-101模型都无法利用近一半的GPU资源。
有动力充分利用我们的GPU能力,我们在Facebook发布纸质后,我们对分布式培训感到更加兴奋,“准确,大型小纤维SGD:1小时内训练想象,展示他们在256个gpu上用一个小时的时间训练ResNet-50网络数据并行性采用创新的学习率调整技术。这个里程碑非常清楚地表明,大规模的分布式培训可以对模型开发人员的生产力产生巨大的影响。
利用不同类型的算法
在这次实现之后,我们开始寻找更好的方法来培训我们的分布式Tensorflow模型。由于我们的模型足够小,以便在单个GPU上适应单个GPU或单个服务器中的多个GPU,因此我们尝试使用Facebook的数据并行方法来分布式培训。
概念上,数据并行分布式培训范例很简单:
- 运行训练脚本的多个副本,每个副本:
- a)读取数据块
- b)在模型中运行
- c)计算模型更新(梯度)
- 多个副本之间的平均梯度
- 更新模型
- 重复(从步骤1a)
标准的分布式TensorFlow包使用参数服务器方法来平均梯度。在这种方法中,每个进程都有两个潜在角色:工作人员或参数服务器。工人们处理训练数据,计算梯度,并将它们发送到参数服务器进行平均。
虽然这种方法提高了我们的表现,但我们遇到了两个挑战:
- 确定worker服务器和参数服务器的正确比例:如果使用一个参数服务器,则可能成为网络或计算瓶颈。如果使用多个参数服务器,则通信模式变为可以使网络互连饱和的“全面”。
- 处理增加的Tensorflow程序复杂性:在我们的测试期间,分布式Tensorflow的每个用户都必须明确地开始每个工作者和参数服务器,传递服务发现信息,例如所有工人和参数服务器的主机和端口,并修改培训程序以构造tf.server()有适当的tf.ClusterSpec ()。此外,用户必须确保所有操作都适当使用tf.train.device_replica_setter()并修改代码来使用塔利用服务器内的多个gpu。这常常导致陡峭的学习曲线和大量的代码重构,占用了实际建模的时间。
2017年初,百度发表了一篇文章,“将HPC技术带入深度学习,“传播一种不同的算法,用于平均梯度并将这些渐变传送到所有节点(上面的步骤2和3),以及称为环释放,以及一个分叉的张力流通过这些算法的实施方式。该算法基于2009纸中介绍的方法“工作站群的带宽优化全减算法”由Patarasuk和元。
在Ring-AlrReduce算法中,N个节点中的每一个与其两个对等体2 *(n-1)次通信。在此通信期间,节点发送和接收数据缓冲区的块。在第一个n-1迭代中,接收值被添加到节点缓冲区中的值。在第二个n-1迭代中,接收值替换节点缓冲区中保持的值。百度的论文表明,该算法是带宽 - 最佳的,这意味着如果缓冲区足够大,则它将最佳地利用可用网络。
除了网络 - 最优,还更容易理解和采用。用户利用A.消息传递接口(MPI)实施如打开MPI.启动TensorFlow程序的所有副本。然后,MPI透明地建立了工人互相通信所需的分布式基础设施。所有用户都需要做的是将它们的程序修改为使用A平均渐变allreduce()操作。
介绍HOROVOD.
认识到一个环全减少的方法可以提高可用性和性能,激励我们致力于我们自己的实现,以解决Uber的TensorFlow需求。我们采用百度的草案实现TensorFlow ring-allreduce算法,并在此基础上进行构建。我们概述了我们的过程如下:
- 我们将代码转换成一个独立的Python包,名为Horovod该舞蹈以一种传统的俄罗斯民间舞蹈命名。在这种舞蹈中,表演者手挽手围成一圈跳舞,就像如何分布式Tensorflow流程使用Horovod彼此通信。在任何时候,Uber的各个团队都可能使用不同的Tensorflow版本。我们希望所有团队能够利用戒指重新验证算法,而无需升级到最新版本的Tensorflow,将修补程序应用于其版本,甚至花时间构建框架。有一个独立的包允许我们削减将Horovod从大约一小时到几分钟安装所需的时间,具体取决于硬件。
- 我们取代了百度戒指释放的实施nccl.。NCCL是NVIDIA用于集体通信的库,它提供了ring-allreduce的高度优化版本。NCCL 2引入了跨多台机器运行ring-allreduce的能力,使我们能够利用它的许多性能提升优化。
- 我们增加了对适合单个服务器的模型的支持,可能支持多个GPU,而原始版本只支持适合单个GPU的模型。
- 最后,受一些初始用户反馈的启发,我们对API进行了一些改进。特别地,我们实现了一个广播操作,在所有的worker上强制对模型进行一致的初始化。新的API让我们能够将用户需要引入单个GPU程序的操作减少到4个。
接下来,我们讨论如何使用Horovod为您的团队的机器学习用例!
通过Horovod分发您的培训工作
虽然分布式Tensorflow培训的参数服务器范例通常需要仔细实现重要的样板代码霍洛维德只需要几句新台词。下面,我们提供了一个使用Horovod分发的TensorFlow程序示例:
| 进口纹orflow.作为特遣部队 进口HOROVOD.TENSORFLOW.作为hvd #初始化HOROVOD. hvd.init() #PIN GPU用于处理本地等级(每个过程一个GPU) 配置=tf.ConfigProto () config.gpu_options.visible_device_list.=str(hvd.local_rank()) #构建模型…… 损失=… 选择=tf.train.adagradoptimizer(0.01) #添加Horovod分布式优化 选择=HVD.DistributedOptimizer(选择) #添加钩子来广播0级的变量到所有其他进程 #初始化。 钩子=[hvd.BroadcastGlobalVariablesHook (0)) #做训练操作 Train_op.=选择..Inimize(损失) #的MonitoredTrainingsession.负责会话初始化, #从检查点恢复,保存到检查点,完成后关闭 发生#或发生错误。 借tf.train.MonitoredTrainingsession(checkpoint_dir=“/ tmp / train_logs”, config =.配置, 钩=钩子)作为mon_sess: 而不mon_sess.should_stop(): #执行同步培训。 mon_sess.run (train_op) |
在这个例子中,粗体文本突出显示了使单gpu程序分布式所必需的更改:
- hvd.init()初始化Horovod。
- config.gpu_options.visible_device_list.=str(hvd.local_rank())将GPU分配给每个TensorFlow进程。
- opt = HVD.distributedOptimizer(OPT)用HOROVOD优化器包装任何常规Tensorflow优化器,它使用ring-anyrreduce负责平均梯度。
- hvd.BroadcastGlobalVariablesHook (0)从第一个进程广播变量到所有其他进程,以确保一致的初始化。如果程序不使用MonitoredTrainingsession.,用户可以运行hvd.broadcast_global_variables (0)操作相反。
然后,用户可以在多个服务器上使用MPIRUN.命令:
$ mmpirun -np 16 -x LD_LIBRARY_PATH -H
server1:4、server2:4 server3:4, server4:4 python train.py
的MPIRUN.命令分销火车到四个节点,并在每个节点的四个gpu上运行。
Horovod也可以分发Keras按照相同步骤的程序。(您可以找到TensorFlow和Keras的脚本的示例HOROVOD GITHUB页面。)
Horovod的易用性、调试效率和速度使它成为对发布单gpu或单服务器程序感兴趣的工程师和数据科学家的高效助手。接下来,我们将介绍Horovod时间线,这是一种在分布式培训工作期间提供对工作节点状态的高层次理解的方法。
HOROVOD时间轴
正如我们向Horovod的用户上,我们意识到我们需要一种方法,让他们在处理复杂分布式系统时容易地识别代码中的错误。特别是,很难使用本机Tensorflow时间表或CUDA PROFILER.因为用户需要从各种服务器收集和交叉引用配置文件。
有了Horovod,我们希望创建一种方法来提供跨节点的操作时间线的高级理解。为此,我们构建了HOROVOD时间轴,一个与Chrome兼容的horovod聚焦分析工具内容:跟踪跟踪事件分析查看器。用户可以使用HOROVOD时间表来查看每个节点在整个培训工作中的每次都在做什么。这有助于识别错误和调试性能问题。用户可以通过设置单个环境变量来启用时间表,并且可以通过浏览器查看剖视中的分析结果chrome: / /跟踪。
张解融合
在我们分析了一些型号的时间表后,我们注意到那些具有大量张量的人,例如Resnet-101,往往有很多小allreduce操作。如前所述,ring-allreduce以最优的方式利用网络如果张量足够大,但如果它们非常小,就不能有效或迅速地工作。我们问自己:如果多个小张量在进行环全化之前可以融合在一起会怎样?
我们的答案是:张量融合,一种将张量融合在一起的算法之前我们称之为霍洛华德的环-所有减少。当我们试验这种方法时,我们观察到在大量的层运行在未优化的模型上的性能提高了65%传输控制协议(TCP)网络。我们概述了如何使用张解融合,如下:
- 确定哪些张量可以减少。选择适合缓冲区并具有相同数据类型的前几个张量。
- 如果未先前分配,则分配融合缓冲区。默认融合缓冲区大小为64 MB。
- 将选定张量的数据复制到融合缓冲区中。
- 在融合缓冲区上执行allreduce操作。
- 将数据从融合缓冲区复制到输出张量。
- 重复直到没有更多的张量来减少循环。
随着HOROVOD,张量融合等内置米开朗基罗顶部的其他功能,我们可以通过我们的机器学习系统提高效率,速度和易用性。在我们的下一部分中,我们分享了展示HOROVOD表现的真实世界基准。
HOROVOD基准
我们重新运行官方Tensorflow基准修改为使用Horovod并将性能与常规分布式Tensorflow进行了比较。如图6所示,以上,我们观察到我们的规模能力的大量改进;我们不再浪费了GPU资源的一半- - - - - -实际上,使用Incepion V3和Reset-101型号的缩放实现了88%的效率标记。换句话说,培训大约是标准分布式Tensorflow的两倍。
自两块MPI和NCCL支持远程直接存储器存取(RDMA)支持网络(例如,通过Infiniband.要么RDMA通过融合以太网),我们使用RDMA网卡运行了其他一套基准测试,以确定它们是否有效地与TCP网络相比增强了效率。
对于Inception V3和ResNet-101模型,我们发现RDMA并没有显著提高我们的性能,仅比TCP网络提高了3%到4%。然而,RDMA确实帮助Horovod在两个模型上的扩展效率都超过了90%。
与此同时,当我们利用RDMA网络时,VGG-16模型的速度显著提高了30%。这可以解释为VGG-16的模型参数较多,这是由于使用了全连通层,且层数较少造成的。这些特性阻碍了从GPU计算到通信的关键路径,造成了网络瓶颈。
这些基准证明HOROVOD在普通的TCP和RDMA的网络上展示良好,尽管使用RDMA网络的用户将能够在使用具有大量模型参数的模型时挤出最佳性能并体验显着的效率增益,例如vgg-16。
对于Horovod,我们在深度学习中探索性能优化时只触及了表面;在未来,我们打算继续利用开源社区,利用我们的机器学习系统和框架来获取额外的性能收益。
下一步
今年早些时候,我们开源Horovod为每个人带来可访问的,可扩展的机器学习模式。有一些领域我们正在积极努力改善霍洛夫德,包括:
- 使得更容易安装MPI:虽然在工作站上安装MPI相对容易,但在集群上安装MPI通常需要一些努力;例如,有数量的工作负载管理器可用,应根据网络硬件进行不同的调整。我们正在开发用于在群集中运行Horovod的参考设计;为此,我们希望与MPI社区和网络硬件供应商合作,开发安装MPI和相关驱动程序的说明。
- 收集和分享关于分布式深度学习调整模型参数的学习:Facebook的论文“准确,大型小纤维SGD:1小时内训练想象描述了在分布式训练任务中建模超参数所需的调整,以达到与在单个GPU上训练相同模型相同或更高的精度,演示了在256个GPU上训练TensorFlow模型的可行性。我们认为,这一领域的深度学习研究仍处于早期阶段,并希望与其他团队合作,进一步雷竞技是骗人的扩大深度学习培训的方法。
- 添加非常大型型号的示例:Horovod目前支持的模型适合一个服务器,但可能跨多个gpu。我们渴望开发更多的例子,用于跨多个gpu的大型模型,并鼓励其他人也在这些类型的模型上测试Horovod。
我们希望简单起见Horovod使他人能够采用分布式培训,更好地利用他们对深度学习的计算资源。我们欢迎反馈和贡献:请报告您遇到的任何问题,共享加速,并发送拉出请求。
如果您有兴趣使用Uber以规模地制定机器学习,请考虑申请职务在我们的团队!






