李炳剑,秦国轩,朱少杰,裴智慧
天津大学 微电子学院,天津300072
1 引言
随着人工智能的高速发展,卷积神经网络(convolutional neural network,CNN)越来越受到人们的重视,在图像处理等很多领域发挥着重要的作用[1-2]。相比于传统算法,CNN 的计算复杂度要高很多,通用CPU已经无法满足计算需求,目前主要的解决方法是使用GPU 进行CNN 的计算,虽然GPU 在并行计算方面有着天然的优势,但是在成本和功耗方面有着很大的不足,无法满足一些低特定场景下的CNN计算要求。
FPGA(field-programmable gate array)具有强大的并行处理能力、灵活的可配置特性和超低功耗,使其成为CNN 的实现平台的理想选择。目前已经有很多研究人员研究了使用FPGA 实现CNN 加速[3]。
Farabet 等人提出了一种运用移位寄存器实现卷积运算单元的方案,该结构设计简单,在一定程度上实现了CNN 中卷积部分的并行化计算,但是这种设计结构并行化计算程度有限,并且对于卷积核尺寸的支持也不够灵活[4]。
Ma 等人提出了一种卷积层间流水,同一层内部在输出特征图数、宽度和高度三个维度展开实现并行化计算的加速器架构。但是该文所提出的架构将特征图像素和权重都缓存在片上,这种设计对于FPGA 资源需求过多,很难在低端FPGA 上使用[5]。
Feng 等人设计的加速器使用了流水线和循环展开来优化计算过程,实现卷积并行化计算,数据复用的程度也得到了有效提升,但是在嵌套循环重构方面的设计并不合理,虽然节省了硬件资源,但是在计算性能方面不是很理想[6-7]。
Zhang 等人设计了一种用于VGG 网络加速的FPGA 加速器,该加速器针对VGG 网络特点进行了特定优化,在Arria10 GX1150 FPGA 上实现了高达1 790 GOP/s 的计算能力,但是缺点也很突出,该加速器只能支持单种特定网络加速,无法满足通用化的需求[8]。
Ferdman 等人将研究重点放在了在片内外访存带宽需求上。其在文章中指出,在计算神经网络时,由于是逐层计算,在计算每层的前后都要读写特征图片,这占据了近50%的片外存储访问。因此他们提出了一种层间计算融合的模式(fusion),相比其他加速器,在fusion 计算模式中,一层结果计算完成后直接进行下一层的计算而不是被存储到片外中,这种模式可以尽可能地减少片内外的数据传输[9]。
本文在研究了大量CNN 模型特性后,设计了一款基于FPGA 的CNN 加速器,通过使用流水线架构以及多个层面实现的并行计算,提升了CNN 计算效率。设计了片内存储及权重缓存器(buffer)的双缓存结构,减少片外存储访问的同时实现了有效的数据复用。支持参数化设计,让所设计的加速器可以适配在不同规模的FPGA 上。通过指令控制可以实现模块间运算顺序的变换以及单个模块内部配置的变换,这种设计可以实现支持不同的CNN 模型加速的目的。
2 加速器设计研究2.1 CNN 介绍
卷积神经网络是一种经典的深度学习模型,目前被广泛应用于图像识别等领域。其经典网络模型包含卷积层、池化层、全连接层等结构,卷积过程如图1 所示。输入的图像首先经过多个卷积层和池化层运算,之后进入全连接层,最后通过输出层得到最终的分类结果[10]。
在介绍加速器的设计细节之前,首先研究了当前最先进的几种CNN 模型,目的是通过这些CNN 模型的结构分析来帮助更好地设计加速器所需的功能。几种典型的CNN 模型列在了表1 中。
CNN 中卷积层的功能是通过卷积运算对输入数据进行特征值提取。卷积层通过输入特征图与由权重wi,j组成的卷积核进行卷积运算,运算结果加上偏置后输出,输出即卷积层运算结果[11]。卷积层运算如式(1):
Fig.1 Convolutional neural network图1 卷积神经网络示意图
Table 1 Typical convolutional neural network表1 典型CNN 模型
卷积层内部包含多个卷积核,目前CNN 中卷积核大小正在发生变化。早期的CNN 设计[12]采用的卷积核尺寸为11×11,相比目前最常用的3×3 卷积核要大得多。152 层ResNet 在除了第一层外的所有卷积层都使用了3×3 卷积核。SqueezeNet[13]甚至使用1×1卷积核来进一步降低计算复杂度,实验结果表明这种结构达到了AlexNet[14]的准确度,而参数量仅为其1/50。在卷积层中使用较小的内核可以显著地减少计算复杂度,因此目前人们更倾向于使用较小的卷积核。从表1的统计中也可以看出目前最受欢迎的卷积核大小是3×3 卷积核以及1×1 卷积核,因此本文设计的加速器支持3×3 和1×1 两种卷积核,这样的设计可以让所设计的加速器支持大部分最新的CNN模型。
池化层目的是在尽量不丢失图像特征的前提下,对图像进行降采样。目前的CNN 网络主要有最大池化(Maxpooling)和平均池化(Averagepooling),虽然Maxpooling 和Averagepooling 都对数据进行了下采样,但是Maxpooling 进行了特征选择,选出了分类辨识度更好的特征,因此Maxpooling 的效果更好一些,Averagepooling 主要是对整体的特征信息进行下采样,能更好地减少参数量[15-16]。由表1可以看出目前大部分CNN 运用的是Maxpooling,Averagepooling 仅在部分网络的特定层中使用,因此本文所设计的加速器仅支持Maxpooling运算。其运算过程如式(2)所示:
CNN 中全连接层是对输入进行线性空间转换,得到输出,其计算过程描述为:
激活函数主要是用来给网络加入非线性因素,常用的激活函数主要有Sigmod、Tanh、ReLU 等。ReLU 函数比Sigmod 函数和Tanh 函数有更快的收敛速度,因此是目前最受欢迎的激活函数[17-18]。从表1的统计也可以看出,几种典型的CNN 网络均使用ReLU 作为激活函数,另外两种激活函数目前已经很少用到,因此本文所设计的加速器仅支持ReLU运算。
ReLU 模块设计比较简单,只需将输入的负值数据置零即可。ReLU 计算公式为:
下面以VGG16 为例,通过分析VGG16 的网络结构进一步探讨CNN 加速器的设计思路。VGG16 网络结构如图2 所示,一共有13个卷积层,3个全连接层和5个池化层,卷积层均为3×3 大小的卷积核,池化层均使用2×2 窗口大小的池化。
Fig.2 VGG network structure图2 VGG 网络结构
其每层网络参数如图3 所示,特征图数据量在第一层时最大为3.2 MB,而权重数据在第一个全连接层时数据量最大,达到了102 MB,这样的数据量很难在FPGA 片上高速缓存。因此,需要设计合理的存储结构以及数据复用方式,下一节将进行具体探讨。
Fig.3 VGG network parameters图3 VGG 网络参数
2.2 计算精度优化
VGG 网络采用的数据为32 位浮点数,这在大部分FPGA 中需要使用3个数字信号处理(digital signal processor,DSP)资源才能实现一次乘累加操作,但如果使用8 位定点数则只需1个DSP 就能实现一次乘累加。同时,使用8 位定点数相比32 位浮点数还能有效减少FPGA的片上存储资源占用。相关的实验证实了降低精度对于CNN 识别准确度影响是很低的[19]。因此本文设计中输入的图像数据和权重数据均采用8 位定点数,这样的设计减少了FPGA 资源利用,同时提升了网络运算速度。
2.3 参数化设计
不同型号的FPGA 可用资源不同,固定的加速器架构无法在不同型号的FPGA 中都发挥最佳的性能,因此提出了参数化的设计方案,通过在综合前改变参数N的值可以实现不同规模的加速器,所设计的加速器提供了3种参数设置,在N等于32、64、128时分别可以产生512、1 024、2 048个MAC 的加速器架构。
3 加速器设计方案3.1 加速器整体结构
加速器的整体架构如图4 所示,由主机和FPGA组成。其中主机主要负责图像数据、权重数据的预处理以及指令数据生成工作,FPGA 负责整个CNN运算部分。
Fig.4 CNN accelerator overall structure图4 CNN 加速器整体结构
加速器运算过程由主机负责控制,首先通过主机将图像和权重数据进行预处理,将精度转化为8 位定点数。然后根据网络结构生成指令,当数据和指令准备完成后,主机将图像数据、权重数据和指令数据传输到外部存储器中,传输完成后发出指令控制FPGA 中的CNN 运算单元启动。当运算完成后,运算结果数据会通过FPGA 发回给主机。
3.2 加速器计算单元架构
CNN 的计算单元流水线结构如图5 所示。其中卷积运算模块和池化模块分别负责CNN 中的卷积和池化运算部分。直接内存存取(direct memory access,DMA)模块负责从外部双倍速率同步动态随机存储器(double data rate,DDR)中搬运图像数据、权重数据和指令数据,并负责将运算结果写回DDR,其中搬运进来的图像数据存放在片上存储中,权重数据存放在权重buffer 中,指令数据存放在指令随机存取存储器(random access memory,RAM)中,DMA 通过AXI4总线与外部DDR 通信。指令控制模块负责从指令RAM 中读取指令数据分发给卷积运算模块、池化模块和这两个模块相对应的地址控制器,通过一些简单的指令变换可以实现卷积层、池化层顺序方面的排列组合,是否进行归一化(batch normalization)计算,以及不同卷积核大小间的模式选择等,这样的设计可以达到支持不同网络模型的目的。地址控制器1 负责通过产生地址来访问片上存储相应的特征图数据并将这些数据送入卷积运算单元,同时负责将卷积模块以及ReLU 模块处理后的数据写回片上存储中,地址产生器1 可以通过产生无效地址来支持零填充(Padding)功能。地址控制器2 负责从片上存储中读取上一层卷积和ReLU 运算后的数据送入池化模块进行池化运算,并负责将结果写回片上存储中。
Fig.5 Accelerator computing unit architecture图5 加速器计算单元架构
本文所设计的架构运算过程为:
(1)将神经网络模型转换成加速器能识别的神经网络指令。
(2)将图像数据、权重数据和转换好的神经网络指令存入FPGA 上的外部DDR 中。
(3)通过CPU 启动加速器,加速器的DMA 模块首先启动,将部分图像数据搬运到片上存储中,将权重数搬运到权重buffer 中,将指令数据搬运到指令RAM 中。
(4)当图像数据和指令数据搬运完成后指令控制模块启动,从指令RAM 中读取指令数据,分发给卷积运算模块和地址控制模块。卷积运算模块收到指令后,根据指令要求从片上存储中读取图像数据同时从权重buffer 中读取权重数据,并进行卷积运算,卷积运算后将数据送入ReLU 模块完成ReLU 运算。
(5)卷积以及ReLU 运算完成后,指令控制模块将后面的指令分发给池化模块和相应的地址控制模块。池化模块收到指令后,从片上存储中读取第4 步运算后的数据,根据指令要求进行池化运算,运算后将结果写回片上存储。
(6)反复执行步骤(4)和步骤(5),直到整个卷积神经网络运算完成,然后将运算结果通过DMA 搬运回DDR 中,完成整个加速过程。
3.3 卷积模块
卷积运算单元如图6 所示,包括16个处理单元(processing unit,PE)模块和一个加法器。PE 模块主要负责卷积运算中乘法运算、一部分加法运算以及归一化Batch Normalization 运算;加法器负责将16个PE 模块的计算结果与片上存储输入进来的中间结果相累加。
Fig.6 Convolution operation module图6 卷积运算模块
PE 模块结构如图7 所示,16个PE 模块每个模块中有一个权重buffer 负责存储权重数据以便进行数据复用。其具体运算过程是:输入PE 的N个8 bit 特征图数据与相应的N个8 bit 权重数据对应相乘,然后将这N个结果累加起来加上偏置后送入Batch Normalization 模块进行归一化计算,然后输出。
Fig.7 PE module图7 PE 模块
3.4 卷积运算并行化
卷积运算是CNN中所占计算量最大的部分,实现卷积并行计算将会显著提高CNN 的计算效率,以3×3卷积核为例,本文使用了四层循环的算法实现了卷积并行优化。其中输入的特征图数据大小为Fx×Fy,卷积核大小为Kx×Ky,通道数为C,卷积核数量为K。
(1)第一层循环
第一层循环如图8 所示,16个PE 单元从权重buffer 中取16个卷积核N个通道方向的第一个像素点分别与输入特征图N个通道方向的第一个像素点相乘,然后在通道方向上累加,输出结果。
(2)第二层循环
第二层循环如图9 所示,在这一层循环中,PE 单元中的权重数据不变,通过在特征图上滑动,得到卷积核N个通道的第一个像素点与部分特征图相乘并在通道方向上累加的结果。
(3)第三层循环
Fig.8 The first loop of convolution operation图8 卷积运算第一层循环
Fig.9 The second loop of convolution operation图9 卷积运算第二层循环
Fig.10 The third loop of convolution operation图10 卷积运算第三层循环
第三层循环如图10 所示,这一层循环是通过改变PE 单元中的权重数据,使乘法运算覆盖整个卷积核以及整个特征图数据,得到3×3 卷积核N个通道方向上所有像素点与整幅特征图相乘并在通道方向上累加的结果。在这一层运算中通过从片上存储取出中间结果送入加法器,完成与3×3 卷积核9个权重数据相对应的特征图数据在时间方向上累加。
(4)第四层循环
第四层循环如图11 所示,这一层循环是在上一层循环的基础上,卷积核与输入特征图分别在通道方向上取下一组N个通道,然后重复上面3个循环的操作。
3.5 池化模块
Maxpooling 运算过程如图12 所示,通过滑动窗口将输入特征图划分为多个不重叠的图像块,图像块大小为n×n,其中n由滑动步长决定,然后对每个图像块求其最大值,使得输出图像长和宽方向都缩小为原来的1/n[20]。
本文设计池化模块支持2×2 窗口大小的Maxpooling 和3×3 窗口大小的Maxpooling 两种模式,为了提高池化模块的计算效率,该模块设计为由16个单独的池化模块组成,16个池化模块并行计算以达到提高计算效率的目的。单个池化模块结构如图13所示,包括一个数据比较器、一个计数器和两个先进先出存储器(first input first output,FIFO)模块,其中数据比较器负责将输入的数据依次比较,得到最大值结果,计数器负责记录输入比较器的数据个数,FIFO 模块负责输入输出数据缓存。对FIFO 模块的满信号进行了特殊处理,当输入数据达到FIFO 最大数据量的一半时,FIFO 满信号便拉高,这样的设计有效防止了由于数据请求延迟而导致数据丢失的情况。池化模块计算过程为:
(1)每个池化模块通过地址控制器2 从片上存储中取出卷积层运算后的数据存入FIFO 中等待进行Maxpooling 运算。
(2)第一次计算时,计数器计数为1,此时将输入FIFO 中的第一个数据存入寄存器延一拍,然后与第二个数据同时送入比较器进行比较得到较大值。
(3)将得到的较大值与FIFO 中下一个数据进行比较。每次从FIFO 中取两个数据送入比较器,以此类推,直到计数器值为n(n为池化窗口大小),此时池化模块计算完毕得到最终结果值,每n+1个时钟周期可以计算出16个Maxpooling 结果。
Fig.11 The fourth loop of convolution operation图11 卷积运算第四层循环
Fig.12 Maxpooling operation图12 Maxpooling 运算过程
Fig.13 Pooling module图13 Pooling 模块
3.6 存储结构
存储分为片上存储和片外存储,在FPGA 中片上存储主要使用块随机存储器(block RAM,BRAM),特点是存储量小,但是读写速度快。片外存储主要使用动态随机存取存储器(dynamic random access memory,DRAM),特点是存储量大,但读写速度较慢[21]。卷积神经网络计算过程中数据量很大,因此难以将全部数据放入片上存储,同时卷积计算过程中会产生中间结果,从相关的研究中可以看出,如果全部存储到外部DRAM 中对计算速度的影响较大[8]。因此本文设计了片外存储加片上存储的结构。先将图像数据和卷积核数据存储在DRAM 中,开始运算后通过DMA 将图像数据传送到片上存储中,然后参与运算。对于参数量较小的网络,在预处理时可以将整张图像存入片上存储。对于参数量更大的网络或更高分辨率的输入图像,无法将全部图像一次存入片上存储,可以将图像拆分成小块再送入片上存储进行计算。
权重数据存储在PE 内部的权重buffer 中,权重buffer 使用乒乓存储结构。在进行现在的运算时,DMA 会提前将下一个权重数据存入权重buffer,这样的设计防止了计算单元由于等待数据搬运而闲置,提高了运算效率。
指令数据存储在指令RAM 中,指令RAM 也采用了乒乓存储结构来提升效率。
3.7 数据复用分析
重复使用特征图和权重数据可以减少读取片上存储的次数。相关文献研究中总结出了可以进行数据复用的两种方式,即空间方向的数据复用和时间方向的数据复用。空间方向的数据复用意味着,从片上存储读取数据后,在同一个时钟周期,该数据被用于多个并行运算单元。另一方面,时间方向的数据复用意味着取到的数据用于多个连续的时钟周期[22]。本文设计的加速器通过采用片上存储和权重buffer的方式在进行卷积运算中同时实现了两种类型的数据复用。
对于特征图数据来说,本文支持了空间上的复用,从片上存储到特征图数据,在同一时间周期被16个PE 模块所共享。对于权重数据来说,本文实现了时间上的数据复用,权重数据存入权重buffer 后,在接下来的连续时钟周期内,权重数据不会改变,直到这一权重数据与图像上所有对应的点都计算完成后再读取下一个权重,这样的方式让每一个存入权重buffer 的权重数据都做到了最大化的数据复用。通过以上数据复用策略,减少了加速器的带宽需求以及存储占用,有效提高了运算效率。
4 实验结果分析4.1 实验平台
本文实验使用Xilinx 公司的Vivado 进行硬件开发,Synopsys公司的VCS进行仿真。FPGA使用Xilinx公司的Virtex-7 2000T,工作频率达到了152 MHz。实验采用的测试集是ImageNet数据集中100张224×224大小的图片,图片精度为8位定点数,所用CNN网络为VGG16,实验对比方面,CPU采用主频为3.6 GHz的i7-6850K 处理器,GPU 采用NVDIA 公司生产的NVDIA GTX 1080Ti,其带宽为484 GB/s,显存为11 GB。
4.2 实验结果
本文研究了加速器的性能功耗比与N值的参数以及片上存储大小的关系,从图14 中可以看出,N值越大,加速器的运算单元越多,其性能功耗比越大,因此所设计的加速器在高端FPGA 上相比低端FPGA 更能发挥优势。片上存储方面,在片上存储小于3.5 MB 时,片上存储值的增大,性能功耗比越强,当片上存储大于3.5 MB 后,性能功耗比随着片上存储值的增大反而减小。这是因为在片上存储比较小时,中间参数无法全部存入片上存储,需要分块存入处理,这影响了加速器的计算性能,当片上存储足够将所有中间参数存入时,片上存储的增大不再对加速器性能产生影响,但随着片上存储的增大,FPGA的功耗会增大,因此性能功耗比会有所下降。
Fig.14 Accelerator performance power ratio vs parameters图14 加速器性能功耗比与参数关系
图15 中列出了FPGA 的资源使用情况,所用的片上存储大小为3.5 MB。在N=32,64,128 条件下,BRAM使用率均为72%。乘法部分运算逻辑全部使用DSP 资源,使用率分别为25%、48%和95%。Register分别使用了4%、6%和9%,查找表(look-up-table,LUT)分别使用了17%、29%和52%。
Fig.15 FPGA resources utilization图15 FPGA 资源占有率
表2 列出了各平台对于CNN 计算的性能以及功耗方面的对比,所用网络为VGG16,对比数据中本文所设计加速器以及CPU、GPU 图像数据和权值数据均为8 位定点数。从表中可以看出,本文所设计的加速器相对于CPU 在计算速度方面有着明显的提升,达到了560.2 GOP/s,为CPU 的8.9 倍,相对于GPU 虽然在计算速度方面没有优势,但性能功耗比达到了GPU 的3.0 倍。相比其他FPGA 进行CNN 加速的研究可以看出,本文的设计在性能功耗比上相比文献[10]、文献[23]、文献[16]有着明显优势,对于文献[8]所提出的设计,本文的设计在性能功耗比方面存在一定的差距,但文献[8]使用的Intel Arria10 GX1150系列高端FPGA,采用20 nm 工艺,相对于本文所使用的28 nm 工艺,FPGA 在性能和功耗方面存在着天然的优势。综上,本文所设计的加速器在对主流CNN网络进行推理计算的性能和能效上,利用较为低端的硬件实现了比大多数方案更好的效果,同时不乏通用性。
Table 2 Accelerator performance power consumption comparison table表2 加速器性能功耗对比表
5 结束语
本文提出了一种基于FPGA 的卷积神经网络加速器,整体架构使用了流水线技术以及片上存储结构,卷积运算方面实现了四个维度的卷积并行运算以及有效的数据复用策略,支持参数化设计。在三种参数下单个时钟周期分别可以进行512、1 024、2 048 次乘累加。用VGG16 网络对本文的设计进行了实验,并与CPU、GPU以及文献中相关设计方案进行了对比,实验结果表明,本文所提出的设计计算速度达到了i7-6850K CPU 的8.9倍,计算能效达到了NVDIA GTX 1080Ti GPU 的3.0 倍。与其他FPGA 加速器设计方案相比,本文所设计的加速器在主流CNN网络计算上实现了较高的性能功耗比,同时兼顾了通用性。
本文所研究的重点在于加速器整体架构设计,并未对FPGA 资源利用方面进行很好的优化,没有最大限度地发挥本文实验中所用FPGA 的全部资源。未来工作中可以对FPGA 的资源进行更为细致的优化,例如用灵活运用LUT 来代替部分DSP 资源,以最大化地发挥FPGA 的计算能力。