分享

分布式深度学习平台DistBelief和TensorFlow

 虎牙变大猫 2018-07-08

深度学习框架处理能力的提升主要依靠纵向扩展(scale up)和横向扩展(scale out)。前者主要通过提高单台机器的处理能力来扩展,后者主要用分布式集群提高处理能力来扩展。Google公司作为分布式深度学习平台的领头羊,已经分别研发了该公司的第一代深度学习平台DistBelief和第二代分布式深度平台TensorFlow。这两个平台是横向扩展的经典案例,下面逐一介绍。

一、DistBelief

Google 将自家研发的深度学习系统命名为 DistBelief,它使得 Google 能够同时处理成千上万台大型计算机的数据,构建更大型的神经网络和大规模训练。Google 的搜索、图像识别及邮箱等均采用了该技术。一般情况下,深度学习系统都需要先设定好 feature(特征),再学习如何分辨。但 Google DistBelief 神奇的地方在于,“Google Brain” 开发团队 “XLab” 曾用它在未事先获取 “猫的特征描述” 信息的情况下,从大量 YouTube 视频中区分除了哪些是猫的视频。这意味着深度学习系统 “DistBelief” 自行总结出了猫的 feature(特征)!虽然这个案例的识别范围、识别率有待提高(81.7%),但作为人工智能最经典案例之一,为人工智能翻开了新的篇章。而 “猫” 的事件,也让曾经的 Google Brain 开发团队 “XLab” 的核心人员、现在被李彦宏挖到百度的吴恩达得到了 “Google Brain” 之父的美誉。不过,时代总是进步,而 “DistBelief” 有缺陷。

深度学习和非监督特征学习在很多实践领域表现出极大的前景。但是,我们可以观察到深度学习的规模在不断增加,这是因为训练样本的数量和模型参数的数量可以显著提高分类精度。

1.1模型并行化

为了促进大型深度网路的训练,Google Brain团队提出了软件框架DistBelief。该框架支持神经网络的分布式计算和层次化的图模型。用户定义在模型每一层每一个节点发生的计算和前先后向传播的消息传递。对于大型模型,用户也许会把模型设计成分布到几个机器执行的计算模型(如图1所示)。在训练阶段和推断阶段,这个框架自动使用可用的核来自动并行化计算,和管理通信、同步化,和机器之间的数据转移。

把一个深度网络分布到多个机器的性能提升主要依赖于连接结构和模型的计算需求。如果一个模型拥有很多参数或者很高的计算需求,那么这个模型将从访问更多的CPU和内存,主要瓶颈就是网络通信了。他们已经成功把DistBlief框架分布到144个节点,这个框架的性能得到显著提升,而且他们发现当分不到8或者16个节点的时候,可以得到最大的速度提升。显然,有局部连接的模型比全连接结构的模型更适合扩展到分布式体系,因为它们的通信需求更低。分布式的性能提升比理论值要差的主要原因是,对于某个任务执行阶段,所有机器需要等待速度最慢的那台机器完成该阶段的计算任务才可以执行下一个阶段的任务

图1:DistBelief的划分

1.2 DistBelief的分布式优化算法

DistBelief可以利用一个数以百计个机器的计算集群来训练大型深度网络模型。为了在规定的时间内训练一个大型网络模型,需要的计算并行化不仅局限于单个机器内部的并行化,而且需要实现节点之间的并行化。因此,他们利用一组模型副本(model replica)来实现节点之间的并行化。

在这个框架,他们研发了两个算法:Downpour SGD和Sandblaster。两种方法都用到一个集中式分片的参数服务器概念,模型副本使用参数服务器来共享他们的参数。

(1)Downpour SGD,随机梯度下降是训练深度神经网络的最常用的优化程序。不幸的是,SGD的传统计算需要一种固定的顺序(inherently sequential),使得它难以应用到大规模的数据集合为了把SGD应用到大规模的数据集合,他们提出了一个异步随机梯度下降的变形,名字为Downpower SGD,其基本原理就是使用一个DistBelief模型的多个副本。

(2)Sandblaster L-BFGS。在小型的深度网络中,一些批量处理方法效果非常好。为了把这些方法应用到大型模型或者大型数据库,他们设计了一种块优化框架Sandblaster。Sandblaster的一个核心想法就是分布式参数存储和调配。优化算法的核心优化算法定格在一个协调处理(如图2所示),这个协调处理没有直接访问模型的参数。因此,它在运行大规模模型(模型参数的个数数以亿记)过程中不会大量地发送参数和梯度到一个单独的集中式服务器。


图2:左边为Downpour SGD,右边为Sandblaster L-BFGS


1.3DistBelief的问题

DistBelief使用了参数服务器(parameter server)体系结构,这个成为该体系结构的瓶颈。在这个参数服务器体系,一个任务包含两个进程:无状态的工作进程和有状态的参数服务器进程。前者在训练模型的时候执行大量的计算,后者处理维护模型参数的当前版本DistBelief的编程模型类似于Caffe的模型,用户把一个神经网络定义为层次的一个有向非循环图,然后以一个损失函数终止。

尽管DistBelief给很多机器学习研究项目奠定了基础,但是,“Google Brain”团队发现它的局限性越来越大。DistBelief中用于搭建预定义层的基于Python的脚本接口可以满足用户的简单需求,但是更多的高级用户需要更高级的弹性。更高级的弹性包括以下3点:(a)定义新的层次。为了提高效率,DistBelief的架构是使用C++语言实现的。对于那些需要使用新层次体系(例如:softmax classifiers和attention modules)做实验的机器学习研究者,这个不熟悉的编程语言将成为他们在定义新层次体系的主要障碍。(b)提炼训练算法。很多神经网络都是使用梯度下降法进行训练,通过在不断降低损失函数的方向移动来训练参数,然而一些对SGC的提炼是通过修改更新规则来加速收敛。研究者通常希望使用新的优化方法来做实验,但是在DistBelief上做这些实验会涉及到修改参数服务器的实现。(c)定义新的训练算法。DistBelief的每个节点都遵循一个固定的执行顺序:读一批输入数据和当前参数,计算损失函数(一个前向传播),计算每层每个参数的梯度(一个反向传播),最后把梯度写会到一个参数服务器。这个模式对于简单的反馈神经网路有效,但是对于高级模型就失效了,例如循环神经网络,对抗式神经网络、增强学习模型。除此之外,更多其他的普通的机器学习模型也无法适应这样的框架,例如:期望值最大化,决策森林训练,和潜在狄利克雷分布。


二、TensorFlow

Google 称,虽然 DistBelief 非常成功,但它仅仅以神经网络为目的、十分局限,而且很难进行配置。另外,DistBelief 牢牢绑定在 Google 的内部基础设施上,几乎不可能将代码与外界共享。因此,Google 的第二代深度学习系统 “TensorFlow” 横空出世了。

Google 表示,在设计上尤其针对克服 DistBelief 的短板,灵活、更通用、易使用、更快,而且完全开源。TensorFlow 可以被架设在智能手机这样小的设备上,甚至仅一块电路板上,更灵活; TensorFlow 可以被使用在很多计算平台,无论是智能手机还是大型计算机、单个 CPU / GPU 计算机还是成百上千 GPU 卡组成的分布式系统,ARM 的还是 X86 的构架,更通用;TensorFlow 支持多种编程语言,提供了很多深度学习模型库,易使用;在很多指标上,TensorFlow 要比 DistBelief 要快一倍,更快。但是,学术界和工程界的一些朋友并不喜欢这个 “刚刚闯入” 开源界的 “小伙子”,判了它 “意义不大” 的死刑。“TensorFlow” 之所以 “开源” 却不讨好,是因为 TensorFlow 不是第一个被开源的深度学习系统,并且目前只开源了 “单机版”,而非能够识别猫的 “分布式版本”。除了并非第一以及只开源了单机版代码这两点外,Google 开源 TensorFlow 这件事最被人诟病的地方在于,在 “用事实”、“用数据” 说话的学术界、工程界,Google 并未用 “数据对比” 证明 TensorFlow 的 “灵活、更通用、易使用”。

2.1 TensorFlow的三大设计原则

(1)原始算子的数据流图。TensorFlow和DistBelief都为他们的模型设计了一个数据流表示,他们的主要区别在于,DistBelief由一些相对简单的层组成,而TensorFlow的数据流图中的每个顶点都是一个独立的数学算子(例如举证乘积、卷积等等)。这个方法让用户更容易地使用一个高级脚本接口来组装新的层次。

(2)延迟执行。一个典型的TensorFlow应用都可以分为两个阶段:第一阶段负责把程序(一个即将被训练的神经网络和更新规则)定义为数据流图;第二个阶段在一组可用的设备执行一个程序的优化版本。通过把执行延迟到整个程序可用,TensorFlow可以通过计算的全局信息来优化执行。例如,TensorFlow利用图的依赖结构在不用等待中间结果的情况下发送一系列的内核到GPU,从而提高GPU的利用率。尽管这种设计让执行过程更高效,但是我们不得不把更复杂的特征(例如动态控制流)融合到数据流图。

(3)异质加速器的通用提取。除了像CPU和GPU这样的通用设备,一些用于深度学习的专用加速器能获取显著的性能和能效提升。在Google,一些研究员已经为机器学习搭建了张量处理单元(英文全称:Tensor Processing Unit,简称:TPU)。与其他最先进的技术相比,TPU在能效方面获得一个数量级的提升。为了在TensorFlow里面支持这些加速器,他们为设备定了一个通用提取。该设备实现的方法至少需要:(1)用于执行任务的内核;(2)为输入和输出分配内存空间;(3)缓存可以转移到客户端内存,或者从客户端转移过来。对于不同的设备,每个操作(例如矩阵乘法)都能有专门的实现。因此,相同的程序可以让GPU、TPU、CPU这些各式各样的设备满足训练和离线推断的需求。

2.2 TensorFlow的执行模型

如图3所示,TensorFlow使用一个数据流图表示一个机器学习算法涉及到的所有计算和状态,包括:数学算子,参数和它们的更新规则,输入数据的预处理。能更清晰地表达了各个子计算模块的通信的数据流图更容易把计算划分到多个设备。

图3:数据流图

如图4所示,数据流图(dataflow graph)用“结点”(vertex)和“线”(edges)的有向图来描述数学计算。“节点” 一般用来表示施加的数学操作,但也可以表示数据输入(feed in)的起点/输出(push out)的终点,或者是读取/写入持久变量(persistent variable)的终点。“线”表示“节点”之间的输入/输出关系。这些数据“线”可以输运“size可动态调整”的多维数据数组,即“张量”(tensor)。张量从图中流过的直观图像是这个工具取名为“Tensorflow”的原因。一旦输入端的所有张量准备好,节点将被分配到各种计算设备完成异步并行地执行运算。

图4:TensorFlow的数据流图

在一个TensorFlow图中,每个顶点(vertex)表示一个局部计算单元,每条线(edge)表示输入和输出。顶点的计算被称为运算(operations),线运输的数值被称为张量(tensor)。数据流图的主要元素包括:(a)张量(tensor),在TensorFlow中,所有的数据都被建模为张量(n维数组),张量的每个元素可以是原始数据类型(如int32,float32,string)的其中一种。张量在很多机器学习算法中表示数学运算的输入和输出,例如:两个二维张量的矩阵乘积生成一个二维张量,一批二维卷积takes一个四维张量生成另外一个四维张量。(b)运算(operations),一个运算用m个张量作为输入和n个张量作为输出。(c)有状态的运算:变量。这种运算包含一些易变状态(每次读写都需要更新状态)。(d)有状态的运算:查询。TensorFlow包含一些能支持更高级形式协调工作的查询功能。

【1】http://mp.weixin.qq.com/s/1iWS9SUqFnvJZkVS-BD7gQ

【2】Large Scale Distributed Deep Networks

【3】https://zhidao.baidu.com/question/1433109429124904939.html

【4】http://blog.csdn.net/itplus/article/details/31831661

【5】http://www./articles/EviQ32m

【6】http://www./

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多