Optimizing Memory Efficiency for Deep Convolutional Neural Networks on GPUs

Optimizing Memory Efficiency for Deep Convolutional Neural Networks on GPUs(基于gpu的深度卷积神经网络存储效率优化)

摘要:利用大数据集,深度卷积神经网络实现了最先进的识别精度。然而,由于大量的计算和内存操作,它们需要大量的执行时间。GPU的海量并行计算能力使其成为加速CNN的理想平台之一,并开发了大量基于GPU的CNN库(这里就是一些类似于加速GEMM运行的库等)。而现有的工作主要集中在CNNs的计算效率上,而CNNs的存储效率却在很大程度上被忽略了。即大家都是关于CNN的运行速度,但是没有在乎其的内存开销可能带来的性能损耗。然而,中枢神经系统具有复杂的数据结构,它们的记忆行为会对性能产生重大影响。在这项工作中,我们研究了不同CNN层的内存效率,并从数据布局(Layout)和内存访问模式两方面揭示了性能含义。实验表明,我们提出的优化在单层和各种网络上都具有普遍的效果,单层的优化效率高达27.9倍,整个网络的优化效率高达5.6倍。

Introdution: 首先是介绍了当前CNN的成功,甚至在一些任务上已经超于了人类的判别能力,本文在提出来的时候当时还是Alexnet等神经网络,其实这里是发表的时间比较晚。最近开发了一些基于GPU的加速CNN库。cuda-congett[15]是第一个在GPU上高度优化的CNN实现。之后,Torch [7]、antao[1]、Caffe [11]等一批流行的机器学习框架都发布了自己的CNNs GPU库。其中,Caffe是最流行的深度学习框架,在机器学习社区中得到了广泛的应用。GPU硬件厂商NVIDIA也开发了一个新的库cuDNN [4],它提供了在CNNs中使用的高度优化和可移植的GPU内核函数。当然也存在很多通过减少CNN算术计算难度来完成性能优化的,这些现有的工作主要集中在网络的计算效率,特别是卷积层的计算效率。然而,网络的存储效率在很大程度上被忽视了。由于深度神经网络具有复杂的数据结构,内存行为的性能影响并不简单。我们的研究揭示,有两个方面尚未得到解决,但对内存效率和CNN的整体性能造成了不小的影响。这些现有的工作主要集中在网络的计算效率,特别是卷积层的计算效率。然而,网络的存储效率在很大程度上被忽视了。由于深度神经网络具有复杂的数据结构,内存行为的性能影响并不简单。我们的研究揭示,有两个方面尚未得到解决,但对内存效率和CNN的整体性能造成了不小的影响。
    第一个是数据布局:由于GPU线程组织,即线程网格和线程块维度,高度依赖于数据布局。数据布局决定了内存访问模式,对性能有着至关重要的影响。对于CNN,数据是使用多维(4维)数组组织的。根据我们如何将数据放入不同的维度,我们有许多(24)种方法将数据存储在内存中。虽然之前的工作忽略了这一点,但令人惊讶的是,我们发现数据布局会显著影响性能和内存效率。图1显示了AlexNet上两种最流行的数据布局对不同卷积层和池层的性能比较。从图中,我们可以看到,通过选择适当的数据布局,可以保持高达6.9x的层级性能提升。此外,即使对于一直被认为是受计算限制的层,即卷积层,我们发现选择合适的数据布局可以导致高达2.3倍的性能提高。另一方面,由于每个维度都有不同的内存访问模式,并且每个维度的大小也会影响性能,因此数据布局对性能的影响是复杂的,开发人员很难推理。同时在CNN中不同的层之间的数据布局方法应该不同才行,卷积层和池化层中不同的数据布局产生了不小的性能差异,单个数据布局不能为所有层提供最佳性能,也就是说不能在所有的层中都使用单一的数据布局。然而,现有的库对所有CNN层仅采用一种数据布局。现有设计中这种单一的统一数据布局与CNN中使用的不同层的固有异构性不匹配。
    第二种是冗余片外存储器访问。我们的性能分析表明,内存限制的池化层和分类器(即softmax)层的内存效率远非最佳,因为它们忽略了片外内存数据访问。首先,CNN通常需要多个步骤来完成,并且这些步骤之间存在顺序的数据依赖性。通常的做法是每一步都使用一个内核。然而,当数据通过带宽受限的片外存储器时,内核间数据通信的成本很高。其次,利用数据局部性获得高内存性能是一项重要的优化。然而,如何为不同的数据布局优化局部性在现有的CNN库中还没有得到解决。
  文章的主要贡献包括以下几部分:

  1. 首先,我们描述了CNN各层中的数据布局,并揭示了不同布局的性能影响。然后我们导出一个轻量级的启发式规则,以最小的分析开销来指导数据布局的选择
  2. 我们通过在图形处理器上提出快速多维数据布局转换来支持一个具有多个数据布局的网络。我们将对自动数据布局选择和转换的支持集成到一个流行的深度学习框架Caffe中。
  3. 我们研究了内存缓冲池和softmax层的内存行为,优化了它们在GPU上的内存访问效率。
  4. 我们对不同类型的层和代表性网络进行严格的评估和结果分析,并展示了单层和完整网络的高性能改进

背景
在这一节中,我们首先介绍了一个CNN的结构,并总结了CNN中主要类型的层的算法特点。然后我们描述了我们研究中使用的GPU加速CNN库。CNN的工作原理如下:CNN的工作原理是从高分辨率特征地图中提取局部特征,并将其组合成更抽象的低分辨率特征地图。这些是通过两种交替的层实现的:卷积层和池层。最后几层是完全连接的分类器,将所有局部特征组合在一起,产生抽象的分类结果。
CNN简单结构
卷进层的计算直接卷积
卷积层:如上图所示:其可以理解为卷积层的直接卷积的计算公式,其中n(图像数量)、C(特征图数量)、H(图像高度)和W(图像宽度)。有了这个符号,我们可以看到等式1使用了NCHW布局。在NCHW数据布局中,沿着最低维度W的元素被连续存储在存储器中。相比之下,沿H维的连续元素的步幅为W;沿C维的连续元素的步距为H * W;诸如此类。
  很显然很多的研究都是基于卷积层是一种非常耗时的计算来进行计算复杂度的优化,如FFT、img2col等基于现有的GEMM的技术进行计算加速。文中觉得与直觉相反,我们观察到卷积层不一定是唯一的计算界限。具体来说,对于具有小的C和N维的卷积层,性能实际上是类似于2D卷积的存储器限制(例如,图3中的conv9)。此外,即使对于计算受限的层,它们的内存组织(尤其是数据布局)也会对它们的内存性能和整体性能产生重大影响。
池化层:对于池化层来说有平均池化和最大池化两种类别,其中池化的性能主要是受限制于内存的带宽等,因为池化层本身涉及的计算量不是很庞大。
池化层
全连接层:几乎任何的神经网络都具有全连接层,全连接层的实现也很简单,一些基于剪枝的思想对于参数减少的操作可以在一定程度上实现防止过拟合,但是本文主要讨论的是对应的计算。本文例举的是使用softmax的方法完成分类的。[softmax]比较简单太容易理解!(https://blog.csdn.net/bitcarmanlee/article/details/82320853)
文章接下来说出一些现有的库在优化CNN运算的实现:到目前为止,已经为CNN研究开发了许多框架。其中,Caffe、cuda-convnet 和cuDNN的应用最为广泛,专门针对GPU加速进行了优化。在本文中,我们研究了它们对于不同类型的层的存储效率。Caffe和cuDNN对所有层使用NCHW数据布局。使用这种数据布局有两种卷积实现。一种是用**矩阵乘法(MM)**计算卷积。这是默认方法,因为它可以用于不同配置的卷积层。另一种是基于FFT的,在最近的著作中已经提出并细化,并集成到cuDNN第4版中。由于一些限制,快速傅立叶变换方法对中间数据有很大的开销,并且适用于某些类型的卷积层[23]。与Caffe和cuDNN不同,cuda-convnet选择CHWN数据布局,使用直接卷积法。对于每个库,我们都使用它们最新的、性能最好的版本,cuda-convnet2和cuDNNv4。
实验方法和条件

CNN图像识别中最流行的三种数据集分别是MNIST、CIFAR、IMAGNET三种,在对应的官网上都可以找到对应的数据集的下载。深层CNNs的流行数据集是MNIST [18]、CIFAR [14]和ImageNet [21]。MNIST数据集用于手写字符识别。它在训练集中包含50,000个手写数字图像,在测试数据集中包含10,000个例子,LeNet [17]是MNIST研究得最好的网络。CIFAR10包含10种不同类别的对象,如猫、卡车、飞机等。,每个类别有5000个训练图像和1000个测试图像。我们将cuda-convnet中包含的Cifar网络示例用于CIFAR10。ImageNet是一个大规模的图像集合,有100多万幅真实世界的图像,分为1000多个类别。常用的基准网络包括AlexNet [12],ZFNet [25]和VGG [22]。AlexNet被广泛用作探索各种新网络的基线网络。这五个网络涵盖了范围广泛的问题大小(从28到256个图像大小)和网络大小。表1显示了从五个网络中选择的不同类型的基准测试层的配置。
第四部分:在本节中,我们首先描述了不同类型CNN图层中数据布局的性能影响,并推导出基于图层的大小和类型选择合适数据布局的启发式方法。然后,我们开发了一种快速的多维数据布局转换,以支持一个网络中的不同数据布局。最后,我们展示了如何将灵活的数据布局支持应用到流行的库/框架中。因为本身CNN中的卷积的操作应该是有不同的实现方法的,所有对于不同的实现方法应该分开分析各自的性能的影响。
通用实现上:也就是使用MM的方法实现的矩阵计算,对于卷积层,我们从表1中总结了它们的共同特性。首先,批量大小N通常是16的倍数,选择有限。因此,使用N作为最低维度是一个很好的选择,可以满足合并内存访问的要求,因为线程是相应地组织的。鉴于其有限的选择,例如32、64和128,该维度的优化空间是有限的。第二,尽管每个图像的宽度和高度通常是相同的,但是对于不同的卷积层,这些值可以有很大的不同,从12到224。第三,在第一卷积层中,输入特征映射的深度(Ci)对于灰度图像是1,对于RGB图像是3,然后在其余卷积层中是16的倍数,这也可以为GPU线程的扭曲(扭曲大小=32)提供规则的存储器访问。基于以上在每个维度上讨论的属性,将W和H维度相结合,并且使用维度N作为最低维度是合理的选择。这样,我们就有了两种候选数据布局:CHWN或HWCN。cuda-convnet中使用CHWN布局,每个卷积滤波器应用于H和W维,以生成一个输出特征图。对HWCN布局的测试显示了与cuda-convnet上的CHWN布局相同的性能,因为它没有改变N维的内存合并功能,并且在其余维上保留了相同的数据重用。一种流行的卷积实现是将4D矩阵映射到2D阵列,并以矩阵乘法的形式执行计算。在这种情况下,使用NCHW1数据布局,这是Caffe和cuDNN中使用的策略,因为矩阵乘法是一种调整良好的代数原语,几乎可以在任何输入大小的平台上使用。cuDNN中特殊的快速傅立叶变换实现也继承了NCHW布局,我们将在本节稍后分析其独特的效果。这里我们用cuDNN来表示它的默认MM方法。由于Caffe在其实现中也将cuDNN绑定为改进版本,我们主要比较CHWN (cuda-convnet)和NCHW (cuDNN)数据布局。在我们下面的分析中,在cuDNN总是比Caffe好的图中,我们省略了Caffe的结果。

  图3示出了卷积层中两种不同数据布局之间的性能比较。如上所述,不同的数据布局也会影响卷积层的实现。每个数据布局的性能都是使用它们的最佳性能实现来评估的[4][15]。我们可以做如下观察。首先,如图3所示,cuda-convnet在CONV1 ~ CONV5和CONV9层的性能优于cudn(加速高达6.5倍),但在其余六个卷积层的性能更差。这两组层的区别在于N和C维。在cuda-convnet性能更好的六个层中,CONV1、CONV3、CONV5和CONV9是它们对应的CNNs中的第一层,这些层的C值要么是3,要么是1。CONV2和CONV4层的C值也相对较小,不大于64。对于使用cuDNN性能更好的其余层,N的值是64或32。为了进一步确定每个维度上数据布局的敏感性,我们收集了一个可变维度大小(N或C)和其他三个固定维度大小的结果。
在这里插入图片描述与cuda-convnet相比,cuDNN和Caffe使用NCHW布局,并利用cuBLAS [27]库(或内部例程)进行矩阵运算。由于矩阵乘法只有两个维度,需要一个矩阵展开步骤(沿着H和W)来扩展输入矩阵,并将多个维度合并为两个维度[11]。当矩阵大小有限时,这种矩阵变换开销更加明显。结果,如图4b所示,当C的值小于32时,cuda-convnet(即CHWN布局)表现得更好,因为它没有矩阵扩展的开销。另一方面,当C大于32时,cuDNN的性能更好,其中矩阵扩展由于维度合并而导致更好的数据重用和更高的并行性[4]。

总结:这项工作研究了当前GPU加速的深度CNN实现的内存效率问题,包括数据布局和片外内存访问。我们的详细研究揭示了数据布局对不同类型CNN层的影响及其性能影响。然后,我们提出高效的数据布局支持作为我们的解决方案。我们进一步研究了内存限制层的内存访问模式,并提出了有效的优化措施,以大幅减少片外内存请求和内核间通信。实验证明了我们的内存优化的有效性及其对不同类型的层和各种完整网络的普遍影响。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值