孫 明,陳 昕
同濟大學 電子與信息工程學院,上海201804
卷積神經網絡是一種以特征提取為主要方式的深度學習算法,被廣泛用在圖像分類、對象檢測和語義分割等領域[1]。但其參數過于龐大,運算過程需要使用大量的算力。適用于CNN 高密度計算的主流硬件有GPU、ASIC和FPGA[2]。與前兩者相比,FPGA作為并行化的計算密集型加速硬件,功耗低、可靈活編程、開發周期短,在加速CNN上,獲得了更廣泛應用。
研究人員主要集中在兩方面優化:減少所需的內存帶寬和降低推理計算復雜度。Chung等人[3]采用了將奇異值分解與剪枝方法組合使用的方案來對模型進行壓縮,從而減少網絡參數。Zhang等人[4]提出一種Caffeine框架,將卷積和全連接運算轉換為通用矩陣相乘,實現了100 倍性能提升。Liang 等人[5]和Prasanna 等人[6-7]采用快速算法Winograd 和FFT 將卷積變換到特殊域(如頻域)完成,將乘法數量減少到n2。Alwani 等人[8]采用fusion計算模式逐層推理,減少高達90%的片內外傳輸。上述方法存在以下問題:對模型修剪[3]或卷積層融合[8]時,雖減少了內存用量和降低帶寬壓力,但片上計算資源利用率低;并行計算程度較高[4]或降低運算復雜度[5-7],但造成冗余數據復制,對片上緩存容量要求高。
本文旨在克服上述不足,主要貢獻如下:
(1)對卷積6 個循環進行設計空間探索,以確定循環分塊因子,提高數據復用程度以減小帶寬需求。
(2)通過展開分塊充分挖掘4 種計算并行度:層間并行、層內并行、核間并行、核內并行。
(3)將加速方法包裝成RTL 組件,向外提供Python接口,給定器件規格和網絡配置,可實現深度學習加速算法到板級FPGA部署的自動代碼生成。
本文第1章描述了CNN加速框架設計流程和CNN加速器整體架構;第2章詳細介紹了具體加速方法;第3章展示了實驗結果;第4章得出了結論。
如圖1 所示,本設計流程可分為訓練和生成兩步,前一步的輸出作為后一步的輸入。

圖1 CNN加速框架設計流程圖
訓練階段:與卷積神經網絡訓練過程相同,對于一個目標網絡.prototxt,用戶采用caffe 在CPU 或GPU 上進行反向傳播,當迭代次數達到給定值或驗證集準確率符合期望時,得到訓練后的權重文件.caffemodel。
生成階段:首先對前一階段的權重信息文件.caffemodel 和網絡模型定義文件.prototxt 進行解析,獲得各層類型(如:Conv、Activation、BN、Shoutcut等)和卷積核尺寸,將網絡各層進行模塊化分解,映射到對應的預制IP庫中各RTL塊(如乘累加器、循環計算模塊、激活函數模塊、數據流控制器、輸入輸出處理模塊等),通常情況下,一個卷積層由多個基本RTL組件構成。在優化階段,基于設計空間探索,對實現卷積計算的6 個循環進行分塊,并將循環分塊展開(詳見第2 章),本過程是生成加速器的核心,此外,還對整體網絡層的流水線進行了細粒度優化,在同一時間點各層也能進行同時計算。進入組件整合階段,生成器將預構建的各RTL 網絡組件、各層數據流控制器、讀寫控制模塊等進行組裝以形成CNN實現,各個模塊或組件均是高度可重構,以確保對不同結構的CNN 的適應性和擴展性。最后,在代碼生成階段輸出適用于目標FPGA 開發板的CNN 加速器的Verilog代碼。
若綜合和實現后,當前CNN 時延過大或各層的BRAMs 數/DSPs 數比率差異大等,用戶可更新網絡設計,例如修改網絡層、更換位寬量化策略、改變計算并行度等,經過訓練和生成的幾次迭代,最終的網絡配置結構和優化方法能契合預期性能。
生成的加速器總體架構如圖2所示,采用層并行模式。主要包括卷積計算引擎、片上緩存、外部存儲、內部互聯總線、多個控制器等。片外DDR 用于存儲訓練好的模型參數和初始輸入圖片、推斷結果。片上緩存包括各個權重緩存單元和輸入輸出緩存池,用于保存通過DMA 讀取的權重值、各層輸入輸出特征圖和中間計算結果。卷積計算陣列,由多個處理單元組成,每個處理單元的構成元素是級聯的乘累加器,負責并行計算。互聯總線用于前后層的控制信號傳輸??刂破髫撠熅W絡各層計算順序和緩存流向。

圖2 生成的CNN加速器概覽
運算過程中,在將圖片像素從片外DDR 中讀入計算陣列前,先將各層的權重通過DMA 控制器讀到權重緩存中,若參數量小,則一次性將其全部保存,運行過程中不再傳輸權重,當參數規模較大則需要實時傳輸。之后,啟動PE 陣列計算。為達到高效計算和節省ROM/RAM資源,配置兩個片上緩存池,各層在輸入和輸出緩沖池中均有兩個可重用的乒乓緩沖區,緩沖區的數量小于層數,通過覆蓋計算時間來避免加/卸載數據所需要的時間開銷。緩沖控制器負責輸入和輸出緩沖池中的數據讀取寫入,上層輸出緩存區中的寫入數據即為本層待輸入的特征圖。結合卷積計算的循環分塊技術,在得到部分輸出結果時,即可開始下一層運算,主控制器用來支持整個網絡的細粒度流水線順序。
CNN 網絡中卷積計算可視為一個多維嵌套循環,如圖3所示。其中Rin=(Rout-1)×S+K,Cin=(Cout-1)×S+K。

圖3 卷積層偽代碼
采用分塊技術分割循環中的迭代空間可有效緩解片上內存緊張,而可行的分塊維度包括平面卷積窗口運算(K×K)、輸出特征圖尺寸(Rout×Cout)和輸入輸出通道數(M×N),因為K值一般都很小(通常為[3,11]),故采用對后兩個維度進行分塊操作,如圖4所示。

圖4 循環分塊原理圖
其各維度對應的分塊尺寸為Tro、Tco、Tn、Tm完成一個卷積層的執行周期數為:

未分塊的圖3所示的卷積層所需的操作總數為:

在采用后續的循環展開操作以及忽略流水線開銷的影響時,Rooflinemodel[9]中的ComputationalRoof 可由下式計算:

而對于具有Npe個處理單元的計算通路,通常有如下限制條件:

最優的架構是最大化ComputationalRoof,等效于最小化執行周期數。
在采用w位寬量化策略時,圖4中循環分塊對輸入輸出特征圖和權重緩存尺寸的要求為:

其中BRAMcapacity為片上內存容量。
分塊后需要對輸入輸出特征圖和權重進行片外讀取的次數為:

Computation to Communication(CTC)ratio 用來表征每次內存訪問能支持的計算操作數量,是衡量數據重用水平的一個指標,其定義如下:

由公式(3)和公式(10)可得出,在給定分塊策略
由于生成的加速器采用層間流水線架構,為達到最大吞吐量性能,在考慮各層復雜度、數據重用行為的情況下,需使各流水線段的負載平衡,以使時延大致相等[10]:

其中Ci代表層i的計算復雜度(見公式(2)),Ri表示層i所消耗的計算資源(公式(4)乘以每個PE 所需DSP 數量),片上可用的計算計算為Rtotal,而層i的時延Di為:

其中λ是與硬件工作頻率有關的常量。網絡整體吞吐量受限于具有最大計算時間的卷積層:

因此,本加速器采用公式(12)~(15)指導網絡對各層進行計算資源分配。
經過循環分塊后,圖3 最里層的6 個小循環所涉及的計算任務不僅具有數據來源的相關性和結果的獨立性,而且被劃分為更小的計算單元,完全可能在片上實現并行化計算,使資源和帶寬得到更充分利用,如圖5~8所示。

圖5 層間并行
圖5展示了層間并行,以分塊為基本流水段的細粒度流水線可以實現同一時間段所有層的并行計算,減小了啟動延時。圖6中是層內并行,該并行是通過輸入像素復用實現的,當計算輸出特征圖像上不同通道相同位置的區域,所需要的輸入特征圖像數據是固定區域,唯一的區別是各個輸出通道對應的卷積核不相同,該種并行度為Tn×Tm。圖7 描述了核間并行,該并行是通過權重數據復用實現的,輸出特征圖像中的同一個通道的不同位置像素,所使用的是同一組權重數據,對應該種并行度為Tro×Tco。圖8 是核內并行,輸入特征圖每一通道的卷積窗口與對應卷積核平面計算涉及大量乘加操作,這些運算都是可并行的,并行度為K×K。

圖6 層內并行

圖7 核間并行

圖8 核內并行
本加速器計算引擎采用上述4種并行性后的結構,如圖9所示。圖中,Pix和W代表像素和權重,一個乘法器和一個加法器組成一個基本處理單元,后面連接一加法器樹。每個灰色填充區域代表一個卷積窗口和對應卷積平面點乘,對應核內并行;Tn個灰色區域為一組,用黑色實線框住,可以生成一個輸出像素值。而紅色虛線包圍的計算處理引擎共享相同的特征圖像數據,能夠實現層內并行,Tm×Tn×K×K表示小工作集像素值復用和核內并行下的乘法器個數,可同時生成Tm個輸出像素。左邊藍色虛線區域的處理引擎不同的像素值與相同的權重相乘,實現了核間并行,Tro×Tco×Tn×K×K表示小工作集權重復用和核內并行下的乘法器個數,可同時生成Tro×Tco個輸出像素。

圖9 全并行模式下的計算引擎結構
本文實驗首先在ubuntu18.04 系統和python2.7 環境下,采用caffe 訓練AlexNet[11]網絡模型,將訓練后的權重.caffemodel、網絡定義文件.prototxt 以及FPGA(Virtex7 690t)各資源參數值作為CNN 加速框架輸入,得到分割并轉換后的各層權重二進制.coe文件、加速器verilog 源代碼和仿真測試數據。之后在ubuntu14.04 系統和vivado2013.4的非工程模式下,調用其multiplier和ROM/RAM memory IP 核生成用于各層乘加運算和存儲結果的模塊。最后,在配備有Intel i5-7400 CPU,顯卡為HD Graphics 630的Win10系統下,通過vivado2018.3和modelsim10.1c 的聯合仿真(200 MHz 工作頻率)、綜合及布局布線,實現了3個網絡的正向傳播??紤]到過度參數化的CNN 模型中存在大量冗余連接[12],為了有效減少片內外存儲需求,加速器使用動態4-8-16位量化策略,top-5準確率僅下降不到2%。
根據FPGA(Virtex7 690t)的硬件資源參數值和AlexNet模型的網絡配置,CNN加速框架輸出verilog語言形式的CNN 加速器。采用Vivado2018.3 工具集完成布局布線和仿真,得到圖10 中的AlexNet 加速器,圖11是圖10 中的第五個卷積層結構的原理圖,可見加速器的整體架構采用層并行模式以層間流水線形式存在,各卷積層IP通過由乘累加器組成的vector_muladd模塊實現并行計算。表1 顯示了部署后的資源利用率和實現性能,加速器高效地利用了FPGA的硬件資源。在批處理尺寸為11,采用4-8-16 位動態精度數據量化策略[13],工作頻率為200 MHz時,每秒能處理93.7張227×227×3的圖像最高可達1 493.4 Gops 計算峰值,而僅使用了2 562 塊DSP 和688 塊BRAM 參與前向推理,分別占用片上存儲和計算資源總數的46.8%和71.2%。

表1 Virtex7 690t@200 MHz下實驗結果

圖10 AlexNet網絡加速器原理圖

圖11 卷積層結構原理圖
本文對關鍵資源DSP 的利用效率進行了評估。引入DSP 效率來表示參與運算的DSP 的實際與理論最大性能的比率,定義為:

當采用定點數16,8,4 時,β=2,4,8,表示一個DSP 與其相應的邏輯單元在一個時鐘周期可進行的算術操作次數[10]。DSP_num×freq×β是在給定頻率下,所有DSP能達到的理論最大算力,分子Perf.為表1 中的實際性能。因為其不依賴于FPGA 平臺的片上DSP 數量且消除了時鐘頻率的影響,可以對使用不同FPGA 平臺和CNN模型的并行優化算法進行公平比較。表中顯示在Virtex7上DSP的效率高達0.73(Ops/DSPs/cycle)。
令DW/DP 表示,位寬為DW 的數據定點量化后小數點位置為DP。表2列出了主導計算的層的數據量化情況。

表2 關鍵層的輸入輸出與權值量化
未列出的層(如池化等)輸出與輸入量化保持一致。圖12是文獻[14]多次訓練后得出的AlexNet預測準確度top-1 和top-5 隨網絡量化位寬的變化曲線(訓練后,各層權值截斷至相同位寬)??梢?,當精度下降到8 bit 以下,準確度急劇下滑,但考慮到全連接層權重密度大、數值小和存在冗余連接多,本策略仍然對全連接層權值采用較激進的4 bit位寬。與采用32位浮點方案相比,本方案在Ristretto caffe[15](caffe的擴展,可以有限數據精度訓練、微調和測試網絡)訓練后的top-1和top-5準確度下降幅度均在2%以內,分別為從55.7%下降到53.9%,79.0%到77.9%。

圖12 預測準確度與網絡量化位寬關系
進一步針對于具體圖像采用上述量化方案在FPGA上正向傳播過程中產生的誤差進行分析,由于AlexNet層數較多,圖13 僅展示Conv1 第一個特征圖和最后一個全連接層Fc8的輸出情況。

圖13 Conv1和Fc8的輸出
從圖3可定性得出,真實數據(caffe浮點數輸出)和仿真數據(modelsim10.c定點數輸出)的分布基本一致,將仿真數據減去真實數據可得誤差值的分布情況,如圖14所示。

圖14 Conv1和Fc8的誤差分布
定義公式(17)對誤差定量分析:

sim、real分別表示各層特征圖像素的仿真和真實數據值,可得Conv1第一個特征圖和Fc8輸出的誤差分別為0.001 101、0.002 413。仿真數據與真實數據的差值很小,誤差影響可忽略。同理,介于Conv1 與Fc8 之間的隱藏層情況類似,網絡整體的平均量化誤差為0.003 2,說明上述的量化策略可取。
動態4-8-16位量化策略可有效減少存儲需求:
(1)片外DRAM 用于存儲源圖像、AlexNet 權重和推理結果,表2 顯示,輸入特征圖和網絡推理結果量化為16 bit,而卷積層和全連接層權值分別量化為8 bit和4 bit。AlexNet 一共有60 965 224 個可訓練參數,輸入為標準227×227×3彩圖,輸出是1 000個分類概率,當采用4-8-16 量化策略后,加速器對片外存儲空間需求從244 483 244 Byte(233.2 MB)下降到31 960 826 Byte(30.5 MB),節省87%的DRAM存儲。
(2)片上RAM/ROM 用于保存推理運行中的權重、中間結果和各層輸入輸出特征圖,本加速器采用層并行模式下的細膩度流水線架構,乒乓緩存數據傳輸,僅需獲得上層輸出的部分分塊數據和部分權重即可開啟本層運算,對片上內存需求大大減少。圖15 比較了本文片上內存管理方法與傳統設計(特征圖和權重完全保存)對BRAM需求的差異。

圖15 本文方法與傳統設計的內存需求比較
從圖15 可知,本加速器部署前8 個卷積和池化層,使用394個BRAM,而傳統的將特征圖和核權重全部存儲在片上的方法,使用1 915 個BRAM。傳統設計比本文方法最低多消耗1.34倍存儲資源(pool5),最高為6.21倍(conv4)。最后3個全連接層占據了96%的權重,傳統設計方法無法一次性將其保存至片上,故本文未對其加以分析,而在細膩度流水線架構和輸入輸出緩存池技術下,本方法在Fc6、Fc7、Fc8 層分別僅消耗166、68、43 個BRAM,至少會節省80%存儲資源。
進一步地,探究了在本文內存管理方法下,數據有無進行動態4-8-16位精度量化對內存需求的變化,如圖16所示。

圖16 兩種量化方案對內存需求的差異
在32位浮點情況下,AlexNet加速器需要占用2 552個BRAM,是4-8-16位量化的3.81倍。注意到,3個全連接層Fc6、Fc7、Fc8 的壓縮比率較高,分別為5.35、5.49、3.81 倍,主要原因是全連接層存在大量冗余連接,權值接近0,采用較激進的4 bit量化可在不降低推理準確度的前提下減少片上存儲壓力。
Zhang等人[9]在Intel Xeon CPUE5-2430上運行AlexNet模型中,開啟多線程執行,在103.48 ms 內完成正向傳播,達到12.84 Gops的峰值性能。從Nvidia官方文檔可知,采用16 位浮點,批尺寸為2,AlexNet 模型在GPUTX2[16]上的幀率為250 frame/s。圖17比較了CPU、GPU與FPGA在計算性能上的差異。本文設計的AlexNet加速器在FPGA 上的計算性能分別是CPU 和GPU 上的115.8 倍和4.1 倍,一方面是因為FPGA 更適合計算密集型任務,另一方面是本加速器更充分挖掘了CNN 可并行計算的空間和進行了有效內存管理。

圖17 CPU、GPU與FPGA之間的性能比較
此外,本文將Virtex7 690t上的加速器實驗結果與3個最近的具有分類功能的基于FPGA 的CNN 加速器進行比較,如表3 所示。在Virtex7 690t 上達到的峰值性能為1 493.4 Gops,比其他3個參考結果都要高,最低為4.2 倍,最高達到24.2 倍。由于不同的實驗利用不用規所格示的。FPGA 平臺,所使用的CNN 模型和時鐘頻率也不一樣,為了能公正客觀衡量各個設計方法的優劣,下表進一步列出了DSP效率,其用來評估每一個參與運算的DSP利用的充分程度。

表3 與基于FPGA的CNN加速器的比較
在Virtex7 690t 平臺,本文設計方法的DSP 效率均比其他文獻中采用的方法要高,分別是他們的1.7 倍、2.6 倍和1.2 倍。說明本加速器采用的方法能提高硬件資源利用率和數據重用機會,充分挖掘了FPGA并行計算能力。
本文提出一個針對卷積神經網絡加速的CNN加速框架,生成的加速器可實現高性能和高效率。為了提高計算吞吐量,采用基于設計空間探索的方法確定卷積分塊因子,并將分塊進行展開,從而提高計算并行性。該方法可增大CTC 率,減少外部存儲訪問帶寬需求,提高數據復用程度。對整個網絡采用細粒度流水線架構,考慮到有限的片上內存容量,用內存池、乒乓緩存和4-8-16位精度量化策略進行數據傳輸,以減少啟動和輸出延時?;谏鲜龅脑O計方法,與其他基于CPU/GPU/FPGA的方法相比,本文達到了最高吞吐性能峰值1 493.4 Gops,DSP效率超過了其他設計方法,本文加速器高效且性能優異。