文獻標識碼: A
DOI:10.16157/j.issn.0258-7998.191070
中文引用格式: 王春林,譚克俊. 基于脈動陣列的卷積計算模塊硬件設計[J].電子技術應用,2020,46(1):57-61.
英文引用格式: Wang Chunlin,Tan Kejun. Hardware design of convolution calculation module based on systolic array[J]. Application of Electronic Technique,2020,46(1):57-61.
0 引言
在過去的幾年里,深度神經網絡(Deep Neural Network,DNN)在圖像分類、目標檢測[1]及圖像分割等領域起到十分重要的作用。這些使用的各種DNNs及其拓撲結構中,卷積神經網絡(Convolutional Neural Network,CNN)是其中最為常見的實現方式。目前在硬件加速方案中,主要有基于CPU、GPU以及FPGA三種主流方案。考慮到 CPU性能限制和GPU功耗高的問題,采用FPGA來實現卷積神經網絡成為了一種可行的實現方式,例如文獻[2]在FPGA中實現神經網絡目標檢測系統,其檢測速度與能效均優于CPU。采用傳統的Verilog HDL或者VHDL硬件描述語言實現卷積神經網絡較為困難[3],高層次綜合(High Level Synthesis,HLS)將C/C++代碼通過特定的編譯器轉化為相應的RTL級的代碼,降低了卷積神經網絡的開發難度,減少了卷積神經網絡的開發周期。
使用FPGA實現卷積神經網絡中卷積計算模塊的過程中,通常采用循環平鋪和循環展開[4]的方式實現。這種方式以擴大并行度來達到網絡的時間復雜度。但是當輸入和輸出特征圖維度增加時,擴大并行度會帶來硬件設計中長廣播、多扇入/扇出的數據通路,導致卷積計算模塊無法在較高的主頻上運行。因此,很多神經網絡加速器都使用脈動陣列來優化加速器架構設計,如谷歌TPU加速器[5]、ShiDianNao加速器[6]等。而在這些加速器架構設計中大多是采用im2col[7]的方式,即將參與卷積計算的輸入特征圖和權重展開為兩個矩陣,然后進行矩陣乘法運算。這種實現方式因為卷積步長的存在而產生大量的數據重疊,不利于在FPGA的片上塊存儲器(Block RAM,BRAM)內進行存儲。
為了解決上述存在的問題,本文提出一種基于脈動陣列的卷積計算模塊設計,將由并行展開所帶來的長數據通路變為每個處理單元的短數據通路;并按照存儲矩陣的坐標向卷積計算模塊中輸入特征圖數據,以解決im2col方式存在的數據重疊,不利于BRAM存儲的問題。整體設計使用Vivado HLS開發環境進行實現與優化。
1 本文工作
1.1 脈動陣列實現卷積計算模塊
脈動陣列(Systiloc Array)[8]是1970年KUNG H T[9]提出的一種應用在片上多處理器的體系結構,由多個相同的、結構簡單的計算單元(Processing Element,PE)以網格狀形式連接而成,具有并行性、規律性和局部通信的特征。信號處理算法如卡爾曼濾波[10]和數值線性代數算法都可以用脈動陣列來實現。本文卷積計算模塊中采用的脈動陣列實現方式如圖1所示。
在圖1中,I表示輸入特征圖,W表示權重參數,O表示輸出特征圖,r、c分別表示特征圖的長和寬,m、n分別表示輸入特征圖與輸出特征圖的層數。在開始進行卷積運算之前,將特征圖數據輸入到BRAM中進行緩存,將權重輸入到每個PE中進行緩存。開始計算之后,輸入緩存中的數據沿脈動陣列的列方向進行傳輸,PE計算的結果沿脈動陣列行方向進行傳輸。非第0列的PE按照公式(1)進行計算:
式中PEin表示從輸入緩存或者上一個PE讀取輸入數據,W表示PE緩存的權重數據,PEout表示每個PE儲存的計算結果,cho與chi分別表示當前PE的行列坐標。第0列的PE只進行乘法運算。在每一行PE的末尾處連接一個result緩存,用來累加和存儲每行最后一個PE輸出的結果,并在完成一個卷積核運算之后將存儲結果輸出到輸出緩存中。本文脈動陣列結構設置為矩形脈動陣列,長和寬分別以輸入特征圖和輸出特征圖的層數來部署,并且每個PE在一個時鐘周期內進行一個乘法和加法運算,根據這個條件可以得到所有PE完成計算所需要的時間計算公式:
式中,Tsum表示完成所有輸出特征圖的計算所需要的時間,R、C分別表示輸出特征圖的長和寬,Cin、Cout分別表示輸入特征圖層數和輸出特征圖層數,K表示卷積核的邊長,Tprc表示每個時鐘周期所需要的時間。如果R和C的大小設置為5,Cin和Cout分別設置為3和8,K設置為3,Tprc為10 ns,根據公式(2)可以得到理論上需要的時間為2 340 ns。
1.2 卷積計算模塊硬件設計
根據1.1節中脈動陣列在卷積計算模塊中的實現方式,在Vivado HLS開發環境上對卷積計算模塊進行設計。卷積計算模塊分為三個部分:輸入階段、計算階段和累加輸出階段。
輸入階段的流程圖如圖2所示,圖中in(chi,ir,ic)表示BRAM存儲的輸入特征圖,ir、ic分別表示特征圖的長和寬。mid_in(cho,chi)和mid_out(cho,chi)分別表示每一個PE中的輸入和輸出緩存,CHI表示輸入特征圖的層數,CHO表示輸出特征圖層數,COUNT表示一個PE需要進行卷積運算的次數。chi、cho、loc表示三個變量,分別表示脈動陣列的列坐標、行坐標以及運行計數。根據圖2中的運行方式,每經過一個時鐘周期,位于脈動陣列非0列的mid_in會從上一個相同行的mid_in中讀取輸入數據。位于脈動陣列的第0列的mid_in,會根據運行狀態判斷是否需要從BRAM中讀取輸入特征圖數據。
計算階段的流程圖如圖3所示,其中weight(cho,chi,kr,kc)表示緩存到PE中權重參數,kr、kc分別表示卷積核的列坐標與行坐標。當輸入階段結束之后,進入計算階段。位于脈動陣列非0排的mid_out會將mid_in中的數據與weight中的數據做乘法,再和上一個相同列的mid_out中的輸出數據做加法。位于脈動陣列第0排的mid_out則只做一次乘法。PE計算結果保存在當前mid_out中。
累加輸出階段的流程圖如圖4所示,圖中out(cho,r,c)表示BRAM中輸出特征圖緩存,r、c分別表示輸出特征圖的列坐標與行坐標。result表示輸出緩存到BRAM之間的累加寄存器,用來將脈動陣列末尾行PE的結果進行累加,k表示寄存器運行的累加次數。當一個卷積核運算完成之后,將結果按照當前的行列坐標輸出到BRAM中的out緩存中,之后result寄存器清零,繼續下一次累加計算。
在這三個階段運行過程中,希望在每一個時鐘周期內,當前PE可以從外部或者相鄰的PE中讀取一個數據進行乘加計算。因此使用#pragma HLS PIPELINE管道操作優化指令,并設置流水為1級流水,保證每個時鐘內都能夠開啟一次新的計算。在使用流水化操作之后,為了保證在輸入階段和計算階段的數據不會被覆蓋,采用移位寄存器的運行方式,由末尾的PE開始依次從相鄰的上一個PE讀取數據,新數據最后再進行輸入。
同時,因為采用將權重固定到PE中的計算模式,所以將In和Out以數組的形式存放到BRAM中。因為每個BRAM最大可配置的輸入輸出端口數為2,所以當同時從BRAM中輸入輸出數量大于2時,就需要等待上一個操作結束之后,再執行下一個操作,這樣就無法達到1級流水所需要的時間間隔。因此使用#pragma HLS ARRAY_PARTITION variable=<variable> complete dim=X指令,其中<variable>表示需要展開的數組名,X表示需要展開的數組維度,將in(chi,ir,ic)和out(cho,r,c)按照第一個維度展開成多個數組,來匹配脈動陣列的輸入與輸出。
2 實驗結果與分析
本文在Vivado HLS 18.3開發環境上進行綜合與仿真,使用的FPGA芯片型號為賽靈思公司的xc7z020clg484-1,運行時鐘為100 MHz。使用輸入特征圖7×7大小的3層矩陣,得到的輸出特征圖為5×5的8層矩陣。卷積核采用8×3組大小為3×3的矩陣。單個PE的功能仿真波形如圖5所示。
其中,din0和din1分別表示輸入特征圖和權重數據,din2表示從上一個相鄰PE中讀取的計算結果。dout表示乘加計算之后的結果,d0表示result寄存器中的輸入數據,q0表示result寄存器的輸出數據。由于本文采用的時鐘頻率為100 MHz,每個時鐘周期為10 ns。從圖5中可以看出,當ce0信號置1時,表示開始進行運算。之后在每一個時鐘周期內,都進行一次乘加運算,并將結果通過dout進行輸出。因為采用1級流水優化指令,dout輸出的結果將會在下一個時鐘周期輸出到d0。然后進行累加操作。當完成3×3次加法運算,輸出標志位we0信號置1,然后result寄存器將當前的d0結果按照address0的地址通過q0輸出到指定BRAM上的輸出緩存中。然后d0清零,等待下一次計算開始。
卷積計算模塊的輸出波形如圖6所示。從圖中可以看出,在ap_start使能信號置1之后,經過17個時鐘周期得到輸出結果。從開始輸出結果,到輸出完成,一共經過234個時鐘周期,也就是2 340 ns,與公式(2)中計算結果相同。
卷積計算模塊的總體時延如表1所示,從表中可以看出,每次計算PE需要17個時鐘周期才能夠得到結果。在使用了流水化操作,并且達到了1級流水的目標之后,每個時鐘周期都會開啟一個新的循環,PE無需等待到計算出結果就可以進行下一個循環。與圖6中的波形結果相同。
表2所示為卷積計算模塊的總體資源消耗,卷積計算的核心就是乘法運算。賽靈思xc7z020clg484-1型FPGA芯片內置了DSP48核,可同時進行一組乘法和加法運算。根據卷積模塊的設計,每一個PE使用一個DPS48核進行乘加計算。在CHI為3,CHO為8的情況下,一共需要24個DPS48核,與表中使用資源情況相符。觸發器和查找表資源使用也較少,為之后擴大卷積計算模塊和設計卷積神經網絡其余模塊預留了充足的資源。
3 結論
卷積神經網絡中存在著大量的卷積計算,本文在資源使用情況較少的情況下,基于脈動陣列的運行方式,對并行展開的卷積計算模塊進行改進,然后通過Vivado HLS在賽靈思xc7z020clg484-1型FPGA芯片上進行實現。在后續的研究中,可以將脈動陣列與循環展開和循環平鋪等并行展開方式相結合,從提高運行速度與降低使用資源上進一步提升卷積計算模塊的性能。
參考文獻
[1] 張杰,隋陽,李強,等.基于卷積神經網絡的火災視頻圖像檢測[J].電子技術應用,2019,45(4):34-38,44.
[2] 陳辰,嚴偉,夏珺,等.基于FPGA的深度學習目標檢測系統的設計與實現[J].電子技術應用,2019,45(8):40-43,47.
[3] Zhang Xiaofan,Wang Junson,Zhu Chao,et al.DNN-Builder:an automated tool for building high-performance DNN hardware accelerators for FPGAs[C].Proceedings of the International Conference on Computer-Aided Design.ACM,2018.
[4] Zhang Chen,Li Peng,Sun Guangyu,et al.Optimizing fpga-based accelerator design for deep convolutional neural networks[C]. Proceedings of the 2015 ACM/SIGDA International Symposium on Field-Programmable Gate Arrays.ACM,2015.
[5] JOUPPI N P,YOUNG C,PATIL N,et al.In-datacenter performance analysis of a tensor processing unit[C].2017 ACM/IEEE 44th Annual International Symposium on Computer Architecture(ISCA).IEEE,2017.
[6] Chen Tianshi,Du Zidong,Sun Ninghui,et al.Diannao:a small-footprint high-throughput accelerator for ubiquitous machine-learning[C].ACM Sigplan Notices.ACM,2014:269-284.
[7] HU Y H,KUNG S Y.Systolic arrays.in:handbook of signal processing systems[M].Springer,Cham,2019:939-977.
[8] SANAULLAH A,HERBORDT M C.Unlocking performance-programmability by penetrating the Intel FPGA OpenCL Toolflow[C]. 2018 IEEE High Performance Extreme Computing Conference(HPEC).IEEE,2018.
[9] KUNG H T,LEISERSON C E.Systolic arrays(for VLSI)[C].Sparse Matrix Proceedings 1978,Society for Industrial and Applied Mathematics,1979.
[10] 王陽,陶華敏,肖山竹,等.基于脈動陣列的矩陣乘法器硬件加速技術研究[J].微電子學與計算機,2015,32(11):120-124.
作者信息:
王春林,譚克俊
(大連海事大學 信息科學技術學院,遼寧 大連116026)