基于现场可编程门阵列的卷积神经网络加速系统的制作方法

文档序号:15689226发布日期:2018-10-16 21:42阅读:172来源:国知局
本发明涉及一种算法的硬件加速平台,具体涉及一种通用性好和灵活性高的基于现场可编程门阵列的卷积神经网络加速系统及其设计方法。
背景技术
:卷积神经网络(cnn)隶属于人工神经网络,是一种前馈的深度神经网络,已经得到了广泛的应用,如字符识别,图片分类和自然语言理解。由于卷积神经网络的特定计算方法,因此在通用处理器(cpu)上效率并不高,并且很难达到很高的性能。在实践中,图形处理器(gpu)被广泛应用于卷积神经网络的训练和分类任务中,然而,它受限于较低的能效收益。除了gpu被应用于卷积神经网络加速以外,基于专用集成电路(asci)和现场可编程门阵列(fpga)的卷积神经网络加速器也被提出。综合比较这些平台(cpu,gpu,asic和fpga),基于fpga的加速器因为具有可重构性高,开发周期短和高能效等优点,越来越受欢迎。但是,使用fpga来加速卷积神经网络仍然存在很多挑战。众所周知,fpga平台主要受限于有限的计算资源和昂贵的片外内存访问。然而,在最先进的卷积神经网络模型中,存在大量的计算操作(>1g)和大量的参数(>50m),这将需要消耗大量的能量。并且,卷积层参数的高可变特性也损害了硬件资源的充分利用。随着技术的发展,为了达到更高的精度,卷积神经网络模型会变得越来越大,越来越复杂,这将加剧这种情况。因此,需要设计一个高能效的cnn加速器。在使用cnn模型进行推断之前,需要对cnn模型进行训练。对cnn的训练一般都采用离线的方式将模型预先训练好,然后利用训练好的模型做实时的推断处理。由于推断过程对实时性要求很高,因此,加速cnn的推断过程比训练过程有更为现实的意义和价值。卷积神经网络推断过程的高性能低功耗实现一直是近年来的研究热点,受到了学术界和工业界的广泛关注。目前用于硬件加速的平台有通用图形处理器(gpu)、专用集成电路(asic)和现场可编程逻辑门阵列(fpga)。其中,gpu是由很多的并行计算单元所构成,在gpu内部一般都是通过采用simd的方式对应用进行加速,因此,gpu特别适合加速计算密集型的应用。目前,有cuda、glsl和opengl等成熟的编程框架可用于gpu平台,使得gpu平台的开发门槛相对较低,gpu平台已经成为使用广泛的加速平台。但是,gpu平台仅适用于执行数据级并行的任务,对于深度神经网络计算中不能进行数据级并行的部分任务,加速效果不太明显。asic是专用集成电路,因此只对特定的应用具有很好的加速效果。但是asic的灵活性很低,只要应用需求发生微小的改动都需要重新来设计整个的硬件电路。并且,asic的开发需要具备很好的硬件知识和经验,因此门槛很高,并且asic的开发周期也很长,导致开发的成本也很大。fpga芯片内部包含有许多的可编程逻辑模块,它们都可以根据不同的应用场景要求进行重新配置,因此可以提供充分的灵活性。虽然与asic加速效果相比,fpga的稍差,但是随着fpga技术的不断发展和创新,fpga芯片的集成度越来越高,芯片的速度也越来越快,并且,fpga芯片与通用处理器之间的通信也变得越来越简单。更为重要的是,基于fpga的开发工具链也越来越多,这大大的降低了fpga的开发门槛。目前,较为成熟的fpga开发工具链有xilinx公司的vivado和altera公司的基于opencl开发的fpgasdk,它们都能够帮助开发人员从事针对fpga芯片的编程工作。综合以上硬件加速平台的特点可知,fpga是介于asic的效率和通用处理器的可编程性之间的具有吸引力的选择,因此,本发明使用fpga作为卷积神经网络的加速平台。技术实现要素:针对上述存在的技术问题以及最新的技术进展,本发明目的是:提供了一个基于fpga的卷积神经网络加速系统,该加速系统能够实现高性能、低功耗的特点。本发明的技术方案是:一种基于现场可编程门阵列的卷积神经网络加速系统,包括:通用处理器,与现场可编程门阵列进行通信;存储模块,用于通用处理器与现场可编程门阵列的数据交互;现场可编程门阵列,用于加速卷积神经网络的计算过程;还包括统一的编程接口,供用户调用所述加速系统完成相应的任务;整个加速系统的执行过程分为以下几步:s1:通用处理器端通过提供的编程接口选择合适的加速器,并把计算过程中需要使用的输入数据和权值数据写入存储器中;s2:现场可编程门阵列中的加速器从存储器中读取输入数据和权值数据并开始计算,并把最后的计算结果写入存储器中;s3:通用处理器从存储器中读取计算完成以后的结果输出到屏幕。优选的,所述现场可编程门阵列中,包括多个处理引擎(pe),每一个处理引擎都使用了一种分片展开策略来与卷积神经网络中一层的计算对应;所有的处理引擎都映射到同一个fpga芯片上,这样不同的层能够以流水线的方式同时工作。优选的,所述处理引擎包括卷积层处理引擎、池化层处理引擎和全连接层处理引擎。优选的,所述卷积层处理引擎,在卷积层的计算中,使用了循环分片和循环展开,所述循环分片是将较大的循环空间划分成为几个较小的循环空间,循环展开是把循环内的程序段重复多次完成,在没有数据依赖的循环体中能够实现并行计算。优选的,所述卷积层处理引擎中,使用了双缓冲机制来预取下一次执行计算所需要的数据;卷积层处理引擎的执行过程分为以下几步:s01:将输入数据读取到处理引擎的输入缓冲区中,将权值数据读取到处理引擎的权值缓冲区中;s02:处理引擎执行并行的乘法计算,并行的乘法计算后跟着一个加法树的结构完成累加计算;s03:将完成累加计算后的结果写入处理引擎的输出缓冲区中,如果当前层不是卷积神经网络中的最后一层,那么该层的结果将传入下一层,作为下一层的输入;如果当前层是卷积神经网络中的最后一层,则将直接输出。优选的,所述全连接层处理引擎,在全连接层的计算中,使用了循环分片和循环展开,也使用了双缓冲机制来预取下一次执行计算所需要的数据。优选的,所述全连接层处理引擎还使用了剪枝的方法,经过剪枝以后,权值矩阵变得稀疏,全连接层处理引擎还使用了压缩稀疏列的压缩存储技术来存储权值矩阵,经过压缩存储以后,得到wt[]、index[]和offset[]3个向量,它们分别存储着非0元素的值、相应的行索引以及列偏移;全连接层处理引擎的执行过程分为以下几步:s001:将输入数据读取到处理引擎的输入缓冲区中,将经过压缩存储后的wt[]、index[]和offset[]3个向量读取到处理引擎的权值缓冲区中;s002:处理引擎读取index[],用来获得非0权值wt[];s003:处理引擎根据index[]缓冲区的值到输入缓冲区的对应位置取得相应的元素;s004:权值wt[]与输入缓冲区中的相应数据做并行计算;s005:将完成累加计算后的结果写入处理引擎的输出缓冲区中。优选的,所述池化层处理引擎的计算过程和卷积层处理引擎的计算过程重叠在一起。优选的,为了最大化流水线结构的吞吐率,根据每一层的计算量来给它分配相应的计算资源,尽量每一层的的计算时间大致相等。优选的,在确定单个卷积层对应的循环分片因子时,采用的是设计空间搜索,目标是最大化fpga资源利用率。优选的,所述编程接口,包括硬件平台初始化类的函数和数据传输类的函数。与现有技术相比,本发明的优点是:本发明简单易用,对用户透明。本发明中,对卷积神经网络中的每一层都有相应的处理引擎与其对应,并且所有的处理引擎都映射到同一个fpga芯片上,这样不同的层能够以流水线的方式同时工作。并且,本发明中的每个卷积层都使用最合适的分片展开策略,这能够提高硬件资源利用率。综上,本发明提供了一中高性能、低功耗的卷积神经网络解决方案。本发明相对于已有的卷积神经网络加速系统能够取得更高的能效收益。附图说明图1是本发明实施例的加速系统整体结构图;图2是本发明实施例的卷积层处理引擎和全连接层处理引擎的电路结构图;图3是本发明实施例的3x3的卷积核与输入数据进行卷积操作示例图;图4是本发明实施例的ping-pong方式的双缓冲实现数据预取示例图;图5是本发明实施例的池化层处理引擎的电路结构图;图6是本发明实施例的全连接层剪枝过程示例图;图7是本发明实施例的全连接层压缩存储示例图;图8是本发明实施例的流水线执行的时空图。具体实施方式以下结合具体实施例对上述方案做进一步说明。应理解,这些实施例是用于说明本发明而不限于限制本发明的范围。实施例中采用的实施条件可以根据具体厂家的条件做进一步调整,未注明的实施条件通常为常规实验中的条件。实施例:本发明实施例中的卷积神经网络加速系统包括通用处理器、现场可编程门阵列以及存储模块,其中,fpga和通用处理器之间的数据通路可以采用pcie总线协议、axi总线协议等。本发明实施例附图数据通路采用axi总线协议为例说明,但本发明并不限于此。图1是本发明实施例的加速系统整体结构图,如图所示,整个加速器系统映射到同一片fpga芯片上,其中ddr3dram作为加速器系统的外部存储器。processor是一个精简指令集(risc)的软核,它负责启动加速器、与主机端进行通信以及时间测量等。axi4-lite总线用于命令传输,axi4总线用于数据传输。在图1中,包含有多个处理引擎,它们与卷积神经网络模型中的网络层一一对应。当以alexnet模型为例时,pe1与alexnet中的第一个卷积层(conv-1)对应,pe2与alexnet中的第二个卷积层(conv-2)对应,pen与alexnet中的最后一个全连接层(fc-8)对应。为了提高整个加速器系统的性能,所有的处理引擎都以流水线的方式同时工作。卷积操作是由一组称为卷积核的三维数组构成,每组卷积核与输入特征图执行乘加运算,得到输出特征图。由于输出特征图也是三维的,因此,完成一个卷积层的计算需要6重for循环。算法1展示了卷积层计算的伪代码。算法的输入是n个输入特征图,它们将与m组卷积核做卷积操作,最后得到m个输出特征图。算法1:卷积层计算的伪代码为了加速卷积层的计算,本发明利用了循环分片和循环展开对上述伪代码进行优化。循环分片是将较大的循环空间划分成为几个较小的循环空间,从而确保在执行较小循环空间的计算时,计算所需要的数据一直保留在缓冲区而没有被换出。使用循环分片以后,硬件资源的消耗将主要取决于分片因子,从而能够节省大量的硬件资源。循环展开是把循环内的程序段重复多次完成,在没有数据依赖的循环体中能够实现并行计算,从而缩短程序的执行时间。优化后的伪代码如算法2所示,算法中的循环迭代器(m,n,r,c)被分片成为(tm,tn,tr,tc),而算法中的循环迭代器k没有分片,这是因为k值一般都很小(通常在[3,11]之间),并且在每一层中都不相同。最外层的4重循环(第1-4行)与中间的6重循环(5-14)的区别在于中间的6重循环在计算的过程中只需要访问片上缓冲区的资源即可,因此,我们在设计中需要设置合适的参数(即tm,tn,tr,tc),使得所需要的片上缓冲区的资源不要超过fpga芯片所能够提供的。算法2:优化后的卷积层计算伪代码图2是本发明实施例的卷积层处理引擎的电路结构图,该电路结构中包含有多个乘法器以及加法器,用来完成乘加(mac)操作。为了加快计算的速度,并行乘法计算后跟着一个加法树的结构完成累加计算。图3是本发明实施例的3x3的卷积核与输入数据进行卷积操作示例图,在图3中,9个乘法同时执行,完成以后经过加法树结构完成累加计算,得到最终的输出结果。该层如果不是cnn中的最后一层,那么该层的输出结果将传入下一层,作为下一层的输入;如果该层是cnn中的最后一层,则将直接输出。输入缓冲区、输出缓冲区以及权值缓冲区构成了数据缓冲区。在本发明中,权值数据和原始的输入数据都存储在芯片外的ddr3存储器中,在计算的过程中它们将被预取到相应的权值缓冲区和输入缓冲区内,计算的中间结果将被存储在输出缓冲区内。图4是本发明实施例的ping-pong方式的双缓冲实现数据预取示例图,如图4所示,计算单元首先使用inputbuff0中的数据计算,在这个过程中,将下一次需要用到的数据加载到inputbuff1中;下一次计算中,使用inputbuff1中的数据计算,在这个过程中,将下一次需要用到的数据加载到inputbuff0中。完成一轮的计算以后,将数据写入outputbuff1中。接着开始下一轮的计算,与之前不同的是,下一轮计算完成以后,将数据写入outputbuff0中。如此循环往复,达到计算与io重叠的目的。权值缓冲区的设计和输入缓冲区一样。为了避免数据传输成为整个设计的性能瓶颈,需要保证用于数据计算的时间大于数据传输的时间。经过这样的设计以后,处理引擎将能够在每一个时钟周期输出一个中间结果。图5是本发明实施例的池化层处理引擎的电路结构图,这里我们以计算维度是(2,2)的神经元中的最大值为例说明池化层处理引擎的执行过程。如图5所示,为了获取p1的值,需要先得到c1,c2,c3和c4,它们都是上一层卷积层的输出。在该结构中,首先获得c1和c2的值,然后送入比较器进行比较,并将两者之中的较大者max(c1,c2)存入先进先出(fifo)缓冲区内。当上层的卷积层处理引擎完成计算得到c3和c4后,将c3和c4送入该结构,这时,压入缓冲区的值max(c1,c2)将被取出,并与c3和c4进行比较,并将最终的结果max(max(c1,c2),c3,c4)赋值给p1,这样一个池化操作就完成了。需要注意的是,池化层的计算和卷积层的计算是重叠在一起的,这样就可以隐藏池化层的执行时间。全连接层是访存密集型的,并且占据了大部分内存访问。为了减少所需要的内存带宽,我们使用了剪枝的方法。图6是本发明实施例的全连接层剪枝过程示例图,如图6(a)所示,剪枝过程分为以下三个步骤。第一步是通过正常的训练来学习连接。第二步是剪枝,即网络连接中低于阈值的连接会被删除。剪枝完成以后,网络将会变得稀疏,如图6(b)所示。第三步是重新训练保留下来的那些连接,获取最终的权值矩阵。最后一步对于保持较高的预测准确率至关重要。我们对全连接层使用了剪枝,而没有对卷积层使用剪枝的原因是全连接层的连接占整个网络模型连接的绝大部分。以alexnet模型为例,它的5个卷积层的权值占了整个网络权值连接的4%,而3个全连接层的权值占了整个网络权值连接的96%,因此,对卷积层使用剪枝收益不大,并且会破环卷积层原有的计算模式。表1:对alexnet模型的3个全连接层使用剪枝方法后的连接数layerweightbeforeweightafterratefc-638m3.5m9%fc-717m1.5m9%fc-84m1m25%total59m6m10%表1展示了对alexnet的3个全连接层使用剪枝后的结果。从表中可以看到,在使用剪枝前,3个全连接层的权值数量为59m,使用剪枝后,权值数量减少到6m,权值数量减少了10x。为了高效的存储经过剪枝以后的权值矩阵,本发明中采用了压缩存储的技术。图7是本发明实施例的全连接层压缩存储示例图,如图7所示,对于一个经过剪枝以后的5x5的稀疏矩阵,左边采用压缩稀疏列(csc)格式进行存储,右边采用压缩稀疏行(csr)格式进行存储。对于csc、csr两种格式来说,最后都将原来的矩阵转化为3个向量。对于csc格式来说,3个向量中分别存储着非0元素的值、相应的行索引以及列偏移。对于csr格式来说,3个向量中分别存储着非0元素的值、相应的列索引以及行偏移。由于全连接层要执行的计算是向量矩阵乘法,因此,在这里我们假设输入向量为(x0,x1,x2,x3,x4),与权值矩阵相乘得到输出结果。如果采用csr格式存储的话,那么输入向量与权值矩阵的第一列进行计算的过程中,将会读取图7(b)中灰色标记的值,它们并不连续,因此会造成很多的随机访问。如果采用csc格式存储的话,那么输入向量与权值矩阵的第一列进行计算的过程中,将会读取图7(a)中灰色标记的值,它们是连续访问的,因此采用csc格式的存储比csr格式的存储来计算全连接层,数据的局部性更高。对于一个m行n列的权值矩阵,给定矩阵的稀疏率为p,使用csc格式压缩存储以后,权值的数量为m*n*p*2+n+1。因此,压缩率可以通过公式1计算得到。对于alexnet模型来说,p的取值为0.1。为了降低加速器对存储器带宽的要求,在本发明中,对全连接层使用了批处理的方法。使用批处理方法以后的全连接层计算如算法3所示,其中wt[]、index[]和offset[]3个向量是使用csc压缩存储后得到的,分别存储着非0元素的值、相应的行索引以及列偏移。算法3:全连接层的计算的伪代码整个算法的执行过程可以总结为以下3步,它们将重复batchsize次。读取index[]缓冲区,用来获得非0权值wt[];根据index[]缓冲区的值到输入缓冲区的对应位置取得相应的元素;权值wt[]与输入向量做并行计算。从算法3中可以看出,每次计算的过程中,都只取权值非0的元素与对应的输入做计算,而不是对所有的输入都做计算,因此,与没有优化前全连接层的计算相比,使用剪枝和压缩存储以后,全连接层的计算量大大的减少了。全连接层处理引擎的电路结构见图2。在本发明中,为了提高整个加速器系统的性能,所有的层(包括全连接层)同时以流水线的方式工作。为了最大化流水线结构的吞吐率,应该尽量保证每一层的计算时间大致相等,这样整个流水线就不会存在瓶颈段了。为了实现这一目标,我们将根据每一层的计算量来给它分配相应的计算资源。每一层所分配的计算资源可以用等式2来计算。这里我们以alexnet模型和virtex-7fpga开发板为例。virtex-7fpga开发板共有2800个dsp,而alexnet的第一个卷积层有105m的mac操作,占整个cnn网络计算量的14.6%,因此,根据等式2可以计算得到第一个卷积层所分配得到的dsp资源的数量为2800*14.6%=408。其它层可以用相同的方法计算得到它们所分配的dsp资源数量。在本发明中,对不同的卷积层使用了不同的分片展开参数,使得每一个卷积层都可以更加充分的利用所分配到的计算资源,从而提高硬件资源利用率。等式3列举了所有合法的分片空间。其中,#dspsperoperation主要与数据的表示精度有关。在我们的cnn设计中,统一采用16-bit定点来表示输入数据、权值数据和中间结果,因此,#dspsperoperation等于1。我们需要搜索所有可能的分片展开因子组合(tm,tn,tr,tc),找到最合适的分片因子,使得每一层都能够充分利用所分配的计算资源,同时还要满足片上缓冲区的限制。本发明中使用穷举的方法。为了降低控制的复杂度,m,n,r,c最好是tm,tn,tr,tc整数倍,这样也可以减少硬件空闲的周期。给定一组分片展开因子组合(tm,tn,tr,tc),我们就可以通过等式4计算每一个卷积层的执行周期。表2:alexnet模型在virtex-7开发板上实现的参数配置表2列出了alexnet模型的5个卷积层在virtex-7fpga开发板上硬件实现的搜索结果。从表中我们可以看到,每一个卷积层实际使用的dsp资源都没有超过该层分配的dsp资源。更为重要的是,每层的执行周期大致相等,所以整个流水线设计没有瓶颈段。图8是本发明实施例的流水线执行的时空图,正如算法3所示,在对全连接层的优化中,我们使用了批处理的方法。算法4:编程模型代码片段本发明还定义了一组编程接口,用来管理设计的加速器。本发明定义的这一组编程接口通用性很强,能够适用于类似应用领域的不同加速器。编程模型的代码片段如算法4所示,它包含以下2个步骤:硬件平台初始化:初始化包括dma设备的初始化以及加速器的初始化。为了添加更多的硬件模块,我们可以根据硬件的规格相应地修改初始化代码。我们使用axidma_cfginitialize()函数来初始化dma设备,dma设备的初始化参数存储在dmadev结构体中,包括通道号、数据宽度、操作模式以及控制信号。与dma设备初始化类似,加速器的初始化使用pipe_cfginitialize()函数,相应的初始化参数存储在nnetwork结构体中,包括控制信号、设备名称以及物理地址。应用加载以及数据传输:初始化完成以后,我们就可以通过向控制寄存器中写入对应的值来启动加速器和dma设备。所有引导加速器执行任务的信息都存储在inputdata结构体中,加速器完成计算以后的结果信息都存储在outputdata结构体中。需要特别指出的是,我们使用dma_transfer()函数将任务所需要的信息传输到加速器中,并从加速器取回计算完成后的结果。该函数有4个参数,第一个参数指定dma设备(如果有多个dma设备,必须从中选择一个),第二个和第三个参数分别代表数据的起始地址以及数据大小,第4个参数设定了dma传输的方向,有两个方向可供选择,其中xaxidma_dma_to_device表示将数据从存储器传输给加速器,xaxidma_device_to_dma表示将数据从加速器传输给存储器。表3对编程模型中的函数进行了汇总。表3:编程模型中使用的函数与参数上述实例只为说明本发明的技术构思及特点,其目的在于让熟悉此项技术的人是能够了解本发明的内容并据以实施,并不能以此限制本发明的保护范围。凡根据本发明精神实质所做的等效变换或修饰,都应涵盖在本发明的保护范围之内。当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1