目录
Abstract
CNN通过仿效生物的视神经达到了高的准确率。基于深度学习算法的应用的快速发展,进一步完善了研究和实现。特别是大量基于FPGA平台的为CNN设计的加速器被提出,因为它有着高性能、可重构行、快速发展的优势。尽管现代的FPGA加速器已经在一般的处理器上证明了自己的高性能,但是设计空间还没有被充分利用到。
一个关键问题就是计算吞吐量和FPGA平台提供的内存带宽不匹配。结果就是现在的方法不能达到最好的效果。与此同时,深度学习应用的日益增长的复杂度和规模加重了这个问题。为了解决它,作者提出了一种分析设计方法,使用了roofline model。对于一个CNN的任何解决方案,都能量化分析它的计算吞吐量和需要的内存带宽,然后通过roofline model,确定性能最好的方案和最少的FPGA资源。作者还实现了一个样例,显著地战胜了现有的方案。
问题:什么是roofline model?(在background里面有)
Introduction
CNN是受到了生物视神经的激发,一个CNN的设计是通过多层神经元的连接来处理数据,以求在图像识别中达到高的性能。基于CNN的特殊计算模式,通用处理器对CNN的实现效率不高。所以大量基于FPGA、GPU、ASIC的加速器被提出了,用来提高CNN设计的性能。其中,FPGA加速器很受重视,因为其在高性能、高能量效率、快速发展、强重构能力方面都有显著优势。
对于任何一个CNN算法的实现,许多的解决方案给出了巨大的设计搜索空间。如果没有好的加速器结构,CNN的性能就会因为逻辑资源、内存带宽的未充分利用而退化,所以设计加速器的结构很重要。
另外,由于FPGA技术和深度学习算法的提升,FPGA平台提供的逻辑资源和内存带宽的增长,导致设计空间变大。另一方面,算法的规模和复杂度在不断提升。结果就是:在设计空间中找到最优解越来越难。所以就需要一个有效的方法来探索基于FPGA的CNN设计空间。
本文的主要贡献:
- 量化分析了任何可能的解决方案的计算吞吐量和需要的内存带宽。
- 在计算资源和内存带宽的限制下,使用roofline model来确定设计空间中所有可能的解。并讨论了:如何为设计空间中的每一层来找最优解。
- 提出了一种CNN加速器设计,在不同层具有均匀的环展开因子。
- 实现了一个加速器作为样例,是现有方案中最好的。
问题:
什么是逻辑资源? logic resource
什么事是内存带宽? memory bandwith
什么是环展开因子? loop unroll factor
Background
CNN Basis
这里就是介绍了一下CNN。
CNN作为经典的监督学习算法,使用一个前馈过程去识别,使用反馈过程去训练。本文主要是聚焦于加速前馈计算——基于FPGA加速器设计。
典型的CNN由两部分组成:特征提取器和识别器。(feature extracter, classifier). feature extracter 主要是将输入的图片进行特征提取为特征图。这些特征包括角、边、圆形结构,且对于位置变化或者是形变不敏感。feature extracter输出一个包含这些特征的低维向量给classifier,它决定图像属于各个类的可能性。
考虑到卷积操作占用了90%的计算时间,所以本文主要是研究如何加速卷积层。
A Real-Life CNN
这里就举了AlexNet的例子。
the Roofline Model
在系统的吞吐量优化问题中,计算和通信是两大只要限制。(computation,communication)。一个系统的实现,可能是计算绑定或者通信限制。而roofline model,则将系统的性能和off-chip memory traffic(芯片外的内存流量)、硬件平台提供的峰值性能联系起来。
具体的联系就是下面的公式和图:
attainable performance就是系统能获得的浮点型能——对应吞吐量指标。它不大于后面两个术语的最小值。第一个术语Computational Roof描述的是系统中可用的计算资源提供的峰值浮点吞吐量。第二个术语CTC ratio以一个特定的系统中,核所需要的DRAM流量作为特征。二项限制了内存系统在给定计算与通信比率下可以支持的最大浮点性能。也就是说如果通信过多,则浮点性能被严重限制。
问题:
什么是浮点性能? floating-point performance:被用来当做吞吐量指标了。
Accelerator Design Exploration
Design OverView
基于FPGA的CNN加速器设计由几个主要部分组成:procesing elements, on-chip buffer, external memory, on/off-chip interconnect. PE是卷积的基本计算单元。所有要处理的数据都存储在external memory中。由于on-chip resource的限制,数据在被送到PEs前,先被cached到on-chip buffer上。我们注意到这里有两个buffer,可以用data transfer time 去Cover computation time。On-chip interconnect 是专门用来在PEs和on-chip buffer之间做data communication(数据通信)的。
一个加速器设计总览图:
关于加速器效率这方面,有如下几个棘手的问题:
(1)loop tiling的重要性。而且tiling必须设置合适,否则会降低数据的重复使用和并行处理的效率。
(2)PEs、buffer banks的组织和它们之间的interconnects需要认真考虑以高效处理on-chip datas.
然后在后面的部分中,将介绍作者为提高加速器效率而采取的措施。
有关循环分块(loop tiling)的理解在这:https://zhuanlan.zhihu.com/p/292539074
loop tiling的基本思路很简单,就是一个cache line现在被用过以后,后面什么时候还会被用,但是按循环默认的执行方式,可能到下次再被用到的时候已经被evict了。于是我们就把循环内外重排一下,使得一个cache line在被evict之前就被再次使用。
Computation Optimization
使用了一种名为standard polyhedral-based data dependence analysis的方法来提取一系列的合法设计参数(具体是哪些参数后面会说)。计算优化的目的是在充分利用fpga平台提供的所有计算资源的前提下,启动有效的loop unrolling/pipelining.
Loop Unrolling:可以提高对FPGA设备上大量的计算资源的使用率。 对于不同的循环维度的展开,将产生不同的实现模型。展开后的实例能够共享数据。两个unrolled execution instances之间是否以及在何种情况下共享数据,将会很大程度上影响生成的硬件的复杂度、性能。对于一个给定的数组上的循环维度(loop dimension),不同的loop iterations之间的数据共享关系可以分为三大类:
(1)Irrelevant:如果loop iterator i 不出现在向量A的任何访问函数中,则相应的循环维度与A毫不相干。
(2)Independent: 与dependent相反。
(3)Dependent. If the union of data space accessed on anarray A is not separable along a certain loop dimension
i
k
i_k
ik, the loop dimension ik is dependent of array A.
不同的数据分享关系,得到不同的硬件实现,如图:
independent数据共享关系在buffers和PEs之间产生direct connections,irrelavant产生broadcast connections。dependent产生具有复杂拓扑结构的连接。
问题:
(1) loop dimension:比如for(i=0;i<5;i++),这就是一个循环维度。
(2) loop iteration:这里理解为进行循环的参数。比如for(i=0;i<5;i++),那么i为loop iteration。
Loop Pipelining:重叠来自不同循环迭代的操作执行来提高计算吞吐量。基于多面体的优化框架,将并行循环级别排列到了最内层。代码结构图:
可以看到,最内层的循环i和j也加入了tiling,运算进一步高效。
Tile Size Selection:不同的tile size将导致不同的芯片性能。所有合法的参数设计应该满足:
给定一组参数
<
T
m
,
T
n
,
T
r
,
T
c
>
<T_m, T_n, T_r, T_c>
<Tm,Tn,Tr,Tc>,对应的计算性能(或者说是roofline model里面的Computational roof)是可以由
<
T
m
,
T
n
>
<T_m, T_n>
<Tm,Tn>表示的,有公式:
看起来, < T m , T n > <T_m, T_n> <Tm,Tn>需要越大越好。
Memory Access Optimization
在内存带宽的限制下,有着高computatioanl roof的模型不一定就能获得最佳的性能。这一部分主要讲如何通过有效的数据重复利用来降低数据通信量。
Local Memory Promotion:使用本地存储推动,能够减少不同loop iterations之间的冗余操作。最后会大大减少内存访问操作的trip count。
Loop transformations for data reuse:为了在本地存储推进阶段,最大化数据重新使用的概率,作者提出了基于多项式的优化框架polyhedral=based optimization framework来识别所有的legal loop transformations.
CTC Ratio:Computation to Communication ratio可以用来每次内存访问的计算操作。数据复用可以降低内存访问次数,所以作者需要提高CTC。
使用
α
i
n
,
α
o
u
t
,
α
w
g
h
t
\alpha_{in}, \alpha_{out}, \alpha_{wght}
αin,αout,αwght和
B
i
n
,
B
o
u
t
,
B
w
g
h
t
B_{in}, B_{out}, B_{wght}
Bin,Bout,Bwght分别表示trip counts和buffer size,有:
问题:什么是trip count?
Design Space Exploration
从上面的分析可以看成,在给定
<
T
m
,
T
n
,
T
r
,
T
c
>
<T_m, T_n, T_r, T_c>
<Tm,Tn,Tr,Tc>之后,computational roof和CTC可以计算。列举所有的循环顺序和tile sizes可以得到一系列的结果。
这是一个不考虑具体实现平台的图。表示了Attainable performance随着CTC的变化。
这是一个考虑了具体平台的图。通过探索这种platform-supported design,可以得到一些性能最好的点。然后从中选择出CI值最高的点(使用了最小带宽),这就是最好的design。这里最终选的是C点而不是D点。
问题:什么是CI值?
Multi-Layer CNN Accelerator Design
前面的设计是基于CNN的某一层,下面进行expand。下表给出了5层CNN中两个参数的选择和对应的循环次数:
当然,去设计不同的unroll factors来支持不同的层,是一件很难的事情。复杂的硬件结构需要重构computation engines和interconnects。我们也可以设计简单的模型,使它具有统一的unroll factors,不过这样并非最优。上面的表中给出了当 < T m , T n > <T_m, T_n> <Tm,Tn>取到(64,7)时,性能的下降在5%以内,似乎能够接受。所以作者就选择使用统一的unroll factors来设计加速器。
Implementation Details
System Overview
一个系统的总图:
然后罗列了一下使用到的各种器件,包括DDR3 DRAM,MicroBlaze,etc。
Computation Engines
如图,展示了计算引擎的实现框图。两级的展开循环(
T
m
,
T
n
T_m, T_n
Tm,Tn)被实现为并行执行的计算引擎。
使用了这样的一个树状多边形结构:
对于(64,7)这样一组参数,计算引擎被实现为:每一个tree-shaped poly structure都有7个inputs来自输入特征图,7个inputs来自weights,1个input来自bias(这些存储在输出特征图的buffer中)。共有64个这样的结构。
问题:
什么是computation engines?就是专门处理数据的程序。比如人们常用数据库来处理数据,像SQL,它的背后正是数据库的计算引擎,但是数据库的计算和存储通常被集成在一起,称为数据库引擎。
其实我不是很理解那个树状多边形结构。。。
Memory Sub-System
on-chip buffers是基于double-buffering的想法建立的。这在乒乓操作中被应用,能重叠数据的交换和计算时间。布置了两个输入端的buffer,两个输出端的buffer。每个buffer包括一些buffer banks。输入端buffer的banks数量是
T
n
T_n
Tn,输出端则是
T
m
T_m
Tm。
然后是对时间图的理解:当输出缓冲区0在处理数据的同时,下一阶段需要处理的数据将被复制后进行缓冲区1.下一阶段,两个缓冲区的行为与上一阶段相反。
问题:
ping-pong operation:
如图,在两个模块交换信息时,通过加入了两个buffer,使得A在往一个buffer中写数据时,B可以读取另一个的数据。这样二者交换进行,都不用等待。
External Data Transfer Engines
可以在accelerator和external memory之间提供data transfer,可以使加速器的设计独立于平台而存在。
Evaluation
Experimental Setup
讲了实验的搭建环境。
Experimental Results
首先是比较资源利用率。比较了CPU上的软件实现和我们在FPGA上的加速器。资源利用率相当高。
然后是比较加速器和软件实现的性能。总的来说,加速器实现了17.42倍的加速(相比于1 thread的软件)。相比于16 thread,也实现了4.8倍加速。
使用了一个功率计来测量实现器件的功率。相比于软件实现,至少实现了24.6倍的功率降低。
最后,和其他基于FPGA的CNN加速器进行比较,有着很高的GOPS指标,实现了至少3.62倍的加速。
Related Work
前人也有一些基于FPGA的加速器设计工作。
一部分人是聚焦于优化computation engines。早期的方法是通过软件实现来构建CNN应用程序,同时使用一个硬件脉动架构加速器来完成滤波卷积工作。这种设计节约了很多硬件资源,被用到自动机器人的嵌入式系统中。一些工作实现了完整的CNN应用程序,但是使用了不同的并行计算。本文的方法使用了类似"inter-output" 和"intra-output"的并行,还使用了on-chip buffers来进行数据复用,这是前人没有的。
另一部分人考虑到数据通信问题,选择最大化数据的复用,最小化带宽需求。但是它们的方法没有考虑到最大化computation performance。
Conclutions
在本文中,作者提出了一种 roofline-model-based 方法,来进行卷积神经网络的FPGA加速。首先,优化CNN的computation and memory access。然后为所有可能的设计进行建模并为每层找到最好的设计。然后通过列举的方法,找到了最好的cross-layer design。最后在Xilinx VC707上实现了这个设计,超越了所有之前的工作。
Acknowledgment
感谢了来自各方面的支持。