【CSDN现场报道】2014年12月12-14日,由中国计算机学会(CCF)主办,CCF大数据专家委员会承办,中科院计算所与CSDN共同协办,以推进大数据科研、应用与产业发展为主旨的 2014中国大数据技术大会 (Big Data Technology Conference 2014,BDTC 2014)暨第二届CCF大数据学术会议在北京新云南皇冠假日酒店盛大开幕。
2014中国大数据 技术大会首日全体会议中,卡耐基梅隆大学教授、ICML 2014程序主席邢波带来了名为“A New Platform for Cloud-based Distributed Machine Learning on Big Data”的主题演讲。期间,邢波表示,着眼当下大数据处理平台,大量资源都都浪费在集群的通讯同步上。即使比较优秀的平台,计算时间也只有20%,通讯时间占到80%,就比如Hadoop的通讯时间占到90%甚至更高。
卡耐基梅隆大学教授、ICML 2014程序主席 邢波
以下为演讲实录:
邢波:
我首先感谢大会组委会邀请我来给这儿做一个报告。我这个报告风格可能跟以前几个不一样,干货比较多,比较枯燥,有一些正规的实验结果,甚至有一些数学公式,另外我也很乐意分享一下刚刚从学生那得出的结果。
我想讨论一下用于大数据的分布式机器学习运算的平台。当我们面对大数据,大家首先问到的问题通常是,我们从大数据里面能挖到什么东西,大数据到底有什么用?这个问题大家已经看到了很多展示,这块就不再重复或者追加。
我这儿希望能够讲一个更加看似无趣但是基本的问题,如何来进行大规模的大数据运算,如何把它做对。这个原因是?现在数据量如此之大,随之而来关键的问题会是对数据的正确理解,而这里边的工具到底是什么呢?至少在我们计算机学家目前的经历来看,很多人同意机器学习和它代表的统计学习的算法可能是一个对数据进行有效挖掘的途径。
我这里就要探讨一下如何把这个工具过渡到大数据的平台上,而这个“大”字对以前的研究产生什么影响?有必要强调一下这个问题的重要性。现在有很多对大数据的忽悠,很多文章都会说数据就是金钱,有很多数据的话你就变得很有财富,甚至你变得非常聪明。但如果没有一个很好有效体系对这个数据作分析,其实数据不等于知识:就像森林里面倒下一棵树,你没看到的话,它倒没倒下,你并不知道。今天我就讲这些技术型的问题。
为什么大数据的机器学习挖掘比较困难,首先数据量变大,挑战了存储、通讯,甚至处理的极限,所以你要把它分布到一个大的多机的数据中心去而不再仅是单机上。但是其实挑战不仅仅是这一些,当数据变得很大的时候,你的问题变得很复杂,需要聪明大脑和聪明的模型理解。
大家在大型公司里面用到的模型有几百几千个亿的参数,从单机里面溢出需要并行处理,想把这步做对并不是简单的问题,这就涉及到第三个问题,这些软件包工具到底在哪儿?你可能看到刚才讲解者展示IBM的系统,余凯先生下面会展示百度的系统,大数据的问题目前都是大型企业他们专属权利,而比较屌丝级别的公司或非IT公司就没有办法处理,是不是这样的局面无法撼动?我想大数据工具库普及变得非常好用情况就会改观。
大数据工具库不能仅包括简单的工具诸如决策树,kNN,这些工具都有20、30年的历史还在用但并不是很有效;我们要的高大上的工具,深度学习、话题模型、协同过滤这些东西在很现代的文献里面出现,开始被很高级的公司积极使用,他们到底有什么样的一些技术上的挑战,防止普通人或者更多大公司使用?
我这里要提出一个问题:当你这个数据或者是模型大到了从一个机器内存里面溢出,大家希望显然是这么一张曲线:我不断加机器,越加越多能力越高,这是大家的期望。如果各位开发人员尤其工程人员有实际经历,我想你会告诉我,当我给你一千台机器后你的能力并没有增加一千倍;机器有很多的时候,你的资源中各种各样的时间浪费在没有用处计算上,比如说通讯、等待、协调这些方面。因此我们看到的一个曲线是这样的一个曲线--我们实际收获的计算能力并不随机器增加而增加,而是很快封顶了,甚至跌落了。对于计算机学家来说,固然去拿大数据来做挖掘,提供信息,亲自做一个数据挖掘选手很重要,但是我觉得计算机学家另外一个很重要的任务是提供方法论和工具,把这个曲线从这儿提到这儿,这就是我待会讲话中心内容。
我为什么说现在已有的系统不足以实现我们刚才所希望的功能呢?这块我举几个例子。比如说有很多机器学习的学者,他们显然对大数据很感兴趣,由于本身训练局限或者是习惯思维缘故,他们对系统知识通常并不了解,他们看到一百个机器跟一台机器的差别只不过乘了一百,中间的代价或者是机器的失效几率他们可以都不太考虑,所以他们的算法主要是针对数学上的正确性或者是迭代算法迭代次数减少性,但是他们不会钻研这个算法到底在一个真实的机器群上怎么运作;他们会写这么一个程序,中间有一句话:“并行运算”,然后就天真的假设这个就开始发生了,把这些算法程序放在很多机器上它们就能算好。
实际过程中,我至少看到是这样一个情况,你去做一个小实验,去测量用在计算上的时间和用在通讯上的时间,最好结果也无非如此:至少20%的时间花在机器上面,80%的时间花在等待,经常更糟,上面提到那种理想状态不存在,所以这些算法实际上通常无法应用。
另一方面,系统工程师对机器学习或者统计学习原理或者技术并不见得非常精通,他们所需要实现的目标是尽可能实现极高的迭代的输出,修正由于机器造成的一些损耗,所以他们会发展一些非常可靠、非常高通的技术。但是他们对于机器学习的算法通常是做了一个非常简单的假设:我只要把它能够跑起来,它肯定能跑对,肯定会收敛。如果系统中还有一个特殊编程模型,比如Spark里面有一个RDD,GraphLab中有一个节点模型,他们就会假设,无论什么机器学习的算法都可以转换成这么一个模型,这是工程师的任务。我就不知道各位工程师有没有试过把话题模型变成RDD或节点模型,这是很困难的,需要对机器学习原理有深刻掌握才能做到。因此你看不到复杂机器学习在这些系统上的普及应用。
所以系统方面的工作通常简化了在机器学习理论上的工作,把它变得理想化,最起码会造成一些资源上的浪费,但更严重会造成算法本身的失败会发散,你得到结果并没有用处。所以总结一下,由于两方面领域间的隔阂,通常我们在开发已知系统对对方的框架都产生了比较简单化的假设,实际工作中你丧失了很多机会,也造成了很多错误。
理想状况下有这么一个途径,你有很多任务和各种硬件设备,咱们中间有一个普世的算法或者框架,然后这个框架上能够来支持所有这些机器学习的软件,然后使用所有已知的硬件,中间这层机器之间的协调、通讯或者是错误处理应该是被抽象化被自动化,作为一个程序员我们不应该掌握去触碰这些东西。
这个问题到底是在什么层面上能够获得解决呢?我首先想指出这绝对不是一个软件的问题,在设计打造这样的一个界面的过程中,你不仅要懂得系统设计也要懂得机器学习的理论,而且还要懂得算法的设计,所以整个需要的技能是相当庞大的一个技术支持。所以这也就造成了这种问题的困难性,而且它就说明并不是所有人去碰这个问题,风险很大,回报率并不是很高,但总有人在做这样的事情,有人开发类似的操作平台或者框架。我们CMU的团队正在开展这样的工作,我待会想跟大家分享一下开发框架中比较有意思的思路和得到的经验教训。
这里首先要研究设计分布式的策略,怎么做分布。当你有多台机器的时候,显然把任务分布到每个机器上去,每个机器往前走,把中间结果存在局部的存储空间,他们完成的时间并不是一样,保证程序正确性你需要设置等待集合点,每一台端点工作机和那个叫做服务器头领机握手协同后可以接着往下走。机器学习算法有这么一个特点,不是一次性,需要反复进行迭代,这样就造成困难,在你选择对于系统的行为采取不同的措施的时候,它会产生不同的结果,有些结果就是像这样,很多时间浪费在通讯上面,或等待所有端点完成协同,这能保证你的结果很对,它很慢,但是对。另一种方法我把通讯协议可以简单化,让它不必等待彼此,有时候会得到一个很快的结果,但这种结果经常是一个发散的不正确的一个结果。
Hadoop,在过去被大家认为是一个适合写并行程序的平台,但是Hadoop对机器学习的算法是不是真正适合呢?我不知道各位在自己开发过程中有这样的经历,我自己在学校里面或者Facebook做访问教授的这方面的经历是相当悲惨:你在Hadoop掌握了一千台机器,你来写一个Hadoop的项目,但中间硬盘读取等等的瓶颈会极大程度限制了程序有效性,当你有很多机器的时候,彼此之间很难同步,大部分时间发生在等待里面。硬盘读取是相当昂贵的操作所以会耗费大量时间,经常造成程序相当难往前推进。
我们从这个地方出发,怎么来解决这个问题,是相当有意思的一个问题。这块为了表达我们的思路,有必要稍微展示一下到底机器学习的神秘性或者它的特点在哪儿?跟普通的程序有什么区别?我尝试了一下做了比较。通常写计算机程序希望是一个精密的执行,就像我搭一个楼,把一个蓝图精密到按步骤进行实现,这样保证这个楼能搭起来,错一步都不行。机器学习不是精密实现以前设定好的计划,而是通常实现一个数学优化问题,就像在体操里面有一个规定动作一个自选动作,爬这个山顶你可以从这条路爬,也可以从那条路爬,所以有一种容错性,有容错性就给了新的机会。而且机器学习可以写出这么个数学公式,达到最高点你可以用数学公式进行评估,解决途径通常可执行迭代程序,迭代程序本身有自动收敛性的特点。
当你在一定情况下进行迭代,不管你迭代精度是特别高还是比较高,它都有可能收敛,这就造成了机器学习算法既难又简单,关键看你从哪个角度解决。这里用容错性做一个比较:比如说你在做一个排序,我们知道这个东西是不能容错的,这块如果错了以后不改,最后结果是错的。这是传统计算机程序的普遍特点,一旦在某个结骨眼出了错,你必须改。机器学习算法的运行,就像这个有点喝醉的家伙在爬山,虽然醉了,但知道山顶在哪儿,他看得见,脚还能走,多多少少还是能爬上去,不见得爬得那么快,或者每一步都向上,走错了以后不一定要走回去,还要重走,这个地方和传统计算机程序是不一样的。
还有数据和模型的两相性,对于系统工程师,数据和模型并没有什么区别,它都是在内存里边的一些数字而已,把它分割没有问题,比如我有数据分在某一个机器上。我这儿有模型,模型指里面参数,比如神经网络参数可以把它分割,大了以后也可以做所谓的数据和模型并行。
在通常经典的系统设计里面,这两种并行没有区别,有时候你会看到Hadoop和Spark不相区分的并行处理。但是如果你仔细观察机器学习程序特点,你发现这两种并行的结果很不一样,当数据被并行的时候,他们之间是不相关的,所以你不需要对他们之间进行协调,需要对算出的分布的子结果进行一定的协调,但在他们算的过程中你不需要进行协调。
当模型被并行的时候,它中间实际是相关的,所以你不在过程中进行协调,最后结果就会出错,所以这种情况下你会发现,你对数据并行对模型并行需要做不同的通讯和系统设计,还有其它一些东西我就不多讨论。
我做一个总结,机器学习算法有它的独特性,基于优化的算法,而且用(递归)来实现,有一些容错的能力,有一些动态结构,然后它还是非同质的,有一些参数会回归很快,有些收敛很慢,你可以对收敛快做完停下来把资源另外使用,这都是要求编程员或者程序对机器学习算法有一定的了解,这样有一定的机会来进行加速。而这种东西在传统程序里面不存在,通常对于指令级的一个完全正确执行,造成这样很多技术上更多的措施,但在机器学习不见得很有必要。
看看已知的系统怎样解决这个挑战,大家都知道Spark实质上是Hadoop的升级版本,一开始需要把程序,模型,数据转换成一个叫做RDD的特殊数据结构,它是在内存中的,因而读写很快,后面迭代非常好。RDD保持一个过程树,所以在运算中如果出现问题很快找出问题所在,这都是RDD和Spark非常优异的特点,特别在数据库的处理或者非迭代的数据并行处理里面是非常有效的。
做模型并行要求全局性的一个协调,这样就会产生一些很大的代价,Spark上没有特别的机制来应对这种需要。Graphlab,用节点图来表示模型,数据,图上的边表示相关度的强弱,你可以依此写成一个节点程序自动做一个非同步的通讯,仍然保持这个程序最后能够正确收敛。这也是一个很好的思路,在很多情况下都产生了比较好的结果,甚至比Spark还要好。但它也有一些问题,数据量变得非常大,程序会变得非常沉重,效率不是很高。
我们组正在开发这么一个平台,叫Petuum,包含数据和模型并行两套功能,也对机器学习的特点做了比较深入的一个研究,对他们做了一些针对性的使用,所以我们系统对机器学习内部特点比较有针对性,他们有一些非常有意思的特性和功能,这块我可以总结一下。
大致结构是这样,它包含一个参数服务器,大家都知道参数服务器,给你提供很好编程的一个共享虚拟分布内存,大家在编程的时候不用对每个机器进行单独通讯;我们还有一个叫做调度器,它是能够对模型进行有效的分割,甚至是动态分割,然后做一个分布化和载量平衡。运行原理就跟机器学习的工程师写机器学习的算法基本一个思路,用迭代加上对公式的更新量的随机性而不是确定性的反复刷新,跟传统的是不一样的。
这个参数服务器有这样一个编程界面,你在写内存读取内存不需要对每一个机器做一个特殊的指令,而是用和单机读写形式上相似的通用指令。它使用了比较巧妙的所谓半同步的协调机制,这样可以显著降低使用在通讯上的时间,而加强在计算上的时间,所以你可以看到随着我们半同步参数的调整,我们这个通讯时间会显著下降,降到了以至于比计算时间还要少,这样使计算机的资源得到最大量的利用。
在调度器方面我们也用了基于机器学习考量的设计,调度机自动发现机器学习模型里面的一些结构,找出哪些参数是相关,哪些参数是不相关,然后对它们做相应分布,他们在分布运行的时候并不违反正确性、约束性,这样也会造成更快的收敛。
为什么这样做产生这样好的结果?这里边有一些比较深层的技术和科学原理,时间允许,我可以再讲几分钟。并行系统是没有理想的,我们当有好几台机器,显然不能希望它同步运算同步通讯,即使相同的多台机器放在机房里面温度不一样,行为都是不一样的,最后结果就是我们看到这样的情形。我们怎么来协调这样的一个缺陷呢?通常对编程高手,当然这不是问题,他可以对每一台机器做深层操作,可以避开所有的陷阱,对于普通程序员和低端用户,这种非常昂贵而且耗时开发过程并不见得能负担得起,我们需要还是非常简单的界面,让界面下面的支持框架做了通讯上的决定,这个决定在数据并行过程中可以被总结成一个所谓的叫做协调或者是同步协议。这个同步协议我们大家都知道,这一端包括Spark或者Hadoop协议完全协同,然后往下走,这个东西在数学上可证明是对的,但是造成有效性的损失。
另外一种比较肮脏的结果,我不同步了,让自己跑,对程序收敛性和正确性没有任何保障。我们采取的方法是走一个中间路线,做一个半同步,让机器在有限的窗口里做局部的运算,用参数值的局部版本做一个运算,不跟其它东西通讯,当这个窗口被突破的时候,我就必须停下来等,每一个线程到达窗口边界的时间是随机的,所以最后结果是所有线程都可以在最大程度上使用窗口做运算。我们关心的是,这东西显然变得更快,就像非同步的东西,但能不能保证正确性?结果是这样的,因为我们是有限的非同步或者半同步,你可以产生一个证明,产生的收敛结果跟同步结果是一样的。这是我目前知道的第一个对于这类操作系统做一个理论证明正确性的结果,这个系统有一定的理论价值甚至也是一个好的应用价值。
然后它的编程界面是相当普通的界面,你把不同的机器学习算法,像话题模型、矩阵分割或者是像线性或者逻辑回归都表示成参数服务器这样的表示,用这样一个很简单的高级语言来进行操作。结果如何呢?我们发现在不同的程序上面我们都获得了比这个同步或者是完全非同步的方法更好更快和更佳的收敛结果。
再讲模型并行,在数学上有一个更强烈的所谓的协调性的要求,这块我想用一个线性回归做一个简单的阐述。通常我们做线性回归需要估计参数,这个参数矢量是很高维的,也许100亿维,在普通存储机器里面放不下,或者放下以后用串行的方法来算很慢,所以你需要并行,那乱放行不行?最后发觉不行。在数学上可以获得这样一个形式:当你随机取两个参数,当你动用了其中一个参数,另一个参数,它的值和前面那个值相关,所以有一前一后要求,当你把这两个东西做并行,相关性就被破坏,而且无法收敛,这两个相关度在数据上有关系所以可以做定量计算,所以当两个参数非常相关我们需把它们放在同一个机器上面,这是相当昂贵的操作,理论上可通过画出一个节点图我们对每一对参数对做这样的预估,100亿维是很大的图,是不可操作的。
我们在这两种选择里面,纯粹图分割或者随机分割采取中间路线,我们可以想像参数里边并不是所有参数都是同样重要,有些东西重要,有些东西不重要,有些东西快收敛了,我们采用一种方法对参数进行大致评估,只对重要的东西进行处理,这是基于结构的并行化叫SAP,也可以用简单的编程界面。这是一个操作,从某一个方程里面取样,取一部分重要参数,对它结构进行分析,把它们向各个机器上做分布。
在第二个迭代里面,有可能结构会出现变化,可以再重新做这一步,这是用户之间的选择。分布策略有很多可能性,刚才说优先度的考量,哪些参数重要哪些参数不重要,你也可以做模块化考量,把参数分成几个块,也可以做有保障的同步。
实验结果,我们做了良好动态并行实现很快良性收敛,不然如果用随机并行就是不收敛或很慢的收敛,我们也有理论和实验证明,不光在均值,在方差上都有很好的收敛的保障。时间正好让我讲完了科学原理,我们也见到了结果,在不同算法上得到了很大的提升。我最后用几张图总结一下,现在大规模机器学习平台整个环境地貌,这是相当挑战但是相当让人激动的领域,有很多家在玩,我们是后来者。
现在在讲大数据大模型你要是没有几十个亿的参数就不用再谈的。看看最近达到了什么结果,你可以看到有人用一万台机器达到一百亿参数,做了话题模型的估计,你会看到其它的数据、神经网络或者对于话题模型都达到了类似的量级,大家的目标是,我的机器越来越多,把模型可以做得越来越大,这是一个趋势,有所投入有所收获。把大量机器协同起来跑一个分布程序,是很了不起的成果。但同时你也希望把效率进一步提高,这是我们汇报的结果,我们在最近做了话题模型和矩阵分解和卷机神经网络,看到他们的大小都已经超过了现在目前在文献里边所汇报最大的结果,但是所使用的机器比现在的机器少一个数量级。下面还有展示速度上的提升。
我们跟微软做了一个合作,他们用了24台比较高端的机器,实现了10的12次方参数的话题模型,有一百万个话题,每一个话题有一百万个词,这是目前所知道最大的话题模型,比非常有名的腾讯的那个peakcock还要大了大概10到50倍,但我们用的机器比他们少很多。
最后总结:对于平台或框架设计如果既考虑了操作系统原理,也考虑机器学习原理,你会得到很好的收获。Petuum是开源项目,基于目前的观察可以说,它不光可以达到很庞大的模型体积,基本上等价或优于现在最好的系统,而且在对机器集群大小和硬件指标的要求,我们极大的降低了要求。讲话前,刚刚收到学生最新从NIPS大会送来的结果,很让我们惊喜:还有一个组知道了我们的系统,用这个系统跟Spark和GraphLab做了独立比较,我很高兴看到我们的收敛曲线达到最低最快,我想用这个结果来结束我的讲座。最后大家可能会希望知道,到底Petuum系统到了什么程度,我们愿景既包含上层软件,底层软件,和生态界面的支持,成为目前在Hadoop生态系统一个分子,你们可以把它下载以后做自己的开发,也可以使用我们库中的软件。这个项目我最后要感谢我的同事和学生们在这两年里面的支持,也感谢各位的关注,谢谢!