当模型被并行的时候,它中间实际是相关的,所以你不在过程中进行协调,最后结果就会出错,所以这种情况下你会发现,你对数据并行对模型并行做不同的通讯和系统设计,还有其它一些东西我就不多讨论。
我做一个总结,机器学习算法有它的独特性,基于优化的算法,而且用(递归)来实现,有一些容错的能力有一些动态结构,然后它还有一些非同质的,有一些参数会回归很快,有些收敛很快,你对收敛快做完停下来把资源另外使用,这都是要求编程员或者程序对机器学习算法有一定的了解,这样有一定的机会来进行加速。而这种东西在传统程序里面不存在,通常对于指令级的一个正确,造成这样很多技术上更多难的学习,但在机器学习不见得很有必要。
看看已知的系统怎样解决这个挑战,大家都知道Spark是Hadoop新的版本,后面迭代非常好。RDD保持一个过程数,所以在运算中如果出现问题很快找出问题所在,这都是RDD和Spark非常优异的特点,特别在数据库的处理或者非迭代的数据处理里面是非常有效的。
做模型并行要求全局性的一个协调,这样就会产生一些很大的代价。Graphlab,用图上的边表示学习的重要性,你写成一个节点程序自动做一个非同步的通讯, 仍然保持这个程序最后能够正确收敛。这也是一个很好的思路,在很多情况下都产生了比较好的结果,甚至比Spark还要好,它也有一些问题,数据量变得非常大,数据量变得非常沉重,效率不是很高。
我们组正在开发这么一个平台,叫Petuum包含数据和程序并行两套功能,也对机器学习的特点做了比较好的一个研究,对他们做了一些针对性的使用,所以我们系统对机器学习内部特点有比较针对性,他们有一些非常有意思的特性和功能,这块我可以总结一下。
大致结构是这样,包含一个参数服务器,大家都知道参数服务器,给你提供很好编程的一个虚拟并行内存,大家在编程的时候不用对每个机器进行单独通讯,我们还有一个叫做调度器,它是能够对模型进行有效的分割,甚至是动态分割,然后做一个分布化。运行原理就跟机器学习的工程师写机器学习的算法基本一个思路,用迭代加上对公式的,跟传统的是不一样的。
这个参数服务器有这样一个编程界面,你在写内存读取不需要对每一个机器做一个特殊的指令,使用了比较巧妙的所谓半同步的协调机制,这样可以显著降低使用在通讯上的时间,而加强在计算上的时间,所以你可以看到随着我们半同步参数的调整,我们这个通讯时间会显著下降,降到了以至于比计算时间还要少,这样使计算机的资源得到最大量的利用。
在调度器方面我们也爱基于机器学习考量的设计,调度机自动发现机器学习模型里面的一些特点,找出哪些参数是相关,哪些参数是不相关,然后对它们做相应分布,他们在分布运行的时候并不违反正确性、约束性,这样也会造成更快的收敛。
为什么这样做产生这样好的结果?这里边有一些比较深层的技术和科学原理,时间允许,我可以再讲几分钟。并行系统是没有理想的,我们当有好几台机器,显然不能希望它同步运算同步通讯,即使不同的机器放在机房里面温度不一样,行为都是不一样的,最后结果就是我们看到这样的情形。我们怎么来协调这样的一个缺陷呢?通常对编程高手,当然这不是问题,他可以对每一台机器做深层操作,可以避开所有的陷阱,对于普通程序员和低端用户对非常昂贵儿童耗时开发过程并不见得能负担得起,我们需要还是非常简单的界面,让界面本身做了通讯上的决定,这个决定在数据并行过程中可以被总结成一个所谓的叫做协调或者是同步协议。这个同步协议我们大家都知道,这一端Spark或者Hadoop协议完全协议,然后往下走,这个东西在数学上证明是有对的,但是造成有效性的损失。