cluster 2016-07-16
Google开源了新一代深度学习引擎TensorFlow。本文解释了一些TF里面我觉得可以从系统方面值得看的地方。
编程模型
TF目前的编程模型是符号编程 (symbolic computation)。大致的想法就是使用符号API去描述计算通过计算流图的方式,以及更新逻辑,然后通过像服务器去发送计算流图的方式来进行计算。原因是所有的计算全部需要通过计算流图来描述,也就是其实通PythonAPI编写的主要是Tensorflow这一门新的语言。然后通过session的run来进行一些交互。这样子做的主要好处是计算流图的执行可以进行比较多的优化,因为用户只是指定了数据关系,以及需要什么,计算的中间变量如何分配,是否需要保留,都是可以进行优化的。这一点是相比于Torch和numpy的库相对可以更多优化的地方。不过反过来说,和原有host语言的交互会相对比较有限一些,会比较难利用一些host语言(python)的特性来编写如条件和更新法则之类的东西。
作为一个工程师,从优化性能的角度,很容易倾向于用symbolic描述所有东西,然后做尽量多的优化。而作为researcher(Torch来自NYU),更容易倾向于灵活性,而选择过程计算风格的编程。
支持Mutation
和目前的符号语言比起来,TF最大的特点是强化了数据流图,引入了mutation的概念。这一点是TF和包括Theano在内的符号编程框架最大的不同。所谓mutation,就是可以在计算的过程更改一个变量的值,而这个变量在计算的过程中会被带入到下一轮迭代里面去。Mutation是机器学习优化算法几乎必须要引入的东西(虽然也可以通过immutablereplacement来代替,但是会有效率的问题)。 Theano的做法是引入了updatestatement来处理mutation。TF选择了纯符号计算的路线,并且直接把更新引入了数据流图中去。从目前的白皮书看还会支持条件和循环。这样就几乎让TF本身成为一门独立的语言。不过这一点会导致最后的API设计和使用需要特别小心,把mutation引入到数据流图中会带来一些新的问题,比如如何处理写与写之间的依赖。
细粒度操作优化
这一点是Google作为一个公司的资源带来的优势。TF大部分的操作是细粒度操作,可以来带比较大的灵活性,不过反过来,也在工程上面需要比较多的优化开销。一个更加偷懒的做法是直接支持常见的粗粒度操作,加上比较少的细粒度操作来做辅助,这样基本上可以减低优化带来的overhead,而对于大部分的问题也就可以比较轻松的应对了。caffe2和mxnet走了粗粒度操作加细粒度这条路也是基于同样的原因。这属于是在有限资源constraint下面做出的更加轻量级的选择。
分布式支持
TF目前并没有直接放出分布式的支持。从放出来的白皮书看,分布式的容错采取了consistent checkpointrestart策略,似乎没有更加fancy容错,但是又非常实用。可以看到google对于系统的选择还是非常现实的。同样的也可以反思现在的分布式系统,机器学习是不是真的需要像比如lineage这样的容错机制其实要打一个很大的问号。
Parameter Server已经过时了?
在TF白皮书里面提到的一点是PS因为系统的abstraction直接成为计算流图的一部分,相对弱化了PS作为一个系统的地位。这一点的主要原因是dependencytracking在计算流图里面得到的强化,而PS本身的一大功能就是完成dependencytracking。如果你仔细看mxnet本身的kvstore的实现,就会发现本地的参数整合代码几乎完全是利用依赖引擎完成的,这样的确可以大大简化PS的代码实现。不过PS本身作为一个abstraction,在通信和数据consistency上面还是可以提供一些不错的dataparallel 解决方案。未来的方向应该是各个系统更加融合,ps本身也作为一个依赖调度中的primitive直接整合入深度学习引擎,而不再作为一个宿主系统存在了。
目前系统的关系
TF在编程模型上面最相似的是Theano,基本涵盖了Theano所有的功能。在最近新的编程框架上面,比较相关的两个,一个是caffe2,另外一个是mxnet。
caffe2的设计风格基本和TF一致,走的是符号计算的路线,唯一的不同是支持粗粒度的操作,这一点在之前也有提到,是为了轻量级而做的选择。目前主要由yangqing一个人完成,可以认为是轻量级的TF。
mxnet的设计思路是符号计算和过程计算混合。在符号计算部分没有引入mutation,而是允许把符号计算融入到过程计算中,通过host语言来表述更新法则,同时动态调度过程计算的和符号计算的指令。这么做对于调度引擎需要更多的一些要求,并且也可能带来一些效率的影响(过程计算是动态执行的,有动态内存开销,更少一些优化),不过如果合理地把主要的瓶颈部分放到符号计算里面去,剩下的部分用更加灵活的过程计算来做,最终的效率影响不会特别大。
这两个系统在依赖调度和系统优化上面的思想应该和TF基本一致,有兴趣的同学可以对比学习一下。
选择什么
我本人参与了mxnet的设计,因此比较难公正地回答这个问题。不过有一点是肯定的,计算流图和优化的思想,以及依赖关系的调度,和计算优化会是下一代深度学习系统的主题。
一些个人的note
DMLC团队从五月份开始决定联合三个项目做mxnet,六月份设计完成,到九月份初步版本确立。我个人在参与设计mxnet之后七月到G brain实习,接触到了TF和内部的东西。个人的感觉,不同的项目设计是在不同的人力资源,目标(灵活度,效率)和taste的权衡下面做出不同优化的设计决定。mxnet,caffe2和TF的设计实现差别大概就在于此。没有对错,只看每个设计者的品味和想法了。因为这一点,让我确信我们做了正确的选择,并且决定继续九月份结束实习后帮助团队mxnet到目前相对完整的阶段。yangqing因为工作的缘故可能限制更多一些,不过也希往每个人也都有机会实现每心中理想的系统。