TinyML-TVM是如何驯服Tiny的(下)
TinyML-TVM是如何馴服Tiny的(下)
Lazy Execution
實際上,隨著通信開銷開始占主導地位,一旦用戶請求,就執行算子的開銷變得非常昂貴。可以通過延遲評估直到用戶需要調用的結果來提高系統的吞吐量。
從實現的角度來看,現在需要在主機端積累函數調用元數據,然后再將其刷新到設備,而不是急于序列化參數元數據和UTVMTask數據。設備runtime也需要一些改變:
(1)現在必須有一個UTVMTask的全局數組
(2)需要循環執行每個任務。
帶MicroTVM的AutoTVM
到目前為止,所描述的runtime對于模型部署似乎不是很有用,因為它非常依賴于主機。這是有意的,而runtime實際上是為另一個目標而設計的:AutoTVM支持。
一般來說,AutoTVM提出候選內核,在目標后端隨機輸入運行,然后使用計時結果來改進其搜索過程。考慮到AutoTVM只關心單個算子的執行,將runtime設計為面向算子,而不是面向模型。但是,在μTVM的情況下,與設備的通信通常將支配執行時間。延遲執行允許多次運行同一個算子,而不將控制權返回給主機,因此通信成本在每次運行中分攤,可以更好地了解性能配置文件。
由于AutoTVM需要在大量候選內核上進行快速迭代,因此μTVM基礎設施目前僅使用RAM。然而,對于自托管runtime,肯定需要同時使用閃存和RAM。
托管圖形runtime
雖然托管runtime是為AutoTVM設計的,但是仍然可以運行完整的模型(只要沒有任何控制流)。此功能僅通過使用TVM的graph runtime免費提供,但需要使用μTVM上下文。事實上,在運行圖時對主機的唯一依賴是用于張量分配和算子調度(這只是依賴圖的一種拓撲類型)。
Evaluation
有了這一基礎架構,試圖回答以下問題:
μTVM真的不受設備限制嗎?
使用μTVM進行優化實驗需要多少算力?
為了評估(1),對兩個目標進行了實驗:
Arm STM32F746NG開發板,具有Cortex-M7處理器
μTVM主機模擬設備,它在主機上創建一個內存競技場,與主機接口,就好像它是一個裸機設備一樣。
為了評估(2),將探索Arm板的優化,以使成本最大化。
作為比較,使用Arm從本教程中提取了一個量化的CIFAR-10cnn。CMSIS-NN(Arm專家高度優化的內核庫)被用作算子庫,這使CNN成為完美的評估目標,因為現在可以在Arm板上直接比較μTVM和CMSIS-NN的結果。
Methodology
Arm-Specific Optimizations
使用了TVM from HEAD(提交9fa8341)、CMSIS-NN 5.7.0版(提交a65b7c9a)、STM32CubeF7的1.16.0版以及Arm GNU Tools for Arm嵌入式處理器9-2019-q4-major 9.2.1工具鏈(修訂版277599)中的GCC。在UbuntuW620X主機上運行UbuntuW620X主機和Ry299X內核運行的UbuntuW329X處理器。
特定于Arm的優化
對于CMSIS-NN,第一個卷積映射到RGB卷積實現(特別是用于輸入層),后兩個映射到 “快速”卷積實現。在之前的通用優化之后,覺得性能已經足夠接近RGB卷積,但是對于快速卷積結果卻不滿意。幸運的是,Arm發布了一篇文章,描述了CMSIS-NN中使用的優化,發現從SIMD內部函數得到了大量的加速。本文提出了一個使用SIMD內部函數的矩陣乘法微內核(下圖)。雖然可以在TVM的代碼生成設施中添加對內部函數的一流支持,但從長遠來看,這可能是TVM提供的一種“快速而骯臟”的支持SIMD的解決方案。
Diagram from CMSIS-NN paper showing a 2x2 matrix multiplication microkernel
CMSIS-NN論文中的圖表顯示了2x2矩陣乘法微內核
張量化的工作原理是定義一個可以插入TVM運算符最內層循環的微內核。使用這種機制,添加對Arm板的SIMD支持就像在C中定義一個微內核(在這里找到)一樣簡單,反映了論文中的實現。定義了一個使用這個微內核(在這里可以找到)的計劃,進行自動調整,然后得到“μTVM SIMD tuned”結果。
雖然能夠使用SIMD微核進行直接卷積,但CMSIS-NN使用稱之為“部分im2col”的實現策略,在性能和內存使用之間進行了權衡。部分im2col一次只生成幾個列,而不是一次顯示整個im2col矩陣。然后,對于每個批次,可以將矩陣發送給SIMD matmul函數。
假設是,在其他優化中,可以通過自動調整找到最佳的批量大小。在實踐中,發現部分im2col比直接卷積實現慢得多,所以在剩下的結果中沒有包含它。
當然,還可以從CMSIS-NN中進行其他優化,以進一步縮小差距:
批量擴展int8權重到int16,以減少SIMD的重復擴展
將卷積拆分為3x3塊以減少填充檢查
本文目標是展示μTVM能做些什么。甚至連代碼庫都不能使用它,因為其他的代碼庫也不能。
End-To-End CIFAR-10
在探索了卷積的優化之后,開始測量對端到端性能的影響。對于Arm板,收集了未調整的結果、未使用任何SIMD的結果、使用SIMD調整的結果以及使用CMSIS-NN的結果。對于模擬的主機設備,只收集未調整的結果和通用的優化結果。
https://github.com/areusch/microtvm-blogpost-eval
int8-quantized CIFAR-10 CNN comparison on an Arm STM32F746NG (re-posted from above)
int8-quantized CIFAR-10 CNN comparison on μTVM’s emulated host device
在Arm STM32系列板上,性能比初始未調諧的操作員提高了約2倍,而且結果更接近CMSIS-NN。此外,還能夠顯著提高主機模擬設備的性能。雖然x86的數字并不意味著什么,表明可以使用相同的基礎架構(μTVM)在完全不同的體系結構上優化性能。
隨著將這種方法擴展到更廣泛的范圍,請繼續關注更多的端到端基準測試。
Self-Hosted Runtime: The Final Frontier
The envisioned μTVM optimization and deployment pipeline
雖然正如上面所演示的那樣,在當前runtime已經可以獲得端到端基準測試結果,但是以獨立的能力部署這些模型目前仍在路線圖上。差距在于面向AutoTVM的runtime,當前依賴于主機來分配張量和調度函數執行。為了在邊緣有用,需要一個通過μTVM的管道,它生成一個在裸機設備上運行的二進制文件。然后,用戶將能夠通過在邊緣應用程序中包含這個二進制文件,輕松地將fastml集成到應用程序中。這條管道的每一個階段都已經準備好了,現在只是把它們粘在一起的問題,所以期待很快在這方面的更新。
Conclusion
用于單核優化的MicroTVM現在已經準備好了,并且是該用例的選擇。隨著現在構建自托管部署支持,希望也能將μTVM作為模型部署的選擇。然而,這不僅僅是一個旁觀者的運動-記住:這都是開源的!μTVM仍處于早期階段,因此每個個體都會對其軌跡產生很大影響。如果有興趣合作,查看《TVM貢獻者指南》,或者直接進入TVM論壇討論想法。
總結
以上是生活随笔為你收集整理的TinyML-TVM是如何驯服Tiny的(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TinyML-TVM是如何驯服Tiny的
- 下一篇: 自主数据类型:在TVM中启用自定义数据类