加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 湛江站长网 (https://www.0759zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

干货:如何从系统层面优化深度学习计算?

发布时间:2018-05-30 01:06:21 所属栏目:教程 来源:伍鸣
导读:副标题#e# 【资讯】编者按:在图像、语音识别、自然语言处理、强化学习等许多技术领域中,深度学习已经被证明是非常有效的,并且在某些问题上已经达到甚至超越了人类的水平。然而,深度学习对于计算能力有着很大的依赖,除了改变模型和算法,是否可以从系统

  1)Tensor是深度学习计算中最主要的数据结构,大量的计算开销都是花在对Tensor的处理上。Tensor是一种比较简单的数据结构,主要由meta-data和payload两部分组成。Payload就是基本元素的数组,而meta-data就是Tensor的shape信息,也就是维度和每一维的大小。这种简单的数据结构在传输的时候其实不太需要复杂的序列化和反序列化的功能。

  2)在相当多的情况下,Tensor是稠密的,并且其大小也是比较大的,也就是说在传输这样的Tensor的时候并不需要对其进行额外的批处理。

  3)深度学习的训练过程是迭代的。每个迭代处理一个mini-batch。在不同的迭代之间,数据流图和很多Tensor的shape信息并不发生改变,并且其中不少的shape信息是可以在运行时前就静态决定的。

  基于以上几个特点,我们可以对数据流图进行分析,找到那些可以静态决定shape信息的Tensor,以便在运行前,在接收端预先为其分配RDMA可访问的内存空间,并将其相应的可远程访问的地址传送给发送端。这样一来,在运行时,发送端可以通过单边的RDMA请求将Tensor的数据直接传输到接收端,从而完全避免了没有必要的额外内存拷贝,达到零拷贝的通信过程。我们将这种机制在TensorFlow上进行实验, 和基于TCP/IP的gRPC相比,这一方法在一系列典型模型上均取得了多倍的性能改进。甚至和针对RDMA优化过的gRPC相比,我们的方法仍然能够取得超过50%的性能提升。

  另外,我们在分布式深度学习方向上关注的另一个问题是如何自动地对资源无关的数据流图做优化的分布式执行,也就是自动划分数据流图中的计算任务并为其分配相应的计算资源,以使计算效率最优化。Google的Jeff Dean团队在这个方向上已经做了很好的先驱性工作。但局限于模型并行和单机多卡的运行环境,目前这仍然是一个非常重要并且大有可为的方向,需要结合数据并行,分布式及异构环境来综合考虑。

  提升单个计算单元的运算效率

  前面提到过,使用深度学习框架来实现的模型算法,在运行时前会被转换成数据流图。不少具有实际应用价值的模型都非常复杂,由它们所转换出来的数据流图通常是由成千上万的操作节点构成,其中包含了很多运算量非常小的节点,也就是说它们的输入矩阵的大小很小,或者是其计算逻辑的复杂度相对于对输入数据访问的复杂度来说很低。大量这样的操作节点会引入以下一些运行时开销,并且这样的开销会非常显著。

  1)深度学习系统运行时需要根据数据流图中节点的依赖关系来调度节点的执行。调度每个节点的系统开销和操作节点计算量的大小并没有直接关系,因此对于由许多小的操作节点构成的计算流图来说,系统调度所带来的额外开销就会相对比较大;

  2)对于在GPU上运行的计算来说,每个操作节点的实现都对应着一个GPU的内核函数,而这个内核函数的每一次执行需要CPU调用显卡驱动来启动,因此也带来了常数量级的额外开销。这个开销相对于计算量小的内核函数的执行来说是非常明显的;

  3)计算量小的操作节点往往难以挖掘出足够的数据并行性,因此不能充分利用处理器硬件中的计算资源。

  解决这一问题的主要思路是内核融合(Kernel Fusion)。一些手工的优化方法就运用了这一思想,比如NVIDIA基于CuDNN的RNN库函数。它把整个循环神经网络实现成一个GPU的内核函数,因此获得了非常好的性能。然而它的缺点也非常明显,那就是不够灵活和通用,无法应用在其它网络或一些变种的循环神经网络中。而我们更加关注的是如何在深度学习的系统中自动地对任意的网络模型实施优化。

  干货:如何从系统层面优化深度学习计算?

(编辑:PHP编程网 - 湛江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!