ML@Scale
首发于ML@Scale

科普:分布式深度学习系统(一)

前段时间我在一个回答里面挖了一个坑,说要通俗的梳理一下分布式深度学习系统这一块,今天我来把这个坑填上。

这篇文章很长,所以我会分三个部分来发,欢迎各位订阅关注。

这篇专栏文章有以下两个目的:

  1. 科普目的:我希望这篇文章能帮助不在这个领域但是又比较感兴趣的童鞋们了解一下这个领域的不同研究方向以及研究方法。
  2. 广告目的:当然,这篇文章的的主要目的是为了比较简单的介绍Petuum Inc.在分布式机器学习上的部分技术和研究,以及我自己的几个工作。 :)

分布式机器学习一般在研究些什么

分布式机器学习是个很大的领域,也是个很成功的领域:从纯学术角度来说,这个领域“坑”大,维度很广,不管是算法、理论,还是模型、系统,有非常多值得探索和研究的问题;从工业应用来说,这个领域相比其他某些领域与工业和实际应用贴的更近,所以这个领域的成果相比其他一些领域也更容易被部署到开发过程和产品中。在这篇文章中,我会比较专注于“scientific discussion”,所以我会更多的从paper、从学术的角度来讨论这个问题。但是由于分布式机器学习和工业应用息息相关,所以分布式机器学习完全可以从工程、产品的角度来讨论。如果有时间我也可以再写另外一篇文章从这个角度来讨论一下,各位应该能看到一个完全不同的理解。

在开始讨论之前,我想先笼统的介绍一个这个领域的研究者一般“在研究什么”,这样更方便我把后面的讨论限定在一个小的范围内,同时也可以给为对其他子领域感兴趣的读者一些有用的引导信息。前面我说过,分布式机器学习是一个多维度(multi-dimensional)的研究领域,也是一个跨领域(cross-domain)的研究领域,上到理论证明,算法设计,下到模型设计、应用、系统设计和研究,分布式机器学习几乎涉及到机器学习的各个方面。所以很难说你应该去哪个会议的论文集上去找相关论文,因为这个领域的论文既会出现在各大机器学习会议上(NIPS, ICML,ICLR),也会出现在各大系统会议上(SOSP,OSDI,ATC,EuroSys,SoCC)和各个应用对应的顶级会议上(CVPR,KDD),甚至在某些你可能觉得不太相关的领域,比如数据库(SIGMOD, VLDB)甚至编程语言(PLDI)的会议上也会出现大规模机器学习的影子。所以我会倾向于按照研究方法所处的维度来分类(而不是按照论文发表的会议来分),这样方便我们快速从几百篇NIPS/ICML抑或其他论文集里面找出那些感兴趣的。大致上,我们可以把这个领域的相关研究分成下面四个类别(这个分类并不绝对):

(1)从统计、优化理论、优化算法角度来做。这一块研究主要用到的方法包括优化(optimization)和统计学习理论(statistical learning theory),当然还有一些其他的理论工具,不过这里我概括的讲一下最常见的。由于大多数机器学习任务本质上是在一组训练数据上最小化某个loss,而在这个优化的过程中,我们比较关心问题包括优化速度、最优解的质量、训练出来的模型的质量、需要多少训练数据,所以就难免要研究优化理论和统计学习理论(这两套理论一般会有不同的构造,这里我就不介绍了)。在大规模机器学习里面,我们一般会想方设法的把某个机器学习模型或者算法的训练或测试时间或其他成本降低,所以这时候我们就比较关心下面这些问题:我通过分布式并行或其他方法加速训练后,这个新算法还能保证收敛到之前相同的最优值(或者一个满意的最优值)吗?在分布式环境下,收敛能有多快,比非分布式训练快多少?收敛的有多接近,和单机上跑出来的最优解一样吗?收敛需要什么假设?应该怎么设计训练过程(比如,怎么抽样数据、怎么更新参数)从而保证能接近某个最优解,同时还保证加速?这方面的论文通常会提出一个新的分布式优化算法来加速机器学习任务,并附带理论证明,这些证明通常围绕在算法的特性上,会做一些收敛分析(convergence analysis),推导收敛率,证一些asymptotics,等等。这些理论十分有价值,因为它可以帮助我们理解分布式机器学习模型和算法在分布式这个设定下的行为和特性,进而可以用来指导实践。大部分论文还有一些实验,甚至会有一个系统,用来验证这个算法的正确性和性能。这方面的论文很多,比较有代表性的比如这篇(起初发表在HotOS 2012上,后来中了NIPS 2013的Oral):

More Effective Distributed ML via a Stale Synchronous Parallel Parameter Server. Qirong Ho, James Cipar, Henggang Cui, Seunghak Lee, Jin Kyu Kim, Phillip B. Gibbons, Garth A. Gibson, Greg Ganger, Eric P. Xing. NIPS 2013.

还有我上个回答的问题里面廉相如同学做的一系列研究,都是非常不错的。

(2)机器学习模型及解法角度。这方面的论文一般会直接去改某个现存的模型,使其能运行在大规模环境下,甚至开发一个全新的机器学习模型,也或者提高解这个模型需要用到的算法(这个算法不一定是优化算法,因为解(学习)一个模型,优化只是其中一步)。举个例子,比如把话题模型(topic model)改成某种分布式的,让它具备某些好的性质,比如稀疏性(sparsity),以更容易被并行化(parallelize),同时能保证得到同样质量(甚至更好)的收敛结果;或者设计一个新的模型,让他的计算模式天生就和分布式系统的模式契合,抑或是修改解这个模型的方法(比如图模型里面的variational inference和sampling methods),降低其复杂度、提高其并行度,等等。这方面也有很多非常杰出的文章,这里我也推荐几篇:

Asymptotically Exact, Embarrassingly Parallel MCMC. Willie Neiswanger, Chong Wang, Eric P. Xing. UAI 2014.
LightLDA: Big Topic Models on Modest Compute Clusters. Jinhui Yuan, Fei Gao, Qirong Ho, Wei Dai, Jinliang Wei, Xun Zheng, Eric P. Xing, Tie-yan Liu, Wei-Ying Ma. WWW 2015.
SaberLDA: Sparsity-Aware Learning of Topic Models on GPUs. Kaiwei Li, Jianfei Chen, Wenguang Chen, Jun Zhu. ASPLOS 2017.

如我前面所说,这里大家可能也感受到了,分布式机器学习可能出现在各大领域的会议、期刊,这里列的三篇,一篇发表在机器学习会议UAI上,一篇发表在IR(information retrieval)的会议WWW上,还有一篇直接发表在体系结构的顶会ASPLOS上。

(3)从系统角度。由于我们要把机器学习搬到集群上,所以就不可避免的要面对很多分布式系统里的问题,比如:

  • 一致性(consistency):多台机器一起计算一个模型的时候,应该如何保证不同机器上模型参数、计算过程的一致性?
  • 容错(fault tolerance):在一个几千个节点的大集群上启动了一个要跑半个月才能完成的训练任务,跑到一半某几个节点宕机了,怎么办?
  • 通讯(communication):不同节点间怎么通信比较快?通信带宽比较小,通信比较拥塞的时候呢?
  • 存储(storage):机器学习任务一般都涉及到很多数据预处理以及大量的I/O,怎么为不同的部署环境(分布式集群、单机、GPU)设计合理的存储方式?
  • 资源管理(resource management):集群很贵,一般都是共享的。假如某个用户用当前集群跑机器学习任务A,另一个用户跑机器学习任务B,再来一个用户用这个集群跑数据处理任务C,怎么给不同的任务分配硬件资源保证他们协调进行?
  • 编程模型(programming model):如何设计好的编程模型,让用户更方便的写机器学习程序?或者,让用户可以直接把他们写的程序放到系统里面来就自动变成分布式的并获得加速?

等等。这方面的研究通常都会提出并实现一个分布式机器学习系统,从各个方面设计这个系统,并验证其设计的合理性:包括这个系统底层用什么算法保证能获得加速(scalability),系统具体如何设计和实现以应对我上面提到的这些问题,系统提供给用户什么样的编程接口以方便用户在上面写程序,系统怎么部署到不同环境下,等等。这篇专栏将要讨论的一个重点就和这一块比较相关。这方面有代表性的论文可能大家都比较熟,因为你们用的很多机器学习或相关的工具就是由此而来,比如CMU之前的GraphLab, 我们组的Petuum,以及TensorFlow,等等。

(4)从应用角度。这个角度就更有趣了,通常这类工作是出于解决一个具体应用问题的目的,但是这个应用可能需要用分布式计算来加速,于是这些工作就会相应的提出一些方法和specification来实现这一点。由于这些工作直接在解决应用层面的问题,虽然他们可能不如前面三类那么通用,但这些工作很多可以直接部署到产品里面。这方面的论文也挺多且非常具有价值,比如很多做大规模矩阵分解、推荐系统的文章,这里我就不列举了。

但是我要提醒各位读者注意一点的是,以上这个分类绝对不是互斥的。分布式机器学习的很多工作一般都会同时做好几件事情,比如同时做了算法,也证明了对应的理论;或者说设计了一个模型,同时还提供了一个系统实现。比如我前面提到的这篇

More Effective Distributed ML via a Stale Synchronous Parallel Parameter Server

就是分布式机器学习一个里程碑式的文章,这个文章提了一个很generic的算法,提供了在某些合理假设下的收敛证明(优化),并且在这个基础上提了一个合理的编程模型,最后给了一个系统实现(当然最后导致整个Petuum大平台的诞生,这个后面再说)。有兴趣的同学可以关注一下这个文章以及后续的一系列工作,比如这两篇综述性质的文章:

Petuum: A new Platform for Distributed Machine Learning on Big Data. Eric P. Xing, Qirong Ho, Wei Dai, Jin Kyu Kim, Jinliang Wei, Seunghak Lee, Xun Zheng, Pengtao Xie, Abhimanu Kumar, and Yaoliang Yu. IEEE Transactions on Big Data, Volume:1 Issue:2, pp49 - 67, 2015
Strategies and Principles of Distributed Machine Learning on Big Data. Eric P. Xing, Qirong Ho, Pengtao Xie, Wei Dai. Engineering, Volume:2, pp179 - 95, 2016.

相似的系列工作还有伯克利的教授Joseph Gonzalez以及GraphLab的一系列工作。


闲着扯了这么多,我希望能先帮各位对这个领域建立一个初步但又比较宏观的认识。由于这个领域真的很大,所以我不可能用一篇知乎专栏来覆盖到每个方面。由于我自己比较关注大规模深度学习,所以接下来我主要介绍一下这两年分布式深度学习系统这个方向的几个工作,以及我个人比较关注的一些问题。

但是我要提前声明一下,这篇文章不是一个严格的survey,所以我不会涵盖这个子领域的每篇文章。我只会按照我自己的理解和思路来讲讲几篇我认为比较重要的。


基本概念,以及要解决的问题

深度学习重新成为一个热题源于2012年底NIPS上面那篇AlexNet的论文,用卷积神经网络(CNN)跑ImageNet,并且刷新了很多记录。AlexNet文章里面干货很多,除了那一系列把一个几百万个参数的大神经网络调通的技巧以外,其实最重要的一个信息是:这个工作中的神经网络是在GPU上,并且是两个GPU上并行训练出来的。如果你在那个时候(2012 - 2013年左右)试图重现过那篇工作里的结果,你可能会和我有差不多的发现:当时作者公开的cuda-convnet只包含了部分代码并且仅仅支持单GPU训练,并不能很轻易的复现结果;而且Alex写的那个代码确实不太容易看懂...所以这里要先感谢一下Yangqing Jia,做了Caffe,并且成功复现了AlexNet的结果,从此CNN被带到千家万户...

回到话题上,其实在同一年NIPS 2012上,以及第二年的ICML 2013有两篇很重要的文章:

Large Scale Distributed Deep Networks. Jeffrey Dean, Greg Corrado, Rajat Monga, Kai Chen, Matthieu Devin, Mark Mao, Marc'aurelio Ranzato, Andrew Senior, Paul Tucker, Ke Yang, Quoc V. Le, Andrew Y. Ng. NIPS 2012.
Deep Learning with COTS HPC, Adam Coates, Brody Huval, Tao Wang, David Wu, Bryan Catanzaro, Andrew Ng. ICML 2013.

这两篇文章可能总体上并没有AlexNet那篇工作那么出名,不过其实是两篇很有启发性的文章。第一篇Large Scale Distributed Deep Networks即为Google的第一代深度学习系统Distbelief,而第二篇Deep Learning with COTS HPC是Andrew Ng的一个学生Adam Coates (目前在百度北美供职)的文章。这两篇文章里面的核心思想就是把分布式机器学习里面的数据并行(data parallelism)和模型并行(model parallelism)用在深度学习之上——通过两种并行方法把深度学习大规模化到集群上。其中,Distbelief这个系统既有数据并行也有模型并行,而COTS HPC这个系统主要使用了模型并行。很遗憾的是,两篇文章都没有公开代码。

数据并行和模型并行是分布式机器学习里面两个很重要的概念,我们在后面会经常提到。所以我这里简要介绍和区分一下这两个的概念。

何为数据并行,顾名思义,数据并行就是把数据分到不同的计算资源(节点)上,让不同节点处理不同的数据:由于我们有多个节点在并行的处理数据,所以在单位时间内,我们就理应能够处理更多的数据,也即达到了并行计算的目的。对应到机器学习任务里面, 我们的目的是通过并行计算加速模型收敛过程,所以把数据并行应用到机器学习任务里面就很直观:我们先把所有的训练数据分成很多份(data partition),然后让不同的计算节点在每一份上训练模型,再想办法把每个节点上的模型参数(或状态)同步起来,似乎就可以用分布式计算来加速机器学习任务了。这也就是Distbelief里面用集群来加速深度学习的主要方法。

相比较于数据并行,模型并行就是一个更为复杂的概念,甚至很难给出一个严格的定义。大概意义上,我们可以把模型并行理解为:我们先把一个大的机器学习模型划分成很多小块,然后把每小块对应的参数、状态和计算任务分在不同的计算节点上执行,再想办法进行同步。模型并行要解决的问题也很多,一方面,我们希望通过模型并行获得加速(当然),另一方面,当某些模型在单机上无法训练的时候(比如内存不够用),我们就只能用模型并行把它放到多机上训练了。在模型并行里面,如何划分这个机器学习模型并没有一个统一的办法,比如在矩阵分解(Matrix Factorization)或者话题模型(Topic Model)里面,我们通常会把一个大的需要学习的参数矩阵分成很多小块,然后把每一块对应的计算任务和参数更新等映射到在不同的节点上执行;再比如在深度学习里面训练一个比较大的神经网络的时候,可能一个GPU内存放不下,我们则可以把一个网络的的不同层对应的计算任务放到不同的节点上执行,也可以把同一层的任务细分成很多份,然后把每一份分到每个节点上执行;甚至,我可以用一个机器学习模型去学习应该如何划分模型。这里,我也可以给出几个很有趣的工作:

STRADS: A Distributed Framework for Scheduled Model Parallel Machine Learning. Jin Kyu Kim, Qirong Ho, Seunghak Lee, Xun Zheng, Wei Dai, Garth A. Gibson, Eric P. Xing. EuroSys 2016.
Device Placement Optimization with Reinforcement Learning. Azalia Mirhoseini, Hieu Pham, Quoc V. Le, Benoit Steiner, Rasmus Larsen, Yuefeng Zhou, Naveen Kumar, Mohammad Norouzi, Samy Bengio, Jeff Dean. ICML 2017.

前面这篇文章提了一个编程模型,能让你很容易的写模型并行程序,而后面这一篇则直接用增强学习的方法去学习如何划分模型使系统的负载最小。


通过上面的介绍,我们大概注意到,数据并行在训练数据很大的时候非常有效,因为通过数据并行我们可以更快的扫数据训练模型。而模型并行似乎在要训练的模型很大(模型参数很多,或者训练一个iteration需要的计算非常多)的时候更有效,因为它把一个模型划分成很多小块并且分布到不同的机器上。其实在很长一段时间内,这也是圈内的一个共识——当数据很多模型很小,扫一个epoch需要很多时间时,大家倾向于设计数据并行的系统来解决问题 (大部分深度学习模型符合这种条件);而当模型很大,一台机器(或GPU)的内存放不下,抑或是让一台机器上单独完成一个iteration的计算太慢的时候,大家倾向于用模型并行来解决问题(比如大规模的Linear Regression, MF, LDA等)。而且数据并行和模型并行也并不冲突,两者可以同时存在,Petuum和TensorFlow就是两者皆支持的系统。但是,我会在后面重新讨论这个“共识”,因为当把深度学习搬到GPU集群上的时候,会有新的问题出现并影响这个结论。

不管是数据并行还是模型并行,当应用到机器学习上的时候,除了计算任务之外,我们都不得不去做一些“同步”任务(synchronization),以保证训练最终能收敛,并收敛到一个理想的最优点,而怎么做这个同步就是设计分布式机器学习系统的一个核心问题。我前面说了,设计一个分布式机器学习系统的目标是能够获得加速——在最理想情况下,我们希望应该能够获得线性加速。也就是说,我每多加一个计算节点进来,相对于单机,就应该获得额外的1倍加速。但是由于同步不同节点上的计算任务或参数通常会产生额外的开销,这个开销可能会大于、甚至几倍于计算开销。如果这个系统设计的不合理,这个开销就会导致你的训练在多机上并不能获得加速,甚至于出现这种情况:当你用了好几倍于单机的计算资源来并行你的机器学习训练程序,却发现比单机还要慢。围绕这个问题,DistBelief这篇系统提出了一些简单的方法来划分数据和模型(即把数据并行和模型并行应用到深度学习上),还简单介绍了一个用来同步不同节点上计算任务的方法,也就是参数服务器(parameter server )。Parameter server是一个很重要的概念,在DistBelief之后还有很多把parameter server用到深度学习中的工作,比如Microsoft的Porject Adam:

Project Adam: Building an Efficient and Scalable Deep Learning Training System. Trishul Chilimbi, Yutaka Suzue, Johnson Apacible, and Karthik Kalyanaraman. OSDI 2014.

但是如果追根溯源的话,Distbelief应该是第一个公开发表并正式提出这个泛型的工作;当然,在Distbelief之前也有一些工作用到了很类似的架构,感兴趣的同学可以去翻翻相关文章。

接下来我会在我的下一篇专栏中详细介绍一下parameter server。但是注意,DistBelief,以及很多2015年之前的深度学习系统都是基于CPU集群的,而AlexNet这篇文章出来之后,深度学习陆续开始迁移到GPU上。当把深度学习移到GPU上后,由于GPU的特性(更快的计算速度,专有的GPU内存),很多问题会变的很不同并导致这些旧的CPU系统的并行效率大大降低,我会在后面重点讨论这些问题,而这些问题就是我的两个工作Poseidon和GeePS要解决的核心问题。


题外话:一点八卦以及小广告

大家可能比较感兴趣的一点是我在前面提到很多和Petuum有关的文章。因为Petuum的成员们大多在社交网络上比较低调,所以其实我觉得有必要在这里给大家稍微介绍一下。

我反复提到的一篇很重要的文章:

More Effective Distributed ML via a Stale Synchronous Parallel Parameter Server. Qirong Ho, James Cipar, Henggang Cui, Seunghak Lee, Jin Kyu Kim, Phillip B. Gibbons, Garth A. Gibson, Greg Ganger, Eric P. Xing. NIPS 2013.

的一作也就是发明了stale synchronous parallel(SSP)模型的作者Qirong Ho,2014年CMU博士毕业,现在是Petuum Inc.的VP,我们一般亲切称呼他"荣哥"。荣哥的研究涉及机器学习理论、模型、系统,非常广泛,而且荣哥对每个领域的见解都非常深刻。如果各位开会的时候有机会碰到荣哥,可以仔细找他聊聊。

这篇文章里面的作者们其后沿着这条线做了不少知名系统,都是整个Petuum大项目的一部分:

比如Jinliang Wei(韦金良)和Wei Dai(戴维),后续沿着SSP搭了Bosen这个系统:

Managed Communication and Consistency for Fast Data-Parallel Iterative Analytics. Jinliang Wei, Wei Dai, Aurick Qiao, Qirong Ho, Henggang Cui, Gregory R. Ganger, Phillip B. Gibbons, Garth A. Gibson, Eric P. Xing. SoCC 2015.

Bosen获得了SoCC 2015 Best Paper Award。金良最近在研究机器学习程序的自动并行化,而戴维加入创业,现在是Petuum Inc.的产品研发总监。再比如Henggang Cui(崔恒纲)沿着SSP也做了很多系统层面的工作,最近刚从CMU毕业,感兴趣的同学可以去看看他的一系列工作。

而这几位其实同时都是我的coauthor。我和崔恒纲合作了GeePS:

GeePS: Scalable Deep Learning on Distributed GPUs with a GPU-Specialized Parameter Server. Henggang Cui, Hao Zhang, Gregory R. Ganger, Phillip B. Gibbons, Eric P. Xing. Eurosys 2016.

我会在这一系列专栏的后面几篇里详细介绍;同时我也会重点介绍我和韦金良、戴维以及另外几个coauthor的另一篇工作——Poseidon系统:

Poseidon: An Efficient Communication Architecture for Distributed Deep Learning on GPU Clusters. Hao Zhang, Zeyu Zheng, Shizhen Xu, Wei Dai, Qirong Ho, Xiaodan Liang, Zhiting Hu, Jinliang Wei, Pengtao Xie, Eric P. Xing. ATC 2017.

其中,Zeyu Zheng(郑泽宇)今年刚从北大毕业入学UMich读博士,而我的另一个合作者Shizhen Xu(徐世真),是ISC12世界超算竞赛的冠军(抱到大腿有木有)。

我的另外几个coauthor,Xiaodan Liang(梁晓丹),Zhiting Hu(胡志挺)以及Pengtao Xie(谢澎涛)想必机器学习圈的各位都很眼熟,各个都是大腿,其中几位在知乎上偶尔也回答一些问题,抱到大腿的我有多开心!

Poseidon系统现在已经移植到Petuum Inc.内部进行产品开发,而这一块的另一位负责人,也是Petuum的员工Hong Wu(吴竑),曾经一手搭建了豆瓣的paracel系统,在开源社区中贡献了非常多的出色代码。


当然,八卦了这么多是为了一个实在的目的:

我上面提到的大部分大牛现在都是Petuum Inc.的干将。Petuum最近正在大力扩张,诚聘英才,欢迎各位投简历,在这里你可以和世界上最顶尖的一批机器学习、计算机视觉、自然语言处理和分布式系统的大牛一起工作!欢迎各位扔简历给我!

编辑于 2017-09-07

文章被以下专栏收录