陳 杰,李 程,劉 仲
(國防科技大學計算機學院,湖南 長沙 410073)
近年來,以卷積神經網絡為代表的深度學習技術不僅在圖像識別[1-3]、自然語言處理[4,5]等領域發揮了巨大的作用,而且在金融[6,7]、推薦算法[8,9]和物理學[10]等領域也同樣彰顯了重大的應用價值。然而,卷積神經網絡模型的性能提升是以龐大的數據和計算量為前提的。傳統CPU(Central Processing Unit)設計的側重點在于通用性,集成了較多的控制單元,對深度學習的加速效果不夠理想。為了加快深度學習計算,許多科技公司投入了大量人力物力,用于定制深度學習加速器,如谷歌的張量處理器TPU(Tensor Processing Unit)[11]、海思研發的NPU(Neural network Processing Unit)[12]和英特爾研發的深度學習訓練加速器NNP(Nervana Neural network Processors)[13]。這些深度學習加速器具有更高的并行處理能力,在面向深度學習領域應用時的功耗和效率表現要遠強于通用CPU的。
FT-M7004是一款由國防科技大學自主研發的多核向量加速器,在大規模矩陣乘法、快速傅里葉變換等科學計算應用領域能夠實現較高的計算效率。FT-M7004采用了單指令流多數據流SIMD(Single Instruction Multiple Data)技術和超長指令字VLIW(Very Long Instruction Word)架構,支持標向量混合運算,具備強大的并行處理能力。卷積神經網絡的計算瓶頸主要在于卷積層和全連接層,因為這2層算子的實現需要大量的乘加運算。FT-M7004也集成了大量的乘加器,在加速卷積神經網絡的計算上擁有顯著優勢。然而目前基于多核向量加速器的深度學習推理和訓練算法還缺乏系統性的研究。
卷積神經網絡主要由數據輸入層、卷積層、激活函數、池化層和全連接層組成,其中計算主要集在卷積層和全連接層。文獻[14]指出卷積層占據了90%~95%的計算量。因此,如何高效地實現卷積層的推理和訓練算法是研究的重點。在算法層次上,Img2col[15,16]、Winograd算法[17,18]、Cook-Toom算法[19]和FFT(Fast Fourier Transform)[20]用于實現卷積層推理,col2img用于實現卷積層訓練。Img2col主要是通過將圖像數據和卷積核數據展開為二維矩陣的形式,以矩陣乘法的形式實現卷積計算。Img2col算法的缺點是需要在每一層對數據進行轉換,存在較多的冗余空間開銷。Winograd算法將圖像數據和卷積核數據分割成塊,并將數據展開,之后將乘法轉變成加法。在卷積核尺寸較大時,Winograd算法加速效果不佳。Cook-Toom算法與Winograd算法類似,其加速效果和使用范圍均不如前者的。卷積操作同樣可以轉換成FFT來加速,之后再進行逆變換得到最終結果。當卷積核尺寸較小時,FFT算法加速效果收益不大。同時,由于上述算法主要應用于CPU和GPU,與FT-M7004平臺的體系結構差異較大,所以需要針對多核向量加速器設計新的推理和訓練算法。
本文針對自主設計的多核向量加速器FT-M7004上的VGG[21]網絡模型推理和訓練算法,分別提出了卷積、池化和全連接等核心算子的向量化映射方法,并進行了性能測試與分析。本文工作主要包含以下幾個方面:
(1)分析了FT-M7004體系結構的特點;
(2)提出了卷積、池化和全連接算子的前向推理和反向訓練算法的向量化映射方法;
(3)采用DMA(Direct Memory Access)雙緩沖傳輸、向量并行和權值共享等優化策略,在FT-M7004平臺上對上述算法進行優化;
(4)對不同規模的卷積、池化和全連接算法進行了性能測試與分析。
FT-M7004包含CPU和向量加速器2種處理器核心。CPU用于運行操作系統,進行任務管理;向量加速器采用VLIW和SIMD體系結構,為FT-M7004提供了主要的計算能力。FT-M7004集成了4個向量加速器核,單核單精度浮點運算峰值性能可以達到128 GFlops。每個加速器的核心由1個標量處理單元SPU(Scalar Processing Unit)和1個向量處理單元VPU(Vector Processing Unit)組成。SPU主要用于標量運算和流控管理,并支持將標量寄存器的數據廣播到VPU中的向量寄存器,使得SPU可以為向量單元運算提供數據。VPU集成了16個同構的向量處理單元VPE(Vector Processing Element)。每個VPE包含了4個乘累加MAC(Multiply ACcumulate)單元,提供了大部分的算力。FT-M7004的片上陣列存儲器AM(Array Memory)采用了多存儲體的組織方式,能同時支持2個向量存儲操作和DMA向量數據訪問操作,為VPU提供了多達2 048位的訪存帶寬,能夠滿足16個VPE的高并行SIMD計算需求。
本節將對本文算法中使用到的符號進行說明。所有張量的索引都是從0開始。圖像和權重的原始數據分別采用NCHW(N表示圖像批處理大小,C表示圖像通道數,H表示圖像的高度,W表示圖像的寬度)和OCHW(O表示卷積核數量,C表示卷積核通道數,H表示卷積核的高度,W表示卷積核的寬度)布局。令N表示批處理的圖像數量;F′表示網絡每一層前向推理的輸入張量;Z′表示網絡每一層前向推理的輸出張量;dZ′表示網絡每一層訓練的輸入張量;dF′表示網絡每一層訓練的輸出張量;pF′表示對輸入張量F′的所有特征圖外圍填充零后的張量;Zd,i,j表示卷積層輸出的第d幅特征圖第i行第j列的值。卷積層和池化層輸入圖像的通道數為C,輸出圖像的通道數為O,高度和寬度分別為nH和nW。WEI表示卷積核或全連接層的權重,bias表示偏置向量,卷積核的高為kH,寬為kW,卷積步長為st。WEId,c,m,n表示4維卷積核張量WEI在索引[d,c,m,n]處的值。在池化層,池化單元的高、寬和步長的表示與卷積層的一致。全連接層的符號同理。X[m,k]表示矩陣X中第m行、第k列的元素。M[d:]表示矩陣M中第d行的元素,M[d:m,]表示矩陣M中第d行到第m行的元素。矩陣Ar*c,表示A的行數為r、列數為c,bias[n]表示向量bias第n個位置的元素。Zn,d,i,j表示卷積層第n個樣本在第d個通道第i行第j列的值。X[:i]代表矩陣X的第i列。全連接層的輸入神經元個數為K,輸出神經元個數為M。Abs表示一個函數,當輸入值為負時,輸出值為0,否則仍為輸入值。pad表示輸入特征圖邊緣填充零的個數。Max(x,0)表示對輸入的標量x與0進行比較,取其中的最大值。
本文算法將卷積神經網絡前向計算的輸入特征數據和反向傳播的輸入誤差梯度進行存儲。如圖1所示,每一列存儲一個樣本數據,每列的存儲順序為:首先為圖像通道C方向優先,接著是圖像寬度W方向優先,最后是圖像高度H方向優先;如圖2所示,卷積核張量存儲為二維卷積核矩陣,其中矩陣的每一行表示一個卷積核,每行的存儲順序首先為卷積核寬度kW方向優先,接著是卷積核高度kH方向優先,最后是卷積核通道C方向優先。本文算法均采用這種數據布局,因此卷積神經網絡中的張量都將轉換為二維矩陣。為了便于區分3.1節中的張量,以F和Z分別代表實際的輸入和輸出張量,WT表示實際的權重。

Figure 1 Input image layout conversion

Figure 2 Weight data layout conversion
直接卷積算法如式(1) 所示,單次只能計算一個輸出值,效率較低,且需要對原始輸入進行補0,存在較大的數據搬運開銷。
pF′t,c,i*st+m,j*st+n)
(1)
本文提出了一種批圖像融合卷積計算算法,可以將卷積計算轉換成大規模矩陣乘法,如圖3所示,同時也不需要對原始圖像進行補零填充。

Figure 3 Implementation of convolutional algorithm
如算法1所示,可以提前計算當前卷積區域填充0的個數,只從卷積核矩陣和輸入圖像矩陣提取實際參與運算的行與列。令卷積區域左上角的元素所在行為i、所在列為j,則其上方填充零的行數up0為Max(pad-i,0),其下方填充零的行數down0為Max(pad+kH-H-pad,0),其左側填充零的列數left0為Max(pad-j,0),其右側填充零的列數right0為Max(j+kW-W-pad,0)。實際參與運算的輸入圖像矩陣的起始行號為i+up0-pad,起始列號為j+left0-pad。實際參與運算的卷積核矩陣的起始行號為up0,起始列號為left0。通過行號和列號即可提取對應的子矩陣。

算法1 Conv_forward輸入:F,WT。輸出:Z。步驟1 pH=H+pad*2,pW=W+2*pad;步驟2 for (int h=0;h 接下來定義被提取的卷積核子矩陣為W,輸入圖像的子矩陣為M,則有式(2): (2) 其中,x=d+i*O*nW+j*O。 從卷積層的推理過程,可以得到卷積層對輸入圖像的梯度,如式(3)所示: (3) 其中,i′=i*st+m,j′=j*st+n,i∈[0,nH-1],j∈[0,nW-1]。式(3)可繼續化簡為式(4): (4) 其中,m=i′-i*st,n=j′-j*st,且m∈[0,kH-1],n∈[0,kW-1]。當(i′-m)/st∈[0,nH-1]且(i′-m)可被st整除,同時(j′-n)/st∈[0,nH-1]且(j′-n)可被st整除時,式(4)可進一步化簡為式(5): (5) 令δdZl,o,i*st,j*st=dZ′l,o,i,j,且對于δdZ′l,o,k,t,若k不可被st整除或t不可被st整除,則δdZ′l,o,k,t為0。由式(5)可推出式(6): (6) 其中,i′≥m且j′ ≥n。 令δpdZ′l,o,i+kH-1,j+kW-1=δdZ′l,o,i,j,且對于δpdZ′l,o,k,t,若k∈[0,kH-2]或t∈[0,kW-2] ,則δpdZ′l,o,k,t為0。由式(6)可推出式(7): (δpdZ′l,o,i′-m+kH-1,j′-n+kW-1×WEIo,c,m,n) (7) 令m′=kH-1-m,n′=kW-1-n,可得到式(8): WEIo,c,kH-1-m′,kW-1-n′) (8) 式(8)可等價轉換為式(9): WEIo,c,kH-1-m,kW-1-n) (9) 令rotWo,c,m,n=WEIo,c,kH-1-m,kW-1-n,如式(10)所示。卷積核的訓練過程實質是在dZ′的每個矩陣行列間直接插入st-1行列零元素后(即δdZ),再在元素外圍填充高度和寬度為kH-1和kW-1的零元素后的梯度矩陣(即pδdZ′),作為新的卷積層的輸入。旋轉180°后的卷積核矩陣rotW作為卷積核。兩者進行卷積計算得到的結果。但是,由于填充零的過程中存在大量的數據搬移開銷,效率低下。本文提出了算法2,避免了填充零帶來的額外開銷,同樣以矩陣乘法的形式實現了其中的核心計算。 (10) 算法2 Conv_backward輸入:dZ,Weight。輸出:dF。步驟1 for (int h=pad;h 為了確定rotW矩陣中真正參與運算的行與列,算法2中使用hS來記錄卷積核中參與運算的起始行號,使用wS來記錄卷積核中參與運算的起始列號。原梯度矩陣的起始行號h0對應pδdZ′中梯度矩陣的第h0*st+kH-1行。原梯度矩陣的起始列號w0對應rotW每個矩陣中的第w0*st+kW-w列。實際參與卷積計算的梯度矩陣每一列的元素間隔st-1個元素,每一行間隔st-1個元素。最后類似算法1中提取子矩陣的方式,在不對原數據填充零的情況下,完成卷積層的訓練。 針對FT-M7004的體系結構,本文使用算法3來高效實現最大池化層的計算。 本節使用index矩陣記錄Buffer中每一列的最大值,并計算其對應F中的行號,得到輸出圖像的子矩陣。 以最大池化層為例,對于每一個輸出位置Z′n,d,i,j,都需要找到其對應的輸入位置F′n,d,i′,j′,并繼續傳播輸入的梯度。具體算法實現如算法4所示。 算法4 MaxPool2d_backward輸入:dZ。輸出:dF。步驟1 for(int c=0;c 算法4中pos代表推理時最大值所對應的行號,k代表最大值對應的列,算法的核心是將dZ矩陣第row行第k列的值累加至dF中的第pos行第k列。 全連接層的本質是矩陣乘法,其計算如式(11)和式(12)所示: (11) Z=WT×F+bias (12) 具體計算如算法5所示。 算法5 FC_forward輸入:F,WT,Bias。輸出:Z。步驟1 for (int i=0;i 每次將矩陣WT第i行第j個元素乘以矩陣F第j行元素,并將結果累加至矩陣Z的第i行,相較樸素矩陣乘法擁有更好的空間局部性。 從全連接層的推理過程不難得出對權重和偏置求導的式(13)和式(14): (13) (14) dW[i,k]的值即為dZ的第i行與F的第k行相乘,dF[k,j]的值為dZ的第j列與WT的第k列相乘,如式(15)所示: (15) 然而向量加速器在矩陣間列運算上的效果表現不佳,所以需要對式(15)進行轉換,轉置矩陣為WT,則有式(16): (16) 所以,dF就等于轉置后的WT矩陣與dZ矩陣進行矩陣乘法。具體算法如算法6所示。 算法6 FC_backward輸入:dZ,lr。輸出:dF。步驟1 for (int i=0;i 由式(13)可知,bias梯度的每一個值實際上對應了dZ矩陣每一行的和。 面向FT-M7004平臺,卷積神經網絡推理和訓練算法的優化需要經過以下步驟:首先,需要對數據進行預處理,將圖像數據和權重數據的布局進行調整;其次,將輸入圖像數據從DDR(Double Data Rate synchronous)內存中傳輸到陣列存儲器AM(Array Memory);再次,對核心計算進行向量并行優化;最后,將訓練結果從向量空間傳輸到DDR內存中。在以上步驟中,涉及到的優化有以下幾個方面: (1)數據布局預處理; (2)DMA雙緩沖區傳輸; (3)權值共享; (4)向量并行優化。 在第1層卷積計算過程中,圖像數據通過DMA轉置傳輸到向量陣列存儲器(AM)中,單個樣本的圖像數據全部存儲在同一列中。第1層卷積計算完成后,圖像數據通過DMA傳回DDR并保持相同格式。在后續的卷積、池化、全連接等計算過程中,圖像數據的存儲格式保持不變。這種數據格式有助于將大量小規模的卷積計算直接轉化為大規模的矩陣乘法,并以行連續的方式進行數據訪問,可以最大限度地實現計算的向量化和并行化,提高計算性能和內存訪問效率。 本文提出DMA 雙緩沖區的數據搬移優化策略。首先,在AM中劃分一塊區域用于存放輸入圖像數據;其次,將該區域劃分為A和B2個緩沖區,在將一個輸入圖像的子矩陣傳入A緩沖區后,開始計算的同時,將下一個輸入圖像的子矩陣傳入B緩沖區;在A緩沖區計算完之后,再將下一個輸入子矩陣傳入A緩沖區,同時進行B緩沖區的計算。采用這種方式可以實現計算與數據搬移重疊,若數據傳輸時間小于計算時間,則可以有效隱藏數據傳輸時間,從而提高整體計算效率。 卷積權重數據通過DMA廣播傳輸到每個核的標量存儲器SM(Scalar Memeory)。只需一次DDR數據訪問即可實現所有參與計算的圖像的權重數據共享,可以大大減少權重數據的傳輸時間,同時最大程度地實現權重數據的共享。 權重數據通過標量Load指令讀入第k個標量寄存器(Rk),然后通過廣播指令傳送到第k個向量寄存器(VRK)。圖像數據通過向量Load指令讀入第i個向量寄存器(VRi)。VRK和VRi的乘加并行計算是使用SIMD的向量化計算。 向量處理器的并行計算效率可以通過標量和向量之間的協同計算來最大化。 本文的實驗目標平臺是FT-M7004,另外選擇了NVIDIA?的GTX 1080、Pascal Titan X和Maxwell Titan X進行對比實驗。 本文選取了不同批大小的圖像數量作為輸入,使用Caffe框架推理和訓練VGG16模型的結果作為輸出,將兩者轉換為FT-M7004上的數據布局用于對照。結果如表1所示,可以看到,對于不同的批圖像大小,本文的推理和訓練算法均能輸出正確的結果。 Table 1 Results correctness analysis 5.3.1 卷積層推理性能分析 衡量卷積層算法性能的一個重要指標是計算效率。計算效率可通過實際性能與理論峰值性能的比值來得到。測試結果如圖4所示,分別列出了VGG16模型中13種不同的卷積層在推理時的計算效率。隨著卷積核個數的增多,計算效率得到了穩步提升。在最后一個卷積層,計算效率甚至可以超過100%,這是因為本文提出的算法不需要額外填充零,理論峰值性能考慮到了填充零帶來的影響,所以偏低。 Figure 4 Convolution computation efficiency of VGG16(Inference) 5.3.2 卷積層訓練性能分析 卷積層訓練性能測試結果如圖5所示,分別列出了VGG16模型中12種不同的卷積層在訓練時的計算效率。可以看到,隨著卷積核個數的增多,計算效率依次增加。 Figure 5 Convolution computation efficiency of VGG16(Training) 5.3.3 池化層推理性能分析 池化層推理性能測試結果如圖6所示,分別列出了VGG16模型中5種不同的池化層推理時的計算效率和數據訪問效率,其中折線表示計算效率。從圖6可以看出,池化層的計算效率很低,平均約為4.00%。這是由于池化層的計算量較小,大部分時間開銷集中在數據搬移上。然而,池化層的數據訪問效率非常高,平均約為80.00%。這是因為池化層所有數據訪問都是根據本文提出的算法以訪問矩陣行的形式實現的。 Figure 6 Performance of pooling layer(Inference) 5.3.4 池化層訓練性能分析 池化層訓練性能測試結果如圖7所示,分別列出了VGG16模型中5種不同的池化層訓練時的的計算效率和數據訪問效率,其中折線表示計算效率。從圖7可以看出,池化層在訓練時的計算效率很低,平均約為2.39%,數據訪問效率平均約為47.59%。造成池化層訓練性能不如推理性能的主要原因在于,根據本文提出的訓練算法,通過數組記錄最大值位置的方式不能實現對矩陣的逐行訪問,更多時間花費在了不規則的數據訪問上;而池化層的計算量占比極小,對性能影響不大。 Figure 7 Performance of pooling layer(Training) 5.3.5 全連接層性能分析 全連接層性能測試結果如圖8和圖9所示,分別列出了VGG16模型中3種不同的全連接層在推理和訓練時的計算效率。由于全連接層的矩陣較大,最小的權重矩陣尺寸為4096*1000,最大尺寸為25088*4096,所以計算效率極高,推理時計算效率平均達到了93.17%,訓練時計算效率平均達到了81.98%。全連接層訓練時,本質上也采用了矩陣乘法的形式,所以能達到較高的計算效率。 Figure 8 Computation efficiency of fully connected layer(Inference) Figure 9 Computation efficiency of fully connected layer(Training) 5.3.6 與GPU平臺的性能對比 與GPU平臺的性能對比結果如表2和圖10所示。表2是FT-M7004與其他3款高性能GPU在VGG16模型上的推理延遲(單位為s)和吞吐量(單位為fps)測試結果。在推理延遲方面,每推理一幅圖像,GTX 1080的用時為0.068 8 s,Pascal TitanX的為0.006 0 s,MaxWell TitanX的為0.010 8 s,而FT-M7004的為0.090 0 s。吞吐量方面,GTX 1080每秒鐘可推理111幅圖像,Pascal TitanX每秒可推理163幅圖像,MaxWell TitanX每秒可推理92幅圖像,而FT-M7004則每秒可推理16幅圖像。產生這一性能差距的原因在于3款高性能GPU的峰值性能遠高于FT-M7004的,GTX 1080的峰值性能為9 TFlops,Pascal TitanX的為11 TFlops,MaxWell TitanX的為6.7 TFlops,而擁有4個加速器核心的FT-M7004的峰值性能為512 GFlops。圖10分別列出了4種硬件在VGG16模型上的計算效率。在推理時,FT-M7004的計算效率能達到87.76%,效果最為出色。在訓練時,FT-M7004的計算效率為59.74%,僅次于GTX 1080的65.52%。這是因為GTX 1080的浮點運算能力峰值和帶寬比FT-M7004平臺的高,訓練時需要的計算量和訪存量更大。 Table 2 Analysis of inference delay and throughput表2 推理延遲與吞吐量分析 Figure 10 Performance comparison of different platforms 面向FT-M7004平臺,本文完成了對卷積算子、池化算子和全連接算子的優化。本文結合 FT-M7004平臺的特性,使用向量并行化、DMA雙緩沖傳輸和向量并行優化等優化方法,提高了程序 的性能。實驗結果表明,在 FT-M7004平臺上,本文提出的算法能夠較好地考慮到體系結構的特點,實現極高的計算效率。同時,本文還與NVIDIA GPU平臺進行了實驗對比,推理時計算效率領先20%以上,訓練時計算效率雖然不是最佳,但性能差距不大。后續將針對其他深度學習算子完善其在FT-M7004平臺上的實現與優化。3.4 卷積層訓練算法

3.5 池化層推理算法
3.6 池化層訓練算法

3.7 全連接層推理算法

3.8 全連接層訓練算法

4 面向FT-M7004平臺的優化
4.1 數據布局預處理
4.2 DMA雙緩沖區傳輸
4.3 權值共享
4.4 向量并行優化
5 實驗與結果分析
5.1 實驗環境
5.2 正確性分析

5.3 性能分析








6 結束語