孫 明,陳 昕
同濟大學(xué) 電子與信息工程學(xué)院,上海201804
卷積神經(jīng)網(wǎng)絡(luò)是一種以特征提取為主要方式的深度學(xué)習(xí)算法,被廣泛用在圖像分類、對象檢測和語義分割等領(lǐng)域[1]。但其參數(shù)過于龐大,運算過程需要使用大量的算力。適用于CNN 高密度計算的主流硬件有GPU、ASIC和FPGA[2]。與前兩者相比,F(xiàn)PGA作為并行化的計算密集型加速硬件,功耗低、可靈活編程、開發(fā)周期短,在加速CNN上,獲得了更廣泛應(yīng)用。
研究人員主要集中在兩方面優(yōu)化:減少所需的內(nèi)存帶寬和降低推理計算復(fù)雜度。Chung等人[3]采用了將奇異值分解與剪枝方法組合使用的方案來對模型進行壓縮,從而減少網(wǎng)絡(luò)參數(shù)。Zhang等人[4]提出一種Caffeine框架,將卷積和全連接運算轉(zhuǎn)換為通用矩陣相乘,實現(xiàn)了100 倍性能提升。Liang 等人[5]和Prasanna 等人[6-7]采用快速算法Winograd 和FFT 將卷積變換到特殊域(如頻域)完成,將乘法數(shù)量減少到n2。Alwani 等人[8]采用fusion計算模式逐層推理,減少高達90%的片內(nèi)外傳輸。上述方法存在以下問題:對模型修剪[3]或卷積層融合[8]時,雖減少了內(nèi)存用量和降低帶寬壓力,但片上計算資源利用率低;并行計算程度較高[4]或降低運算復(fù)雜度[5-7],但造成冗余數(shù)據(jù)復(fù)制,對片上緩存容量要求高。
本文旨在克服上述不足,主要貢獻如下:
(1)對卷積6 個循環(huán)進行設(shè)計空間探索,以確定循環(huán)分塊因子,提高數(shù)據(jù)復(fù)用程度以減小帶寬需求。
(2)通過展開分塊充分挖掘4 種計算并行度:層間并行、層內(nèi)并行、核間并行、核內(nèi)并行。
(3)將加速方法包裝成RTL 組件,向外提供Python接口,給定器件規(guī)格和網(wǎng)絡(luò)配置,可實現(xiàn)深度學(xué)習(xí)加速算法到板級FPGA部署的自動代碼生成。
本文第1章描述了CNN加速框架設(shè)計流程和CNN加速器整體架構(gòu);第2章詳細介紹了具體加速方法;第3章展示了實驗結(jié)果;第4章得出了結(jié)論。
如圖1 所示,本設(shè)計流程可分為訓(xùn)練和生成兩步,前一步的輸出作為后一步的輸入。
圖1 CNN加速框架設(shè)計流程圖
訓(xùn)練階段:與卷積神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程相同,對于一個目標(biāo)網(wǎng)絡(luò).prototxt,用戶采用caffe 在CPU 或GPU 上進行反向傳播,當(dāng)?shù)螖?shù)達到給定值或驗證集準(zhǔn)確率符合期望時,得到訓(xùn)練后的權(quán)重文件.caffemodel。
生成階段:首先對前一階段的權(quán)重信息文件.caffemodel 和網(wǎng)絡(luò)模型定義文件.prototxt 進行解析,獲得各層類型(如:Conv、Activation、BN、Shoutcut等)和卷積核尺寸,將網(wǎng)絡(luò)各層進行模塊化分解,映射到對應(yīng)的預(yù)制IP庫中各RTL塊(如乘累加器、循環(huán)計算模塊、激活函數(shù)模塊、數(shù)據(jù)流控制器、輸入輸出處理模塊等),通常情況下,一個卷積層由多個基本RTL組件構(gòu)成。在優(yōu)化階段,基于設(shè)計空間探索,對實現(xiàn)卷積計算的6 個循環(huán)進行分塊,并將循環(huán)分塊展開(詳見第2 章),本過程是生成加速器的核心,此外,還對整體網(wǎng)絡(luò)層的流水線進行了細粒度優(yōu)化,在同一時間點各層也能進行同時計算。進入組件整合階段,生成器將預(yù)構(gòu)建的各RTL 網(wǎng)絡(luò)組件、各層數(shù)據(jù)流控制器、讀寫控制模塊等進行組裝以形成CNN實現(xiàn),各個模塊或組件均是高度可重構(gòu),以確保對不同結(jié)構(gòu)的CNN 的適應(yīng)性和擴展性。最后,在代碼生成階段輸出適用于目標(biāo)FPGA 開發(fā)板的CNN 加速器的Verilog代碼。
若綜合和實現(xiàn)后,當(dāng)前CNN 時延過大或各層的BRAMs 數(shù)/DSPs 數(shù)比率差異大等,用戶可更新網(wǎng)絡(luò)設(shè)計,例如修改網(wǎng)絡(luò)層、更換位寬量化策略、改變計算并行度等,經(jīng)過訓(xùn)練和生成的幾次迭代,最終的網(wǎng)絡(luò)配置結(jié)構(gòu)和優(yōu)化方法能契合預(yù)期性能。
生成的加速器總體架構(gòu)如圖2所示,采用層并行模式。主要包括卷積計算引擎、片上緩存、外部存儲、內(nèi)部互聯(lián)總線、多個控制器等。片外DDR 用于存儲訓(xùn)練好的模型參數(shù)和初始輸入圖片、推斷結(jié)果。片上緩存包括各個權(quán)重緩存單元和輸入輸出緩存池,用于保存通過DMA 讀取的權(quán)重值、各層輸入輸出特征圖和中間計算結(jié)果。卷積計算陣列,由多個處理單元組成,每個處理單元的構(gòu)成元素是級聯(lián)的乘累加器,負責(zé)并行計算。互聯(lián)總線用于前后層的控制信號傳輸??刂破髫撠?zé)網(wǎng)絡(luò)各層計算順序和緩存流向。
圖2 生成的CNN加速器概覽
運算過程中,在將圖片像素從片外DDR 中讀入計算陣列前,先將各層的權(quán)重通過DMA 控制器讀到權(quán)重緩存中,若參數(shù)量小,則一次性將其全部保存,運行過程中不再傳輸權(quán)重,當(dāng)參數(shù)規(guī)模較大則需要實時傳輸。之后,啟動PE 陣列計算。為達到高效計算和節(jié)省ROM/RAM資源,配置兩個片上緩存池,各層在輸入和輸出緩沖池中均有兩個可重用的乒乓緩沖區(qū),緩沖區(qū)的數(shù)量小于層數(shù),通過覆蓋計算時間來避免加/卸載數(shù)據(jù)所需要的時間開銷。緩沖控制器負責(zé)輸入和輸出緩沖池中的數(shù)據(jù)讀取寫入,上層輸出緩存區(qū)中的寫入數(shù)據(jù)即為本層待輸入的特征圖。結(jié)合卷積計算的循環(huán)分塊技術(shù),在得到部分輸出結(jié)果時,即可開始下一層運算,主控制器用來支持整個網(wǎng)絡(luò)的細粒度流水線順序。
CNN 網(wǎng)絡(luò)中卷積計算可視為一個多維嵌套循環(huán),如圖3所示。其中Rin=(Rout-1)×S+K,Cin=(Cout-1)×S+K。
圖3 卷積層偽代碼
采用分塊技術(shù)分割循環(huán)中的迭代空間可有效緩解片上內(nèi)存緊張,而可行的分塊維度包括平面卷積窗口運算(K×K)、輸出特征圖尺寸(Rout×Cout)和輸入輸出通道數(shù)(M×N),因為K值一般都很?。ㄍǔ閇3,11]),故采用對后兩個維度進行分塊操作,如圖4所示。
圖4 循環(huán)分塊原理圖
其各維度對應(yīng)的分塊尺寸為Tro、Tco、Tn、Tm完成一個卷積層的執(zhí)行周期數(shù)為:
未分塊的圖3所示的卷積層所需的操作總數(shù)為:
在采用后續(xù)的循環(huán)展開操作以及忽略流水線開銷的影響時,Rooflinemodel[9]中的ComputationalRoof 可由下式計算:
而對于具有Npe個處理單元的計算通路,通常有如下限制條件:
最優(yōu)的架構(gòu)是最大化ComputationalRoof,等效于最小化執(zhí)行周期數(shù)。
在采用w位寬量化策略時,圖4中循環(huán)分塊對輸入輸出特征圖和權(quán)重緩存尺寸的要求為:
其中BRAMcapacity為片上內(nèi)存容量。
分塊后需要對輸入輸出特征圖和權(quán)重進行片外讀取的次數(shù)為:
Computation to Communication(CTC)ratio 用來表征每次內(nèi)存訪問能支持的計算操作數(shù)量,是衡量數(shù)據(jù)重用水平的一個指標(biāo),其定義如下:
由公式(3)和公式(10)可得出,在給定分塊策略
由于生成的加速器采用層間流水線架構(gòu),為達到最大吞吐量性能,在考慮各層復(fù)雜度、數(shù)據(jù)重用行為的情況下,需使各流水線段的負載平衡,以使時延大致相等[10]:
其中Ci代表層i的計算復(fù)雜度(見公式(2)),Ri表示層i所消耗的計算資源(公式(4)乘以每個PE 所需DSP 數(shù)量),片上可用的計算計算為Rtotal,而層i的時延Di為:
其中λ是與硬件工作頻率有關(guān)的常量。網(wǎng)絡(luò)整體吞吐量受限于具有最大計算時間的卷積層:
因此,本加速器采用公式(12)~(15)指導(dǎo)網(wǎng)絡(luò)對各層進行計算資源分配。
經(jīng)過循環(huán)分塊后,圖3 最里層的6 個小循環(huán)所涉及的計算任務(wù)不僅具有數(shù)據(jù)來源的相關(guān)性和結(jié)果的獨立性,而且被劃分為更小的計算單元,完全可能在片上實現(xiàn)并行化計算,使資源和帶寬得到更充分利用,如圖5~8所示。
圖5 層間并行
圖5展示了層間并行,以分塊為基本流水段的細粒度流水線可以實現(xiàn)同一時間段所有層的并行計算,減小了啟動延時。圖6中是層內(nèi)并行,該并行是通過輸入像素復(fù)用實現(xiàn)的,當(dāng)計算輸出特征圖像上不同通道相同位置的區(qū)域,所需要的輸入特征圖像數(shù)據(jù)是固定區(qū)域,唯一的區(qū)別是各個輸出通道對應(yīng)的卷積核不相同,該種并行度為Tn×Tm。圖7 描述了核間并行,該并行是通過權(quán)重數(shù)據(jù)復(fù)用實現(xiàn)的,輸出特征圖像中的同一個通道的不同位置像素,所使用的是同一組權(quán)重數(shù)據(jù),對應(yīng)該種并行度為Tro×Tco。圖8 是核內(nèi)并行,輸入特征圖每一通道的卷積窗口與對應(yīng)卷積核平面計算涉及大量乘加操作,這些運算都是可并行的,并行度為K×K。
圖6 層內(nèi)并行
圖7 核間并行
圖8 核內(nèi)并行
本加速器計算引擎采用上述4種并行性后的結(jié)構(gòu),如圖9所示。圖中,Pix和W代表像素和權(quán)重,一個乘法器和一個加法器組成一個基本處理單元,后面連接一加法器樹。每個灰色填充區(qū)域代表一個卷積窗口和對應(yīng)卷積平面點乘,對應(yīng)核內(nèi)并行;Tn個灰色區(qū)域為一組,用黑色實線框住,可以生成一個輸出像素值。而紅色虛線包圍的計算處理引擎共享相同的特征圖像數(shù)據(jù),能夠?qū)崿F(xiàn)層內(nèi)并行,Tm×Tn×K×K表示小工作集像素值復(fù)用和核內(nèi)并行下的乘法器個數(shù),可同時生成Tm個輸出像素。左邊藍色虛線區(qū)域的處理引擎不同的像素值與相同的權(quán)重相乘,實現(xiàn)了核間并行,Tro×Tco×Tn×K×K表示小工作集權(quán)重復(fù)用和核內(nèi)并行下的乘法器個數(shù),可同時生成Tro×Tco個輸出像素。
圖9 全并行模式下的計算引擎結(jié)構(gòu)
本文實驗首先在ubuntu18.04 系統(tǒng)和python2.7 環(huán)境下,采用caffe 訓(xùn)練AlexNet[11]網(wǎng)絡(luò)模型,將訓(xùn)練后的權(quán)重.caffemodel、網(wǎng)絡(luò)定義文件.prototxt 以及FPGA(Virtex7 690t)各資源參數(shù)值作為CNN 加速框架輸入,得到分割并轉(zhuǎn)換后的各層權(quán)重二進制.coe文件、加速器verilog 源代碼和仿真測試數(shù)據(jù)。之后在ubuntu14.04 系統(tǒng)和vivado2013.4的非工程模式下,調(diào)用其multiplier和ROM/RAM memory IP 核生成用于各層乘加運算和存儲結(jié)果的模塊。最后,在配備有Intel i5-7400 CPU,顯卡為HD Graphics 630的Win10系統(tǒng)下,通過vivado2018.3和modelsim10.1c 的聯(lián)合仿真(200 MHz 工作頻率)、綜合及布局布線,實現(xiàn)了3個網(wǎng)絡(luò)的正向傳播??紤]到過度參數(shù)化的CNN 模型中存在大量冗余連接[12],為了有效減少片內(nèi)外存儲需求,加速器使用動態(tài)4-8-16位量化策略,top-5準(zhǔn)確率僅下降不到2%。
根據(jù)FPGA(Virtex7 690t)的硬件資源參數(shù)值和AlexNet模型的網(wǎng)絡(luò)配置,CNN加速框架輸出verilog語言形式的CNN 加速器。采用Vivado2018.3 工具集完成布局布線和仿真,得到圖10 中的AlexNet 加速器,圖11是圖10 中的第五個卷積層結(jié)構(gòu)的原理圖,可見加速器的整體架構(gòu)采用層并行模式以層間流水線形式存在,各卷積層IP通過由乘累加器組成的vector_muladd模塊實現(xiàn)并行計算。表1 顯示了部署后的資源利用率和實現(xiàn)性能,加速器高效地利用了FPGA的硬件資源。在批處理尺寸為11,采用4-8-16 位動態(tài)精度數(shù)據(jù)量化策略[13],工作頻率為200 MHz時,每秒能處理93.7張227×227×3的圖像最高可達1 493.4 Gops 計算峰值,而僅使用了2 562 塊DSP 和688 塊BRAM 參與前向推理,分別占用片上存儲和計算資源總數(shù)的46.8%和71.2%。
表1 Virtex7 690t@200 MHz下實驗結(jié)果
圖10 AlexNet網(wǎng)絡(luò)加速器原理圖
圖11 卷積層結(jié)構(gòu)原理圖
本文對關(guān)鍵資源DSP 的利用效率進行了評估。引入DSP 效率來表示參與運算的DSP 的實際與理論最大性能的比率,定義為:
當(dāng)采用定點數(shù)16,8,4 時,β=2,4,8,表示一個DSP 與其相應(yīng)的邏輯單元在一個時鐘周期可進行的算術(shù)操作次數(shù)[10]。DSP_num×freq×β是在給定頻率下,所有DSP能達到的理論最大算力,分子Perf.為表1 中的實際性能。因為其不依賴于FPGA 平臺的片上DSP 數(shù)量且消除了時鐘頻率的影響,可以對使用不同F(xiàn)PGA 平臺和CNN模型的并行優(yōu)化算法進行公平比較。表中顯示在Virtex7上DSP的效率高達0.73(Ops/DSPs/cycle)。
令DW/DP 表示,位寬為DW 的數(shù)據(jù)定點量化后小數(shù)點位置為DP。表2列出了主導(dǎo)計算的層的數(shù)據(jù)量化情況。
表2 關(guān)鍵層的輸入輸出與權(quán)值量化
未列出的層(如池化等)輸出與輸入量化保持一致。圖12是文獻[14]多次訓(xùn)練后得出的AlexNet預(yù)測準(zhǔn)確度top-1 和top-5 隨網(wǎng)絡(luò)量化位寬的變化曲線(訓(xùn)練后,各層權(quán)值截斷至相同位寬)??梢?,當(dāng)精度下降到8 bit 以下,準(zhǔn)確度急劇下滑,但考慮到全連接層權(quán)重密度大、數(shù)值小和存在冗余連接多,本策略仍然對全連接層權(quán)值采用較激進的4 bit位寬。與采用32位浮點方案相比,本方案在Ristretto caffe[15](caffe的擴展,可以有限數(shù)據(jù)精度訓(xùn)練、微調(diào)和測試網(wǎng)絡(luò))訓(xùn)練后的top-1和top-5準(zhǔn)確度下降幅度均在2%以內(nèi),分別為從55.7%下降到53.9%,79.0%到77.9%。
圖12 預(yù)測準(zhǔn)確度與網(wǎng)絡(luò)量化位寬關(guān)系
進一步針對于具體圖像采用上述量化方案在FPGA上正向傳播過程中產(chǎn)生的誤差進行分析,由于AlexNet層數(shù)較多,圖13 僅展示Conv1 第一個特征圖和最后一個全連接層Fc8的輸出情況。
圖13 Conv1和Fc8的輸出
從圖3可定性得出,真實數(shù)據(jù)(caffe浮點數(shù)輸出)和仿真數(shù)據(jù)(modelsim10.c定點數(shù)輸出)的分布基本一致,將仿真數(shù)據(jù)減去真實數(shù)據(jù)可得誤差值的分布情況,如圖14所示。
圖14 Conv1和Fc8的誤差分布
定義公式(17)對誤差定量分析:
sim、real分別表示各層特征圖像素的仿真和真實數(shù)據(jù)值,可得Conv1第一個特征圖和Fc8輸出的誤差分別為0.001 101、0.002 413。仿真數(shù)據(jù)與真實數(shù)據(jù)的差值很小,誤差影響可忽略。同理,介于Conv1 與Fc8 之間的隱藏層情況類似,網(wǎng)絡(luò)整體的平均量化誤差為0.003 2,說明上述的量化策略可取。
動態(tài)4-8-16位量化策略可有效減少存儲需求:
(1)片外DRAM 用于存儲源圖像、AlexNet 權(quán)重和推理結(jié)果,表2 顯示,輸入特征圖和網(wǎng)絡(luò)推理結(jié)果量化為16 bit,而卷積層和全連接層權(quán)值分別量化為8 bit和4 bit。AlexNet 一共有60 965 224 個可訓(xùn)練參數(shù),輸入為標(biāo)準(zhǔn)227×227×3彩圖,輸出是1 000個分類概率,當(dāng)采用4-8-16 量化策略后,加速器對片外存儲空間需求從244 483 244 Byte(233.2 MB)下降到31 960 826 Byte(30.5 MB),節(jié)省87%的DRAM存儲。
(2)片上RAM/ROM 用于保存推理運行中的權(quán)重、中間結(jié)果和各層輸入輸出特征圖,本加速器采用層并行模式下的細膩度流水線架構(gòu),乒乓緩存數(shù)據(jù)傳輸,僅需獲得上層輸出的部分分塊數(shù)據(jù)和部分權(quán)重即可開啟本層運算,對片上內(nèi)存需求大大減少。圖15 比較了本文片上內(nèi)存管理方法與傳統(tǒng)設(shè)計(特征圖和權(quán)重完全保存)對BRAM需求的差異。
圖15 本文方法與傳統(tǒng)設(shè)計的內(nèi)存需求比較
從圖15 可知,本加速器部署前8 個卷積和池化層,使用394個BRAM,而傳統(tǒng)的將特征圖和核權(quán)重全部存儲在片上的方法,使用1 915 個BRAM。傳統(tǒng)設(shè)計比本文方法最低多消耗1.34倍存儲資源(pool5),最高為6.21倍(conv4)。最后3個全連接層占據(jù)了96%的權(quán)重,傳統(tǒng)設(shè)計方法無法一次性將其保存至片上,故本文未對其加以分析,而在細膩度流水線架構(gòu)和輸入輸出緩存池技術(shù)下,本方法在Fc6、Fc7、Fc8 層分別僅消耗166、68、43 個BRAM,至少會節(jié)省80%存儲資源。
進一步地,探究了在本文內(nèi)存管理方法下,數(shù)據(jù)有無進行動態(tài)4-8-16位精度量化對內(nèi)存需求的變化,如圖16所示。
圖16 兩種量化方案對內(nèi)存需求的差異
在32位浮點情況下,AlexNet加速器需要占用2 552個BRAM,是4-8-16位量化的3.81倍。注意到,3個全連接層Fc6、Fc7、Fc8 的壓縮比率較高,分別為5.35、5.49、3.81 倍,主要原因是全連接層存在大量冗余連接,權(quán)值接近0,采用較激進的4 bit量化可在不降低推理準(zhǔn)確度的前提下減少片上存儲壓力。
Zhang等人[9]在Intel Xeon CPUE5-2430上運行AlexNet模型中,開啟多線程執(zhí)行,在103.48 ms 內(nèi)完成正向傳播,達到12.84 Gops的峰值性能。從Nvidia官方文檔可知,采用16 位浮點,批尺寸為2,AlexNet 模型在GPUTX2[16]上的幀率為250 frame/s。圖17比較了CPU、GPU與FPGA在計算性能上的差異。本文設(shè)計的AlexNet加速器在FPGA 上的計算性能分別是CPU 和GPU 上的115.8 倍和4.1 倍,一方面是因為FPGA 更適合計算密集型任務(wù),另一方面是本加速器更充分挖掘了CNN 可并行計算的空間和進行了有效內(nèi)存管理。
圖17 CPU、GPU與FPGA之間的性能比較
此外,本文將Virtex7 690t上的加速器實驗結(jié)果與3個最近的具有分類功能的基于FPGA 的CNN 加速器進行比較,如表3 所示。在Virtex7 690t 上達到的峰值性能為1 493.4 Gops,比其他3個參考結(jié)果都要高,最低為4.2 倍,最高達到24.2 倍。由于不同的實驗利用不用規(guī)所格示的。FPGA 平臺,所使用的CNN 模型和時鐘頻率也不一樣,為了能公正客觀衡量各個設(shè)計方法的優(yōu)劣,下表進一步列出了DSP效率,其用來評估每一個參與運算的DSP利用的充分程度。
表3 與基于FPGA的CNN加速器的比較
在Virtex7 690t 平臺,本文設(shè)計方法的DSP 效率均比其他文獻中采用的方法要高,分別是他們的1.7 倍、2.6 倍和1.2 倍。說明本加速器采用的方法能提高硬件資源利用率和數(shù)據(jù)重用機會,充分挖掘了FPGA并行計算能力。
本文提出一個針對卷積神經(jīng)網(wǎng)絡(luò)加速的CNN加速框架,生成的加速器可實現(xiàn)高性能和高效率。為了提高計算吞吐量,采用基于設(shè)計空間探索的方法確定卷積分塊因子,并將分塊進行展開,從而提高計算并行性。該方法可增大CTC 率,減少外部存儲訪問帶寬需求,提高數(shù)據(jù)復(fù)用程度。對整個網(wǎng)絡(luò)采用細粒度流水線架構(gòu),考慮到有限的片上內(nèi)存容量,用內(nèi)存池、乒乓緩存和4-8-16位精度量化策略進行數(shù)據(jù)傳輸,以減少啟動和輸出延時。基于上述的設(shè)計方法,與其他基于CPU/GPU/FPGA的方法相比,本文達到了最高吞吐性能峰值1 493.4 Gops,DSP效率超過了其他設(shè)計方法,本文加速器高效且性能優(yōu)異。