机器之心的读者可能比较熟悉具体的ML算法与常用的深度学习框架,但对于人工智能系统可能并不是很熟悉。正如周礼栋博士所言:"系统最关键的创新,就是把抽象实现的非常完美。用户其实"看不到"系统,大家看到的似乎都是如视觉等上层层面的突破,永远看不到底层的进步。所以我们一直说,系统的最高境界就是完全不可见的,是隐形的。"
这种"隐形的"系统可以帮助开发者与研究者自动搭建开发环境、建立算法内部逻辑以及优化模型的计算过程与硬件调度等,只有我们完全忽略了这些底层工作,系统才是完美的。由此可见,系统正如周礼栋博士所述"它的意思是把零乱的、复杂的东西变成非常有序的整体。中文翻译的"系统"也很好,不光是音译,还意味着把很多零散的东西联系在一起,成为一个统一的整体。"
其实微软亚研在系统研究上也有很多成果,例如能够在内存里面通过集群处理10亿张图的 GraM 分布式并行图处理引擎;每天能够调度几百万条任务,并用来支持搜索引擎、广告等部门的日常业务的Apollo大数据任务调度系统;还有未来将在微软云计算、人工智能系统里面广泛应用的KV-Direct Key/Value系统等。
这一次微软亚研向我们介绍的三个系统或工具都旨在帮助机器学习开发者更便捷地构建模型与应用。首先微软亚研介绍了深度学习框架后端优化如何加速分布式训练、提升计算单元效率以及降低内存限制等,其次论述了OpenPAI系统及异构集群环境如何更好地支持人工智能业务。最后薛卉研究员讨论了深度学习智能探索如何提供智能化、自动化的深度学习工具包,并帮助用户或者开发者自动地进行数据分析、模型搜索、参数调试和性能分析。后文主要关注于系统层面的DL优化,即优化数据流图映射到实际硬件的过程。
对于深度学习框架后端优化,读者可阅读微软亚研伍鸣和薛继龙的文章:
算力与系统优化
深度学习的计算力主要体现在样本数量、迭代数量与推断速度,它们把控制着模型的性能,同时也是最需要计算力的地方。由于深度模型的表征能力非常大,那么很可能模型的方差非常大,这在没有巨量样本的情况下也就造成了模型欠拟合。其次,更大规模和更复杂的神经网络模型已经被证明非常有效,并在产品中有广泛的使用。
此外,深度模型需要大量的迭代更新以搜索最优解。这主要也是因为参数空间巨大,因此它需要大量样本才能学习到正确的参数。最后,模型的线上推理具有更加极致的性能要求。线上的服务具有硬性的服务等级协议(SLA),所以在实际部署大型模型时,需要手工重新优化在深度学习框架(如TensorFlow)上已经训练好的模型,导致大量额外工程开销的产生。
这些都需要大量的优化以降低算力需求,其实任何方面的优化问题都可以从模型算法和系统两个角度来看待。一方面,我们可以通过设计更紧凑的模型或采用剪枝、量化和低秩近似等方法压缩模型所需的计算资源。这样的优化对特定的算法往往非常有效,但却不容易扩展应用到其它算法中。而另一方面,也就是微软亚洲研究院异构计算组正在进行的研究,则是在系统中实现模型算法无关的优化,这种优化通常可以为更多的应用带来计算优化。
对于系统层面的优化,它主要关注将模型计算图映射到对应的硬件资源。因为如今流行的深度学习系统(包括TensorFlow、PyTorch、CNTK、MxNet、Caffe等)大都采用分层的体系结构设计。在前端提供高级语言(例如Python)的接口抽象,允许用户方便地描述神经网络结构。描述好的模型在被系统运行前,首先会被转换成数据流图(Data-flow Graph)。在这个数据流图中,节点是特定的矩阵操作,而连接不同节点的边则是操作节点的输入和输出矩阵。然后,深度学习系统的后端将这个数据流图映射到实际硬件上进行高效地执行,而大部分系统层面的优化就是在这个阶段完成的。 优化这个深度学习计算的挑战主要在三个方面。第一个是扩展性,也就是如何通过增加计算资源,让计算能力线性增加。微软在这一方面主要考虑如何能够极致的发挥如RDMA、NVLink等的高速网络硬件的能力,以及如何能自动地做分布式的执行规划。
其次,微软的研究员关心局部计算,尤其GPU上的计算效率。最后,关注的问题是内存的使用效率,因为许多如GPU等硬件计算单元,它们的内存资源是非常稀缺的,这会限制模型的规模。
加速分布式深度学习训练
分布式训练的主要瓶颈在于多机之间的通信开销。如今计算机网络的硬件技术已经有了很大的发展,InfiniBand的RDMA网卡(Remote Direct Memory Access,这是一种硬件的网络技术,它使得计算机访问远程的内存时无需远程机器上CPU的干预)已经可以提供50~100Gbps的网络带宽和微秒级的传输延迟,目前许多以深度学习为目标应用的GPU机群都部署了这样的网络。那么针对深度学习的应用负载,如何才能更好地利用RDMA硬件的能力?
首先,我们来分析一下深度学习应用的几个特点:
- 张量(Tensor)是深度学习计算中最主要的数据结构,大量的计算开销都是花在对张量的处理上。张量是一种比较简单的数据结构,主要由meta-data和payload两部分组成。Payload就是基本元素的数组,而meta-data就是张量的shape信息。这种简单的数据结构在传输的时候其实不太需要复杂的序列化和反序列化的功能。
- 在相当多的情况下,张量都是密集的,并且其大小也是比较大的,也就是说在传输这样的Tensor的时候并不需要对其进行额外的批处理。
- 深度学习的训练过程是迭代的。在不同的迭代之间,数据流图和很多张量的shape信息并不发生改变,并且其中不少的shape信息是可以在运行时前就静态决定的。
基于以上几个特点,我们可以对数据流图进行分析,找到那些可以静态决定shape信息的张量,以便在接收端预先为其分配RDMA可访问的内存空间,并将其相应的可远程访问的地址传送给发送端。这样一来,在运行时,发送端可以通过单边的RDMA请求将Tensor的数据直接传输到接收端,从而完全避免了没有必要的额外内存拷贝,达到零拷贝的通信过程。
下面展示了利用RDMA优化分布式的深度学习训练。左图中,微软系统是数据流优化的这一层,实际的系统可以整合到TensorFlow里,微软设计了从CNN、RNN到全连接的很多种类型的神经网络结构。图中的红色是微软的数据,蓝色是原始的数据,可以看到,不同的应用类型下,微软可以取得两到八倍的加速。
右图显示了一个完整的应用。它是一个机器翻译的系统,输入数据来源于网上公开的一个翻译数据集,图中显示了其收敛的速度,可以看到微软的技术带来的两到三倍的加速。
提升计算单元运算效率 不少具有实际应用价值的模型都非常复杂,由它们所转换出来的数据流图通常是由成千上万的操作节点构成,其中包含了很多运算量非常小的节点,大量这样的操作节点会引入以下一些运行时开销,并且这样的开销会非常显著。
- 深度学习系统运行时需要根据数据流图中节点的依赖关系来调度节点的执行,因此对于由许多小的操作节点构成的计算流图来说,系统调度所带来的额外开销就会相对比较大;
- 对于在GPU上运行的计算来说,每个操作节点的实现都对应着一个GPU的内核函数,而这个内核函数的每一次执行需要CPU调用显卡驱动来启动,因此也带来了常数量级的额外开销。
- 计算量小的操作节点往往难以挖掘出足够的数据并行性,因此不能充分利用处理器硬件中的计算资源。
解决这一问题的主要思路是内核融合(Kernel Fusion)。一些手工的优化方法就运用了这一思想,比如NVIDIA基于CuDNN的RNN库函数。它把整个循环神经网络实现成一个GPU的内核函数,因此获得了非常好的性能。然而它的缺点也非常明显,那就是不够灵活和通用,无法应用在其它网络或一些变种的循环神经网络中。而微软更加关注的是如何在深度学习的系统中自动地对任意的网络模型实施优化。
以下是微软做内核融合带来的大幅性能提升的实验。这是一个标准循环神经网络LSTM模型的例子,这个模型中,微软通过自动内核融合的方式,可以把整个模型所有的算子融合成一个内核函数,从而基本消除了所有框架本身的额外开销。
右边是微软性能比较数据,最右的黄色柱是微软的结果,跟原始的TensorFlow比,有10倍的加速,中间是XLA,这是TensorFlow里面自己开发的编译优化系统,可以看到微软的优化比XLA的优化效果更好。
克服设备内存资源限制 设备内存的大小往往限制了可以处理的模型规模,解决这一问题的一个思路是对模型进行压缩和量化。如今学术界和工业界已经有大量的研究工作提出不同的压缩和量化的方法,然而,在实际的应用场景中使用压缩和量化仍然是个繁琐的迭代过程。
例如在量化这一常见的压缩算法中,我们只需储存 k 个聚类中心 c_j,而原权重矩阵只需要记录各自聚类中心的索引就行。在韩松 ICLR 2016 的最佳论文中,他用如下一张图非常形象地展示了量化的概念与过程。
如上所示权重矩阵的所有参数可以聚类为 4 个类别,不同的类别使用不同的颜色表示。上半部分的权重矩阵可以取聚类中心,并储存在 centroids 向量中,随后原来的权重矩阵只需要很少的空间储存对应的索引。下半部是韩松等研究者利用反向传播的梯度对当前 centroids 向量进行修正的过程。这种量化过程能大量降低内存的需求,因为我们不再需要储存 FP64 或 FP32 的数据,而只需要储存 INT8 或更少占位的数据。
显然,这样一个繁琐的过程需要一个好的工具来使之变得方便,这也是微软亚洲研究院系统组正在关注的一个问题。他们正在尝试扩展TensorFlow的API来使用户可以在模型脚本中直接控制量化和压缩的方法、对象、程度和过程。
除了这些基本概念与方法,微软亚洲研究院薛继龙研究员还展示了自动化优化框架的基本情况。对于LSTM模型,他在GPU和TensorFlow框架下迭代100步,并发现每一次迭代平均大概需要23毫秒左右。而开发者在增加代码"from tensorflow.contrib import wolong",并调用微软的自动优化系统后,系统会自动将该LSTM的1000多个小算子融合成了一个大的GPU的内核。而该LSTM在相同框架和硬件下每一次迭代平均达到了2毫秒左右,效率有了非常大的提升。 对于这一自动优化框架的GitHub开源情况,周礼栋博士表示:"我们再把它整理一下,看怎么把它变成一个开源的方式。有不同的方式可以包装这样一个库,我们也要考虑怎么打包使得它能够更容易使用,而且让更多人可以跟我们一起来贡献。" ]]> 原文: https://ift.tt/2tIzMH4 |
没有评论:
发表评论