趙 彤,喬廬峰,陳慶華
(陸軍工程大學(xué) 通信工程學(xué)院,江蘇 南京 210007)
隨著硬件GPU的快速發(fā)展和大數(shù)據(jù)時(shí)代的來臨,深度學(xué)習(xí)迅猛發(fā)展,已席卷人工智能各個(gè)領(lǐng)域,包括語音識(shí)別、圖像識(shí)別、視頻跟蹤、自然語音處理等在內(nèi)的圖、文、視頻領(lǐng)域。深度學(xué)習(xí)技術(shù)突破了傳統(tǒng)技術(shù)方法,大大提高了各領(lǐng)域的識(shí)別性能。應(yīng)用深度學(xué)習(xí)技術(shù)到智能化移動(dòng)嵌入式軍事設(shè)備,將成為新一代深度學(xué)習(xí)的發(fā)展浪潮。
伴隨著深度網(wǎng)絡(luò)模型的性能增加,模型的深度越來越深,深度網(wǎng)絡(luò)模型的高計(jì)算量和高存儲(chǔ)弊端,嚴(yán)重制約著資源有限的應(yīng)用環(huán)境,特別是智能化移動(dòng)嵌入式設(shè)備。例如,8層的AlexNet[1]裝有600 000個(gè)網(wǎng)絡(luò)節(jié)點(diǎn),6.1×107個(gè)網(wǎng)絡(luò)參數(shù),需要花費(fèi)240 MB的內(nèi)存存儲(chǔ)、7.29×108次浮點(diǎn)型運(yùn)算 次 數(shù)(The Number of Floating-point Operation,F(xiàn)LOP)來分類一副分辨率為224×224的彩色圖像。隨著模型深度的加深,存儲(chǔ)和計(jì)算開銷增加。同樣分類一副分辨率為224×224的彩色圖像,16層的VGGNet[2]裝有1 500 000個(gè)網(wǎng)絡(luò)節(jié)點(diǎn),1.44×108個(gè)網(wǎng)絡(luò)參數(shù),需要花費(fèi)528 MB的內(nèi)存存儲(chǔ)、1.5×1010次FLOP。
目前,對(duì)深度神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)多是基于通用計(jì)算機(jī),不僅計(jì)算機(jī)體積大,還會(huì)因計(jì)算機(jī)的輸入輸出接口速度限制了整體速度,更限制了應(yīng)用的廣度與深度。另外,深度神經(jīng)網(wǎng)絡(luò)的設(shè)計(jì)者或使用者必須要對(duì)網(wǎng)絡(luò)的工作軟硬件環(huán)境有相當(dāng)了解,才能將其應(yīng)用在實(shí)際系統(tǒng)上,更限制了深度神經(jīng)網(wǎng)絡(luò)的發(fā)展。因此,若能適當(dāng)采用現(xiàn)場可編程邏輯門陣列(Field Programmable Gate Array,F(xiàn)PGA)芯片的形式實(shí)現(xiàn)控制器,不僅可以大大縮小硬件體積,而且具有執(zhí)行速度快、靈活度高的優(yōu)點(diǎn)。目前,雖然已有一些研究[3-6]將神經(jīng)網(wǎng)絡(luò)控制器實(shí)現(xiàn)在FPGA芯片上,但將深度神經(jīng)網(wǎng)絡(luò)的方法實(shí)現(xiàn)在FPGA芯片上的研究越來越受到重視,并展現(xiàn)出很有希望的前景。已有研究發(fā)現(xiàn),使用FPGA實(shí)現(xiàn)后硬件在執(zhí)行速度上可將原本限制于普通計(jì)算機(jī)I/O的毫秒等級(jí)速度提高到微秒等級(jí)的快速輸出,高處理速度將可使深度神經(jīng)網(wǎng)絡(luò)應(yīng)用在更多需要快速反應(yīng)的應(yīng)用上。深度神經(jīng)網(wǎng)絡(luò)會(huì)因FPGA硬件體積較小和功耗較低提高使用者的興趣,尤其在學(xué)習(xí)精準(zhǔn)度上沒有因?yàn)橛布刑蟛町?。此外,由于FPGA的可重復(fù)編程性,可以方便地實(shí)現(xiàn)算法更新和目標(biāo)重定義。
由于目前神經(jīng)網(wǎng)絡(luò)的規(guī)模越來越大,層數(shù)也越來越深,而受限于FPGA上的存儲(chǔ)資源,必須借助外部存儲(chǔ)芯片,才能完成整個(gè)網(wǎng)絡(luò)的運(yùn)行。因此,本設(shè)計(jì)采用將外部DDR存儲(chǔ)芯片與運(yùn)算FPGA相結(jié)合的方式,架構(gòu)如圖1所示。由圖1可以看出,整個(gè)硬件平臺(tái)的架構(gòu)由運(yùn)算FPGA芯片和存儲(chǔ)芯片DDR組成,F(xiàn)PGA內(nèi)部由總控和運(yùn)算單元(PE)組成。
圖1 CNN加速器的基本架構(gòu)
總控主要負(fù)責(zé)對(duì)輸入的特征圖、網(wǎng)絡(luò)的權(quán)重以及產(chǎn)生的中間結(jié)果進(jìn)行管理,并負(fù)責(zé)各PE與外部DDR之間的通信和數(shù)據(jù)轉(zhuǎn)換,結(jié)構(gòu)如圖2所示。
總控模塊包含DDR控制器、數(shù)據(jù)接口、數(shù)據(jù)解析/打包模塊以及存儲(chǔ)中間結(jié)果的FIFO。
DDR控制器用與FPGA與外部DDR之間的通信,包含運(yùn)行DDR接口協(xié)議的IP核。在滿足一個(gè)突發(fā)的條件后,它將FPGA內(nèi)部的數(shù)據(jù)傳輸?shù)紻DR或者將DDR里的數(shù)據(jù)傳輸?shù)紽PGA。其余部分按數(shù)據(jù)流向可以分成兩部分。
第一部分,數(shù)據(jù)流從DDR到FPGA。在FPGA模塊開始運(yùn)行后,先將一部分特征值與網(wǎng)絡(luò)權(quán)重值預(yù)先存儲(chǔ)在FPGA內(nèi)部。待整個(gè)系統(tǒng)運(yùn)行起來后,在需要數(shù)據(jù)參與運(yùn)算時(shí),通過DDR控制器發(fā)送讀取命令給DDR(包括讀取的bank號(hào),讀取的行列號(hào)以及突發(fā)的長度)。DDR接收到命令后,將相應(yīng)的數(shù)據(jù)以突發(fā)方式傳輸?shù)紽PGA中。由于DDR傳輸來的數(shù)據(jù)含有標(biāo)記信息(包括該數(shù)據(jù)的特征圖編號(hào)、行列號(hào)等),所以FPGA在接收到數(shù)據(jù)后,要先通過數(shù)據(jù)解析模塊解析數(shù)據(jù),再存儲(chǔ)到相應(yīng)的FIFO中,以便PE讀取。
圖2 總控模塊的結(jié)構(gòu)
第二部分,當(dāng)卷積運(yùn)算完成后,產(chǎn)生的中間結(jié)果要從FPGA內(nèi)部傳輸?shù)紻DR。這時(shí)數(shù)據(jù)流從PE中出來,先經(jīng)過數(shù)據(jù)打包模塊為每個(gè)數(shù)據(jù)打上相應(yīng)的標(biāo)簽,包括該數(shù)據(jù)的層號(hào)、特征圖的編號(hào)以及行列號(hào)等信息,而后打包完的數(shù)據(jù)發(fā)送到輸出FIFO進(jìn)行緩存,等到滿足一個(gè)突發(fā)條件后,該突發(fā)數(shù)據(jù)經(jīng)由DDR控制器發(fā)送到外部DDR進(jìn)行存儲(chǔ)。
對(duì)于目前最常見的網(wǎng)絡(luò),最多是3×3和5×5卷積核。所以,對(duì)于PE架構(gòu),有以下兩種設(shè)計(jì):圖3(a)是卷積核為3×3時(shí)的PE結(jié)構(gòu),圖3(b)是卷積核為5×5時(shí)的PE結(jié)構(gòu)。PE中主要由存儲(chǔ)陣列控制器、RAM陣列和乘加操作運(yùn)算矩陣構(gòu)成。存儲(chǔ)陣列控制器負(fù)責(zé)對(duì)RAM陣列中的數(shù)據(jù)進(jìn)行管理,控制行列號(hào)的轉(zhuǎn)換和RAM陣列讀寫操作的控制;RAM矩陣存儲(chǔ)相應(yīng)的特征值和權(quán)重;乘加操作運(yùn)算矩陣負(fù)責(zé)對(duì)輸出的特征值與權(quán)重進(jìn)行計(jì)算,以得到最終結(jié)果。本設(shè)計(jì)針對(duì)卷積核的不同設(shè)計(jì)不同的PE,目的是針對(duì)不同網(wǎng)絡(luò)的結(jié)構(gòu)特性調(diào)整整個(gè)設(shè)計(jì)中PE的分布,從而使性能達(dá)到最優(yōu)。
圖3 數(shù)據(jù)處理單元(PE)的結(jié)構(gòu)
在硬件中實(shí)現(xiàn)多計(jì)算資源來加速CNN的推斷過程,存儲(chǔ)帶寬的限制常常是處理CNN的瓶頸[7]。例如,對(duì)于卷積層來講,大量的乘加操作必然導(dǎo)致大量的存儲(chǔ)器讀寫。因?yàn)槊總€(gè)乘加操作需要至少2個(gè) 存儲(chǔ)器讀操作和1個(gè)存儲(chǔ)器寫操作,而FPGA內(nèi)部存儲(chǔ)資源的限制,必須要把大部分網(wǎng)絡(luò)參數(shù)和中間結(jié)果存儲(chǔ)在外部DDR上,所以會(huì)嚴(yán)重影響吞吐率和能量消耗,甚至比乘加運(yùn)算本身的能耗還要大。
針對(duì)存儲(chǔ)帶寬的限制問題,本設(shè)計(jì)提出一種能降低對(duì)外部存儲(chǔ)帶寬需求的方案。具體地,針對(duì)目前應(yīng)用最廣泛的3×3卷積核,進(jìn)行以下設(shè)計(jì)。對(duì)于一張224×224的特征圖,采用如圖4所示方式進(jìn)行存儲(chǔ)。對(duì)于一個(gè)224×224的特征圖,在整個(gè)運(yùn)算開始前,先將該特征圖的前3行值存儲(chǔ)到3×3的RAM陣列中。在RAM陣列中,每一行RAM只存儲(chǔ)特征圖的同一行值。這樣存儲(chǔ)便可在一拍就得到卷積結(jié)果,而不需要額外的操作。
對(duì)于CNN的參數(shù),采用如圖5所示的格式進(jìn)行存儲(chǔ)??梢钥吹?,該層網(wǎng)絡(luò)共有32個(gè)3×3的卷積核。本設(shè)計(jì)將這些卷積核存儲(chǔ)到一個(gè)3×3的RAM陣列中,3×3卷積核中的每個(gè)權(quán)重值分別存儲(chǔ)到不同的RAM中。這樣權(quán)重值與特征值相對(duì)應(yīng),可以在一拍內(nèi)得出計(jì)算結(jié)果。
圖4 特征值的存儲(chǔ)示意
圖5 權(quán)重的存儲(chǔ)示意
對(duì)于當(dāng)前存儲(chǔ)在RAM陣列中的特征圖和權(quán)重,計(jì)算完成后會(huì)得到分屬于32個(gè)不同特征圖的結(jié)果,這樣需要用FIFO進(jìn)行緩存,而后經(jīng)過一次DMA突發(fā),將屬于同一個(gè)特征圖的特征值送到外部DDR,以最大限度的節(jié)省帶寬。
存儲(chǔ)管理模塊的設(shè)計(jì)流程如圖6所示。
由圖6可以看出,本設(shè)計(jì)運(yùn)算開始后,先固定一個(gè)權(quán)重值,而后遍歷特征圖,以使得該部分的輸出屬于同一個(gè)特征圖,方便對(duì)其進(jìn)行存儲(chǔ)。在當(dāng)前存儲(chǔ)權(quán)重的RAM陣列運(yùn)行到最后一個(gè)值時(shí),更新存儲(chǔ)特征圖的RAM陣列,以保證流水的不中斷,也使設(shè)計(jì)的并行化達(dá)到最大。
對(duì)于每一組ram來講,每一行的3個(gè)ram存儲(chǔ)同一行的特征值,即需要預(yù)先將特征圖的3整行分別存儲(chǔ)到片內(nèi),而后從第四行進(jìn)行更新。在對(duì)同一行進(jìn)行卷積操作時(shí),只有列號(hào)進(jìn)行變化,而行號(hào)保持不變。只有在整列結(jié)束,所有的值都更新完畢后,再進(jìn)行行號(hào)的變化。
當(dāng)存儲(chǔ)在RAM陣列中的權(quán)重值運(yùn)行到最后一個(gè)時(shí),開始進(jìn)行特征圖的更新,在此之前會(huì)將一整行特征圖以DMA突發(fā)的方式傳輸?shù)狡瑑?nèi)FIFO中進(jìn)行存儲(chǔ),再從FIFO中一次取出一個(gè)特征值更新RAM陣列中的特征值,具體過程如圖7所示。
由圖7可以看出,在更新完特征值后,RAM陣列中的列號(hào)要進(jìn)行變化,且更新過的RAM中的讀指針要加1,以方便對(duì)RAM陣列操作,即對(duì)于外部接口來講,每次只需要對(duì)列號(hào)為0、1、2的RAM進(jìn)行操作,便可以讀取相應(yīng)的操作數(shù)。
當(dāng)一整行特征值更新完畢后,要進(jìn)行行號(hào)的轉(zhuǎn)換,具體過程如圖8所示。
由圖8可以看出,一行特征值的最后一個(gè)更新完畢后,相應(yīng)的RAM陣列的行號(hào)也發(fā)生變化,從而為下一次操作做準(zhǔn)備。對(duì)于外部接口來講,每次只需要對(duì)行號(hào)為0、1、2的RAM進(jìn)行操作,便可以讀取相應(yīng)的操作數(shù)。
特征值的行列號(hào)與權(quán)重值的對(duì)應(yīng)關(guān)系,如表1 所示。特征值與權(quán)重的對(duì)應(yīng)關(guān)系是固定的,所以每次運(yùn)算的操作數(shù)均嚴(yán)格按照卷積神經(jīng)網(wǎng)絡(luò)的運(yùn)算規(guī)則,不會(huì)出現(xiàn)位置的不匹配而導(dǎo)致錯(cuò)誤的 結(jié)果。
圖6 存儲(chǔ)管理模塊的流程
圖7 RAM陣列更新時(shí)的列號(hào)變化
圖8 RAM陣列更新時(shí)的行號(hào)變化
表1 特征值的行列號(hào)與權(quán)重值的對(duì)應(yīng)關(guān)系
對(duì)于stride=1的3×3卷積,采用Winograd算法[8]來加速整個(gè)計(jì)算。Winograd算法的基本原理即用加法運(yùn)算代替乘法運(yùn)算,以減少運(yùn)算量。例如,本設(shè)計(jì)中采用F(2×2,3×3),共需4×4=16次乘法運(yùn)算,而標(biāo)準(zhǔn)的算法則需2×2×3×3=36次乘法。
對(duì)于F(2×2,3×3),其輸出為:
其中,
式(2)中剩余的參數(shù)g為3×3的濾波器,d為4×4的特征值矩陣。每一個(gè)特征圖被分割成了4×4的子特征矩陣,相鄰的兩個(gè)子特征矩陣之間有2個(gè)特征值的重疊。
針對(duì)Winograd算法的特性,可以令U=GgGT,V=BTdB,則式(2)變成:
本設(shè)計(jì)在運(yùn)算開始前,可以將卷積核與特征值提前進(jìn)行轉(zhuǎn)換,而后直接在FPGA內(nèi)部進(jìn)行運(yùn)算,以減少大量的重復(fù)性工作。
本設(shè)計(jì)是在Xilinx Virtex7 xc7vx690t平臺(tái)上執(zhí)行的,采用流水結(jié)構(gòu),將每層單獨(dú)設(shè)計(jì),而后統(tǒng)一控制,提升了速度。在流水線設(shè)計(jì)中,每一層的運(yùn)算量要保持大體相等,否則會(huì)產(chǎn)生流水線的瓶頸,從而降低整個(gè)流水線效率。
本設(shè)計(jì)以Alexnet為例,對(duì)提出的相關(guān)算法進(jìn)行實(shí)現(xiàn),并與其他的FPGA實(shí)現(xiàn)方式進(jìn)行對(duì)比,得到的結(jié)果如表2所示。可以看出,采用本方案提出的存儲(chǔ)管理和運(yùn)行框架,可以達(dá)到較高的性能,且在表格所列舉的5個(gè)設(shè)計(jì)方案中,本設(shè)計(jì)的能耗性能比最高。
此外,將該FPGA平臺(tái)的實(shí)驗(yàn)結(jié)果與GPU的實(shí)現(xiàn)結(jié)果進(jìn)行對(duì)比,結(jié)果如表2所示。
本設(shè)計(jì)采用NVIDIA TitanX的GPU,在Caffe框架[13]下對(duì)Alexnet進(jìn)行實(shí)現(xiàn)。在GPU的實(shí)現(xiàn)中,采用Winograd算法對(duì)設(shè)計(jì)進(jìn)行加速,得到的結(jié)果如表3所示。可以看出,在實(shí)現(xiàn)相同的網(wǎng)絡(luò)時(shí),雖然GPU的性能要高于本設(shè)計(jì),但是本設(shè)計(jì)能耗性能比是GPU的2.7倍。
表2 不同平臺(tái)實(shí)現(xiàn)Alexnet的性能對(duì)比
表3 本設(shè)計(jì)與GPU的性能對(duì)比
本文對(duì)基于CNN的FPGA硬件平臺(tái)進(jìn)行研究,設(shè)計(jì)了一種高效的硬件平臺(tái)架構(gòu),提出了一種能夠有效降低存儲(chǔ)帶寬的存儲(chǔ)管理方案。在此基礎(chǔ)上,采用Winograd算法降低運(yùn)算量,并對(duì)卷積核為3×3和5×5的處理模塊分別進(jìn)行設(shè)計(jì),使得該硬件平臺(tái)能夠更加高效加速CNN。本設(shè)計(jì)在Virtex7 xc7vx690t上實(shí)現(xiàn)了Alexnet,性能為1.31 TFlop/s,平均性能功耗比為45.7 GOP/s/W,結(jié)果優(yōu)于目前較流行的集中設(shè)計(jì)方案。