1. 程式人生 > 實用技巧 >從Winograd演算法看INT8量化及卷積加速原理

從Winograd演算法看INT8量化及卷積加速原理

Winograd演算法

主要參考了shine-lee大神的文章《卷積神經網路中的Winograd快速卷積演算法》,詳細請參閱原文。

Winograd演算法論文出自CVPR 2016的一篇 paper:Fast Algorithms for Convolutional Neural Networks

當前的流行的推理框架(加速器),如NCNNNNPACK、TNN等,可以看到,對於卷積層,大家不約而同地採用了Winograd快速卷積演算法,那到底Winograd演算法是個什麼呢。

問題定義

將一維卷積運算定義為F(m,r)m為Output Size,r為Filter Size,則輸入訊號的長度為

m+r1,卷積運算是對應位置相乘然後求和,輸入訊號每個位置至少要參與1次乘法,所以乘法數量最少與輸入訊號長度相同,記為

在行列上分別進行一維卷積運算,可得到二維卷積,記為,輸出為,卷積核為,則輸入訊號為,乘法數量至少為

若是直接按滑動視窗方式計算卷積,一維時需要次乘法,二維時需要次乘法,遠大於上面計算的最少乘法次數

使用Winograd演算法計算卷積快在哪裡?一言以蔽之:快在減少了乘法的數量,將乘法數量減少至或。

怎麼減少的?請看下面的例子。

一個例子 F(2, 3)

先以1維卷積為例,輸入訊號為,卷積核為,則卷積可寫成如下矩陣乘法形式:

如果是一般的矩陣乘法,則需要6次乘法和4次加法

,如下:

但是,卷積運算中輸入訊號轉換成的矩陣不是任意矩陣,其中有規律地分佈著大量的重複元素,比如第1行和第2行的和,卷積轉換成的矩陣乘法比一般矩陣乘法的問題域更小,這就讓優化存在了可能。

Winograd是怎麼做的呢?

其中,

乍看上去,為了計算,需要的運算次數分別為:

  • 輸入訊號d上:4次加法(減法)
  • 輸出m上:4次乘法,4次加法

在神經網路的推理階段,卷積核上的元素是固定的,因此g上的運算可以提前算好預測階段只需計算一次,可以忽略,所以一共所需的運算次數為dm上的運算次數之和,即4次乘法和8次加法

與直接運算的6次乘法和4次加法相比,乘法次數減少,加法次數增加。在計算機中,乘法一般比加法慢,通過減少減法次數,增加少量加法,可以實現加速。

1D winograd

上一節中的計算過程寫成矩陣形式如下:

其中,element-wise multiplicationHadamard product)對應位置相乘,正好,筆者在此突然想起了numpy、tensorflow、pytorch中都有的一個API:愛因斯坦求和,詳細請參閱https://www.jianshu.com/p/7a2eb2da0f60

對於二維的卷積:

對於二維情況
numpy.einnum('ij,ij->', A, B)
對於三位情況
numpy.einnum('ijk,ijk->ijk', A, B)

回到Winograd演算法,

卷積核

輸入

Filter transform矩陣,尺寸

Input transform矩陣,尺寸

Output transform矩陣,尺寸

整個計算過程在邏輯上可以分為4步:

  • Input transform
  • Filter transform
  • Hadamar product
  • Output transform

注意,這裡寫成矩陣形式,並不意味著實現時要呼叫矩陣運算的介面,一般直接手寫計算過程速度會更快,寫成矩陣只是為了數學形式。

1D to 2D,F(2, 3) to F(2x2, 3x3)

上面只是看了1D的一個例子,2D怎麼做呢?

論文中一句話帶過:

A minimal 1D algorithm F(m, r) isnested with itselfto obtain a minimal 2D algorithm,F(m×m, r×r).

其中,gr×rFilter,d為的image tile。

問題是:怎麼nested with itself

這裡繼續上面的例子,擴充套件到2D,,先寫成矩陣乘法,見下圖,圖片來自SlideShare,注意數學符號的變化,

將卷積核的元素拉成一列,將輸入訊號每個滑動視窗中的元素拉成一行。注意圖中紅線劃分成的分塊矩陣,每個子矩陣中重複元素的位置與一維時相同,同時重複的子矩陣也和一維時相同,如下所示

令,即視窗中的第0行元素,表示第1、2、3行;,

卷積運算為對應位置相乘再相加,上式中,表示長度為4的與長度為3的卷積結果,結果為長度為2的列向量,其中,和均為長度為4的列向量,進一步地,可以看成3對長度為4的列向量兩兩對應位置相乘再相加,結果為長度為4的列向量,也可以看成是4組長度為3的行向量的點積運算,同樣,也是4組長度為3的行向量的內積運算,考慮兩者的重疊部分和,恰好相當於的每一行在的對應行上進行1維卷積,上面我們已經進行了列向量卷積的Winograd推導,行向量的卷積只需將所有左乘的變換矩陣轉置後變成右乘就可以了,至此,上面的推導結果就不難得出了。

所謂的nested with itself如下圖所示,

此時,Winograd演算法的乘法次數為16(上圖4×4),而直接卷積的乘法次數為36,降低了2.25倍的乘法計算複雜度

卷積神經網路中的Winograd

要將Winograd應用在卷積神經網路中,還需要回答下面兩個問題:

  • 上面我們僅僅是針對一個小的image tile,但是在卷積神經網路中,feature map的尺寸可能很大,難道我們要實現F(224,3)嗎?
  • 在卷積神經網路中,feature map是3維的,卷積核也是3維的,3D的winograd該怎麼做?

第一個問題,在實踐中,會將input feature map切分成一個個等大小有重疊的tile,在每個tile上面進行winograd卷積。

第二個問題,3維卷積,相當於逐層做2維卷積,然後將每層對應位置的結果相加,下面我們會看到多個卷積核時更巧妙的做法。

這裡直接貼上論文中的演算法流程:

整體仍可分為4步,

  • Input transform
  • Filter transform
  • Batched-GEMM(批量矩陣乘法)
  • Output transform

演算法流程視覺化如下,圖片出自論文Sparse Winograd Convolutional neural networks on small-scale systolic arrays,與演算法對應著仔細推敲還是挺直觀的。

注意圖中的Matrix Multiplication,對應3維卷積中逐channel卷積後的對應位置求和,相當於個矩陣乘積,參與乘積的矩陣尺寸分別為,把Channel那一維消掉。

總結

  • Winograd演算法通過減少乘法次數來實現提速,但是加法的數量會相應增加,同時需要額外的transform計算以及儲存transform矩陣,隨著卷積核和tile的尺寸增大,就需要考慮加法、transform和儲存的代價,而且tile越大,transform矩陣越大,計算精度的損失會進一步增加,所以一般Winograd只適用於較小的卷積核和tile(對大尺寸的卷積核,可使用FFT加速,主要是因為現在流行小卷積核,比如1×1、3×3。FFT只有在卷積核超過大約9×9×9的時候,才有速度優勢。這是在CPU上用MKL做的測試。不過depth wised conv有取代Winograd的趨勢,因為對於1×1、3×3,如果用global depth wised conv的話是不是就體現不出Winograd的優勢,這是一個思考點),在目前流行的網路中,小尺寸卷積核是主流,典型實現如
    等,可參見NCNNFeatherCNNARM-ComputeLibrary等原始碼實現。
  • 就卷積而言,Winograd演算法和FFT類似,都是先通過線性變換將input和filter對映到新的空間,在那個空間裡簡單運算後,再映射回原空間。
  • 與im2col+GEMM+col2im相比,winograd在劃分時使用了更大的tile,就劃分方式而言,與im2col相同。

現在瞭解了Winograd演算法,但是它是如何和INT8量化結合實現更進一步的加速呢?

Int8 Convolution 流程:

input_fp32 -> quantize -> int8-conv -> Int32 -> dequantize -> output_fp32

Int8 Winograd流程:

input_fp32 -> quantize -> int8-winograd -> Int32 -> dequantize -> output_fp32

是不是結合《從TensorRT看INT8量化原理》就突然豁然開朗了呢,其中可以參考文章中的2.3 DP4A(DotProduct of48-bitsAccumulated to a 32-bit)

Reference

[1]https://www.cnblogs.com/shine-lee/p/10906535.html

[2]https://baike.baidu.com/item/%E5%93%88%E8%BE%BE%E7%8E%9B%E7%A7%AF/18894493?fr=aladdin

[3]https://www.zhihu.com/question/264307400

[4]https://zhuanlan.zhihu.com/p/67718316

[5]https://www.jianshu.com/p/7a2eb2da0f60