Tvm一些基本技术
Tvm一些基本技術
一、總體流程:
TVM的工作流程:首先,將網絡表示成統一的表示形式(Intermediate Representation),并進行一些可重用的圖優化;然后,利用不同的后端生成對應設備代碼,如圖1所示。
圖1 tvm 工作流程
首先,將不同的框架下的模型載入,并使用NNVM將模型轉換成中間表示的計算圖,并對圖進行優化,如算子融合、減枝、圖變換等;然后,TVM對張量運算進行優化,TVM將代碼的調度和計算分開(計算:定義需要進行的運算,調度:具體如何來進行運算);最后,使用不同的后端,來生成對應設備代碼,如圖1所示,使用LLVM生成x86,ARM和Javescript/WASM系統代碼,OpenCL、Metal和CUDA生成對應的GPU代碼,通過這種中間堆棧(IR Stack)表示的方式,實現端到端的深度學習模型優化和部署,這種方式將實現op的復雜度轉移到了編譯規則的復雜度。
二、優化計算圖
1、算子融合(operator Fusion)
算子融合,即將多個算子組合在一起放到同一個核中,通過算子融合的方式,不需要將中間結果保存到全局內存,進而減少執行所需要的時間,已知的算子融合分為四種,如圖2所示:
圖2 算子融合示意圖
injective(單射性):一到一的映射,如:add / sqrt / exp / sum 等操作算子(operator);
reduction(簡約):多到少的映射,如:sum / max / min等操作操作算子(operator);
complex-out-fusable:逐元素復用映射到輸出,如:conv2d / bn / relu等操作算子(operator);
opaque:不能被復用
這種算子組合太多了,專門針對這些組合手寫底層優化不太現實,需要做一些自動代碼生成。
2、數據布局變換:
當代計算架構中,從內存中載入數據的時間要遠遠大于進行一次浮點運算所耗費的時間,要重復使用載入內存或寄存器中的數據。
首先看一下3x3的卷積操作,如圖3所示:
圖3 無tile的3x3卷積操作示意圖
不采用tile的方式,每個線程載入一個3x3大小輸入得到一個輸出,16個線程需要進行16x9次數據載入,如果采用tile方式,如圖4所示:
圖4 有tile的數據載入
采用tile方式時,每個線程載入4x4大小輸入得到2x2大小的輸出,4個線程需要進行4x16次數據載入。
三、優化張量計算
張量表達語言(Tensor Expression Language):直接描述每一個單元如何計算。
這樣的tensor表示(數學公式表達),可以涵蓋幾乎所有的高層算子,可以很容易做代碼生成,因為對應的表達式已經確定了。然后就是將tensor expression映射到不同硬件上:
這里涉及到的問題有:算子張量化的問題、cache問題、數據類型問題(float32,float16,、int8)
解決方案: 將所有手工優化的可能(10億級別的)總結起來,并將他們作為搜索空間的一部分,然后自動進行搜索,這里采用auto-tvm來自動進行搜素每個算子的最優實現。
tvm的上限比手寫優化做得更好
如果是機器和人同時去解決一個問題的優化,人通過不斷的去解決,可以做到比機器好一些,實際上,機器不一定要和人解決一樣的問題,比如融合算子,其可能性太多,人可能沒有力氣去優化這些融合算子,機器通過去解決這些人沒有解決的問題,進而達到更高的效率;反過來,當搜索空間越來越大,包含了人所有的搜索空間時,這時,哪怕直接和人的手寫優化一一對應,機器也可以達到和人做的優化差不多,甚至更好都有可能。
總之:
總結
- 上一篇: 北汽蓝谷和北汽新能源
- 下一篇: Tengine AIFramework框