发明内容
针对上述存在的技术问题,本发明目的是:提供了一个基于FPGA的深度神经网络加速平台,使得不具备硬件知识的编程者可以利用已有的FPGA资源,轻松获得良好的硬件性能。
本发明的技术方案是:
一种基于FPGA的深度神经网络加速平台,包括通用处理器、DRAM和FPGA,所述通用处理器用于解析神经网络配置信息以及权值数据,并将神经网络配置信息以及权值数据写入DRAM中,然后FPGA从DRAM中读取配置信息,生成FPGA加速器,接着通用处理器读入图片信息,并把它写入DRAM中,然后FPGA加速器从DRAM中读取图片数据并开始计算,并把计算结果写入DRAM中,最后通用处理器从DRAM中读取计算的结果;所述生成FPGA加速器,包括以下步骤:
S01:根据深度神经网络特点,确定数据合适的表示位数;
S02:根据深度神经网络计算过程,针对各层分别设计出可扩展的IP核实现;
S03:根据用户的网络拓扑结构和FPGA的资源,确定该种资源配置下神经网络各层对应的硬件IP核结构;
S04:移植操作系统到硬件平台,并将硬件IP核烧写到硬件平台,编写各个硬件设备的驱动;
S05:在用户层调用各个硬件IP核,形成硬件加速器。
优选技术方案中,所述步骤S01中数据合适的表示位数是指用定点表示数据代替浮点表示数据,并且在深度神经网络中,针对各层对数据精度降低的敏感性不同,各层选择不同比特位来表示数据。
优选技术方案中,所述步骤S02中各层分别设计出可扩展的IP核,具体包括卷积层IP核、池化层IP核、激励层IP核、全连接层IP核。
优选技术方案中,所述步骤S02中,还提供参数<flagpool,flagact>来标识池化层以及激励层是否被调用;在设计卷积层IP核和全连接层IP核时,使用了双缓冲机制来预取下一个分块的数据,达到了计算时间与数据传输时间重叠的效果;在设计卷积层IP核和全连接层IP核时,通过把并行循环展开层调整到最内层循环,使得流水线的流水间隔为1;激励层IP核使用分段线性近似的方法实现任意的激励函数。
优选技术方案中,所述步骤S03包括以下步骤:
解析深度神经网络各层的配置信息;
根据各层的计算任务为每一层分配相应的硬件资源;
每一层根据分配到的硬件资源,确定其对应的循环分块大小,即该层的硬件IP核结构。
优选技术方案中,神经网络各层的配置信息包括,
卷积层:层类型、卷积核的个数、卷积核的大小、卷积核的步长;
池化层:层类型、池化方法、池化层的大小、池化层的步长;
激励层:层类型、激励方法;
全连接层:层类型、输出个数。
优选技术方案中,在确定各层对应的循环分块大小时,采用的是设计空间搜索,目标是最大化FPGA资源利用率。
优选技术方案中,所述步骤S04包括以下步骤:
在驱动的编写中,采用访问Linux字符设备的方式访问各个硬件设备;
在DMA的驱动编写中采用映射机制进行数据填充;
所述映射机制为在内存中预留出一段连续的物理内存,将其映射到内核空间中的一段地址中,然后将该段内核空间地址映射到用户空间。
优选技术方案中,所述步骤S05中形成的硬件加速器特点在于,深度神经网络各层能够同时部署在FPGA芯片上,各层间以流水线的方式运行,减少了中间数据的传输,同时整个加速器的吞吐量也大大增加。
与现有技术相比,本发明的优点是:
本发明可以简单易用,对用户透明,能够根据硬件资源和网络拓扑设计出针对深度神经网络的加速器,来加速深度神经网络应用,该加速器使得各层能够同时部署在FPGA芯片上,并以流水线的方式运行。本发明使得不具备硬件知识的编程者可以利用已有的FPGA资源轻松获得良好的性能。
具体实施方式
以下结合具体实施例对上述方案做进一步说明。应理解,这些实施例是用于说明本发明而不限于限制本发明的范围。实施例中采用的实施条件可以根据具体厂家的条件做进一步调整,未注明的实施条件通常为常规实验中的条件。
实施例:
本发明实施例中的深度神经网络加速平台包括通用处理器、现场可编程门阵列以及存储模块,其中,FPGA和通用处理器之间的数据通路可以采用PCI-E总线协议、AXI总线协议等。本发明实施例附图数据通路采用AXI总线协议为例说明,但本发明并不限于此。
图1是本发明实施例的加速系统平台的设计流程图,包括的步骤如下:
通用处理器用于解析神经网络配置信息以及权值数据,并将神经网络配置信息以及权值数据写入DRAM中;
FPGA从DRAM中读取配置信息,用于生成FPGA加速器;
通用处理器读入图片信息,并把它写入DRAM中;
FPGA加速器从DRAM中读取图片数据并开始计算,并把计算结果写入DRAM中;
通用处理器从DRAM中读取分类的结果。
图2是本发明实施例的加速系统平台的加速器设计流程图,包括的步骤如下:
根据深度神经网络特点,确定数据合适的表示位数;
根据深度神经网络计算过程,针对各层分别设计出可扩展的IP核实现,主要包括卷积层IP核、全连接层IP核等;
根据用户的网络拓扑结构和FPGA的资源,确定该种资源配置下神经网络各层对应的硬件IP核结构。
图3是本发明实施例的加速系统平台的层次结构图,包含三层,由上到下分别是:用户层、内核层以及硬件层,其中最下层是硬件层次,其它两层都为软件层次。
硬件层次就是神经网络的硬件IP Core层,它除了包含神经网络加速器结构以外,还包含了其他的硬件IP Core部件,比如DMA以及一些总线互连结构等。
软件层次则包含了应用层、平台支持库层以及硬件驱动层这三个层次。
对于应用层,用户通过调用下层的平台支持库层所提供的硬件编程接口来实现能够运行在硬件加速器上的程序。
平台支持库层次是软件层次中最重要的一个层次。平台支持库层主要包含了运行时环境库和用户编程接口这两个内容。
硬件驱动层是软件层次的最底层,主要用来提供硬件加速器以及其他IP Core在Linux操作系统下正常运行的支持。
不同网络拓扑下,改变权值数据的比特位数,观察预测精度(与32位浮点表示的相对精度),结果如表1所示。从表1可以看出,对于Lenet网络,权值数据只需6比特即可达到相同的预测精度,而对于Alexnet网络,权值数据需要10比特才能达到相同的预测精度,即不同的网络拓扑对于权值数据所需的比特位数不同,此结论同样适用于计算过程中的中间结果数据。
表1:不同网络拓扑下,精度随比特位数变化
同时,将Lenet网络进行分解,如表2所示,并改变权值数据的比特位数,观察预测精度(与32位浮点表示的相对精度),结果如表3所示。从表3可以看出,对于Layer1,权值数据只需3比特即可达到相同的预测精度,而对于Layer2,权值数据需5比特,对于Layer3,权值数据需7比特,对于Layer4,权值数据需5比特,即同一网络拓扑下,不同层对于权值数据所需的比特位数不同,此结论同样适用于中间结果数据。同时也看以看到,卷积层对数据精度降低不太敏感,因此可以用较少的比特位来表示,而全连接层由于靠近分类结果,因此对数据精度降低很敏感,因此需要较多的比特位来表示数据。
在神经网络的计算中,常用的是用32位浮点来表示数据,也有用16位定点或者16&32位混合来表示数据,这样会浪费大量的存储空间,同时也会增大芯片面积。而在本发明设计的神经网络加速器中,采用定点表示数据代替浮点表示数据,并且对于不同的层,定点表示数据的比特位数也不相同。对于卷积层,数据表示所用的比特位数区间为[2,10]位;对于全连接层,数据表示所用的比特位数区间为[3,21]位。
表2:Lenet各层分解
表3:同一网络拓扑不同层,精度随比特位数变化
典型的卷积神经网络包含两个部分:特征提取器和分类器。其中特征提取器包含多个卷积层和池化层,用来提取输入图片的特征,形成特征图片;分类器一般由全连接层组成,用来决定输入图片属于哪个类别。
卷积层的伪代码如下所示,它接收N个特征图作为输入,每个输入特征图被一个大小为K*K的滑动窗口做卷积运算,用来生成一个输出特征图上的一个像素点。其中滑动窗口的步长是S,M个输出特征图将作为下一轮的输入参与运算。
为了加速卷积层的计算,本发明利用了循环分片(loop tiling)、循环流水(looppipeline)和循环展开(loop unrolling)对上述伪代码进行优化。优化后的伪代码如下所示。
由于循环迭代变量i和j相对来说较小(通常范围是[3,11]),因此没有分片,其他的循环迭代变量(row、col、to和ti)都分片成了的分片的循环迭代变量(trr、tcc、too和tii)。
利用循环流水和循环展开来充分利用FPGA的大量计算资源,增加计算的并行力度。同时为了使得流水线的流水间隔为1,本发明把并行循环展开层调整到最内层循环中。此种方法充分利用了数据局部性,并降低了硬件所需数据带宽,提高了计算吞吐率。
图4是本发明实施例的加速系统平台的卷积层IP核结构设计图,该结构包括:
Input Buffer:输入数据缓冲区;
Weight Buffer:权值数据缓冲区;
Output Buffer:输出数据缓冲区;
AXI-Stream:允许无限制的数据突发传输,为高性能数据传输协议;
AXI-Lite:一种轻量级的地址映射单次传输协议,适用于硬件运算单元的控制信号传输;
Memory Interconnect:数据通路互联;
DMA:直接内存存取,负责加速器和内存间的数据传输;
Control Interconnect:控制信号线路互联;
PE:乘法计算单元;
本发明设计了大量的并行处理单元(PE)来提高计算性能,每个PE负责输入特征图的像素和相应权值的乘法计算,后面跟着一个加法树结构来累加卷积的中间结果。处理单元PE的数量根据分片Tm*Tn决定。
同时,本发明使用了双缓冲机制来预取下一个分片的数据,达到了计算时间与数据传输时间重叠的效果。
在神经网络中,池化层和激励层总是跟随在卷积层之后(如果有用到),并且能够根据卷积层的输出直接计算出它们的特征图,所以提供参数<flagpool,flagact>来标识池化层以及激励层是否被调用。
图5是本发明实施例的加速系统平台的分段线性近似实现激励层IP核结构设计图,本发明实例采用分段线性近似来实现S型激励函数,将函数按X轴划分为若干等值间隔,每个间隔内按Y=ai*X+bi,X∈[xi,xi+1)进行线性近似,其中xi+1-xi为近似的间隔大小。
每当需要计算激励函数时,首先按照X值寻找其所在的区间并计算其对应的ai和bi相对于基地址的偏移量,进行乘加运算后,即可近似得到Y值。
这种实现方式有两点好处:
1)、可实现任意的S型激励函数或线性函数,而且无需更改任何硬件设计,仅需要更换系数a和系数b所存储的数值即可;
2)、误差极小,当近似区间降低时,误差可以达到可以忽略,而代价仅仅是增加用于存储系数a和系数b的BRAM。而且深度学习计算本身对数据的精确度的要求并不是很高或者说一定程度的精度损失并不影响数据结果。
图6是本发明实施例的加速系统平台的分段线性近似实现sigmod函数结构设计图,与图5不同的是,增加了一条X直接传输到Y的通路,让运算单元可以仅仅执行卷积操作而不经过激励函数的处理。
由于S型激励函数基本上是关于某点对称,以sigmoid函数为例,sigmoid函数关于(0,0.5)对称,所以当x小于0时,按照1-f(-x)进行计算,这样可以复用硬件逻辑,减少对硬件资源的使用。而且当x等于8时,f(x)等于0.999665,之后便无限接近于1,故当x大于8时,直接对结果赋值为1。
全连接层主要涉及大量的矩阵乘法运算,本发明同样采用循环分片思想优化全连接层计算,图7是本发明实施例的加速系统平台的全连接层IP核结构设计图。
假设分片的大小为16,将输入特征矩阵每一行内部按16进行分片,权值参数矩阵按照每一列16个元素进行分片。按行将输入特征矩阵的每16个数据与权值参数矩阵每一列对应的16个数值进行点积运算,待每一行计算完毕后再将这些临时值累加即可得到最终结果,累加时同样采用的是加法树结构(如图4所示)。此种方法不仅充分利用了数据局部性,并降低了硬件所需数据带宽,还让单个运算单元可以实现任意规模的矩阵乘法计算。
为了保持高吞吐率,分片的大小应与运算单元内部设计相配合,同并行粒度保持一致,在矩阵乘法运算时,可以将分片设定为2的n次方,来充分发挥二叉树的累加性能。由于分片大小与并行粒度有关,理论上来说分片越大,并行度越高,运算单元的性能也会越好,所以在硬件资源和带宽允许的情况下,选择最大的2n作为运算单元的分片大小。
神经网络各层的配置信息包括,
卷积层:层类型、卷积核的个数、卷积核的大小、卷积核的步长;
池化层:层类型、池化方法、池化层的大小、池化层的步长;
激励层:层类型、激励方法;
全连接层:层类型、输出个数。
下面是神经网络中卷积层和池化层的配置信息格式。
在设计好上述可扩展IP核结构后,读入神经网络的配置信息和FPGA的资源,根据每一层的计算量为每一层分配相应数量的DSP单元,根据每一层的权值数据所占存储空间为每一层分配相应数量的BRAM单元。然后各层在所分配的硬件资源下,利用设计空间搜索方法,枚举出所有可能的分片情况,找到各层在该配置下,能够最大化硬件资源利用率的组合,即为该层的硬件IP核结构。
当用户给出的网络拓扑是:卷积层→激励层→池化层→卷积层→激励层→池化层→全连接层→全连接层和ZedBoard ZYNQ FPGA开发板时,加速系统平台实现的加速器结构设计图如图8所示。该结构包括:
主机端作为整个系统的控制端,运行软件端代码,并将加速任务加载至FPGA端进行工作。此外,主机端可控制各IP核的工作状态和数据读取等等;
FPGA芯片为整个系统的硬件加速部件,可以根据不同加速任务在FPGA芯片上固化相应的IP核来实现。各个IP核以流水线的方式运行,减少了中间数据的传输,提高了系统的吞吐量。
DDR,负责存储神经网络参数以及输入数据,这里要求数据存储的物理地址为连续的,方便DMA进行数据传输;
数据总线,负责整个系统主机端和FPGA端数据传输;
控制互联,负责整个系统主机端和FPGA端控制信号的传输。
直接内存存取DMA,负责加速器和DDR间的数据传输,每个硬件处理单元均配备一个DMA来并行读取数据;
图9是本发明实施例的操作系统移植到开发板的工作流程图。第一步就是格式化SD卡,生成两个分区:分区1是FAT格式,空间大小在1G以上;分区2是EXT-4格式,空间大小在3G以上。第二步准备四类文件:BOOT.BIN文件包含一些可编程逻辑和处理系统的配置信息,除此之外还包含有加载linux的u-boot信息;Device-tree文件包含有各个硬件相关的驱动信息,而且是内核启动的参数的home目录;这两个文件和内核镜像都存放在分区1中。文件系统是Linux下支持文件读取与存储的系统,目前在平台下支持的文件系统是l inaro和BusyBox,该文件存放在分区2中。这四类文件包含了系统在硬件平台下运行所需要的所有的相关文件。第三步编写IP核和硬件设备的驱动:采用Linux字符设备访问的方式编写各个硬件设备的驱动。
图10和11是本发明实施例的加速系统平台的DMA传送数据的流程图。本发明实施例采用的是驱动动态加载的方式,即将编写好的驱动模块以内核模块的方式动态加载到内核中,各个设备驱动都是采用Linux字符设备驱动模型实现。在操作系统中,分页的机制使得用户进程空间连续地址中存放的数据在物理地址中并不一定是连续的,而DMA传送数据需要连续的物理地址,所以在DMA将数据传送到FPGA片内之前,需要将用户层的数据拷贝到物理地址连续的空间内。
如图10为DMA传送数据的流程图,如图所示:
首先在DMA驱动中利用Kmalloc函数分配一段连续的物理内存,并给出其对应的内核空间的逻辑地址;其次在用户执行应用程序时,将所需要的数据从用户进程空间读取出来并写入到Kmalloc分配的连续物理内存对应的内核空间地址中,写入完毕后数据就实现了在物理地址中的连续存储,最后DMA从连续的物理地址空间中读取数据传送到IP Core,IP Core读取数据进行计算。这就是DMA将数据从用户态传送到IP Core内部的整个流程。IPCore计算后的结果先通过DMA传送到物理地址连续的内存中,然后再从内核空间中将数据传送到用户进程的地址空间中。从图可以看出,完成一次计算需要两次的数据拷贝,而数据拷贝的速度是很慢的,无疑这会降低加速器的性能,为此本发明采用了映射的方式来减少整个数据传送过程中的数据拷贝次数。
图11是映射机制下DMA传送数据的示意图。首先在Linux系统中预先保留一段连续的物理内存(64M),并将它映射到内核空间的前896M中,则该段物理内存和内核地址空间中的一段虚拟地址是对应的,这些信息会保存在MMU PageTable中;然后将内核空间的这段虚拟地址映射到用户进程的某段地址空间中,这样该段用户进程地址空间就和物理地址完成了映射,该段用户进程地址内的数据是存储在地址连续的一段物理内存中。在映射机制下,DMA传送数据的整个流程如下:应用程序执行的过程中将所需要的数据填充到映射后的某段用户进程空间的地址中,然后DMA就可以操作与用户虚拟地址对应的物理地址进行数据的传送,IP Core读取数据进行计算,DMA将计算结果传送到指定的连续的物理内存中,而该物理内存已经映射到用户进程,所以不再需要数据的拷贝操作。由此可见一次计算只需要一次数据的拷贝操作,在数据量小的时候加速器性能的差别不是很明显,但是如果数据量非常大的时候,需要进行多次分片操作,涉及到的数据拷贝次数会非常多,加速器的性能也会出现明显的不同。
上述实例只为说明本发明的技术构思及特点,其目的在于让熟悉此项技术的人是能够了解本发明的内容并据以实施,并不能以此限制本发明的保护范围。凡根据本发明精神实质所做的等效变换或修饰,都应涵盖在本发明的保护范围之内。