前言
在过去的十年里,Yahoo一直持续投资建设和扩展Apache Hadoop集群,到目前为止共有超过4万台服务器和600PB数据分布在19个集群上。正如在2015 Hadoop 峰会上介绍的,我们在自己的服务器上开发了可扩展的机器学习算法,用于分类、排序和计算词向量。目前,Hadoop集群已成为Yahoo大规模机器学习的首选平台。
深度学习(Deep Learning, DL)是雅虎很多产品的核心技术需求。在2015 RE.WORK深度学习峰会上,Yahoo Flickr团队(Simon Osindero和Pierre Garrigues)阐述了深度学习如何被应用于场景检测、物体识别和计算美学。机器学习帮助Flickr自动完成给用户图片打标签,使得Flickr终端用户能够方便的管理和查找图片。
为使深度学习技术惠及更多的Yahoo产品,最近我们把此项技术迁移到自己的Hadoop集群上。基于Hadoop的深度学习主要有这些优点:
深度学习过程可以直接在我们存储数据的Hadoop集群上完成。避免了数据在Hadoop集群和深度学习集群之间的不必要传输。
深度学习可以被定义为一流的Apache Oozie工作流,使用Hadoop进行数据处理和Spark管道进行机器学习。
YARN支持深度学习。一个集群上可以同时进行多项深度学习实验。与传统方法相比,新方法事半功倍。在过去,我们有些项目组靠“记事本”手工调度GPU资源,这是很痛苦的,而且只对少数用户有效。
基于Hadoop的深度学习是深度学习的一个创新方法。业界现有的方法要求使用专用的集群,而基于Hadoop的深度学习不仅能达到专用集群的效果,还额外多出上述几项优点。
增强Hadoop集群
为了支持深度学习,我们在Hadoop集群上添加GPU节点。每个节点有4块Nvidia Tesla K80运算卡,每块卡配置2个GK210 GPU。这些节点的处理能力是我们Hadoop集群所使用的传统CPU的10倍。
在Hadoop集群上,GPU节点有两个独立网络接口,Ethernet和Infiniband。Ethernet作为对外通信的主要接口,Infiniband在GPU之间提供10倍以上速率的数据传输,并且支持通过RDMA直接访问GPU内存。
通过利用YARN最近推出的节点标签功能(YARN-796),我们可以在jobs中声明容器是在CPU还是GPU节点加载。GPU节点的容器能使用Infiniband以极高的速度交换数据。
分布式深度学习:Caffe-on-Spark
为了在这些强化的Hadoop集群上支持深度学习,我们基于开源软件库开发了一套完整的分布式计算工具,它们是Apache Spark和Caffe。我们可以利用下面的命令行向集群GPU节点提交深度学习计算任务。
spark-submit –master yarn –deploy-mode cluster
–files solver.prototxt, net.prototxt
–num-executors <# of EXECUTORS>
–archives caffe_on_grid.tgz
–conf spark.executorEnv.LD_LIBRARY_PATH=“./caffe_on_grid.tgz/lib64”
–class com.yahoo.ml.CaffeOnSpark caffe-on-spark-1.0-jar-with-dependencies.jar
-devices <# of GPUs PER EXECUTOR>
-conf solver.prototxt
-input hdfs://
-model hdfs://
在上述命令行中,用户可以指定使用的Spark executor个数(–num-executors),每个executor分配的GPU个数(-devices),HDFS上存放训练数据的路径,以及模型在HDFS上的存储路径。用户使用标准Caffe配置文件来确定Caffe算法和深度网络的拓扑结构(ex.solver.prototxt, net.prototxt)。
如上图所示,在YARN的Spark加载了一些executor。每个executor分配到一个基于HDFS的训练数据分区,然后开启多个基于Caffe的训练线程。每个训练线程由一个特定的GPU处理。使用反向传播算法处理完一批训练样本后,这些训练线程之间交换模型参数的梯度值。这些梯度值在多台服务器的GPU之间以MPI Allreduce 形式进行交换。我们升级了Caffe,以支持在一台服务器上使用多个GPU,并以RDMA协议来同步DL模型。
Caffe-on-Spark让我们集Caffe与Spark二者之长处,将其应用于大规模深度学习,使深度学习任务如其它Spark应用一样易于操作。集群中的多个GPU被用于训练基于HDFS大规模数据集的模型。
性能测试
Caffe-on-Spark支持(a)多个GPU,(b)多台机器进行深度学习。为了体现我们方法的优势,我们在ImageNet 2012数据集上进行性能对比测试。
首先,我们在单个Spark executor中分别使用1个、2个、4个、8个GPU对AlexNet数据集进行深度学习。如下图所示,训练时间随着GPU数量增加而缩短。当GPU数量为4个时,我们仅花费单个GPU所需时间的15/43=35%就能取得50%的准确率。所有上述执行过程的批大小均为256。使用8个GPU相比4个GPU性能并没有显著提升。因为每个GPU处理的数据量太少而无法充分地利用硬件性能。
随后,我们又在GoogLeNet数据集上进行了分布式性能对比测试,该测试比AlexNet的测试更深,且使用了更多的卷积运算,因此需要更强的计算能力。在每一轮运算中,我们给每个GPU分配的批大小为32,当有n个GPU参与运算时,32n是最有效的大小。我们的分布式算法旨在生成模型并且达到和单个GPU相当的准确率。使用4台服务器(4x8个GPU)训练,能在10小时内使top-5准确率超过80%(20%的误差)。注意1个GPU训练40小时后也只能达到60%的top-5准确率(40%的误差)。
GoogLeNet规模随着GPU数量的增加而扩大。对于60%的top-5准确率(40%的误差),8个GPU能比1个GPU提速680%。下表显示了达到70%和80% top-5准确率的速度提升幅度。如果我们仔细调整批数据大小(并不是将批大小都设为32n),速度还能提升更多。
开源资源
秉承Yahoo的开源承诺,我们向github.com/BVLC/caffe上传了一部分代码:
#2114…允许Caffe在单台计算机上使用多个GPU
#1148…支持计算机之间以RDMA协议传输数据
#2386…提升了Caffe的数据管道和预取技术
#2395…增加计时信息
#2402…更改Caffe的IO依赖为可选
#2397…重构Caffe的解法代码
在接下来几周的后续文章中,我们将分享Caffe-on-Spark的具体设计和实现细节。如果社区有足够的兴趣,我们也许会开源实现的代码。请将您的想法告知我们bigdata@yahoo-inc.com
总结
这篇文章初步描述了将Apache Hadoop生态系统和深度学习集成在同一个异构(GPU+CPU)集群的做法。早期的性能对比结果使我们倍受鼓舞,并计划在Hadoop、Spark和Caffe投入更多精力来使得深度学习在我们的集群上更加有效。我们期待和开源社区的朋友们在相关领域的并肩作战。
原文发布时间为:2015-10-15
本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“BigDataDigest”微信公众号