摘要:以單算子開發為例,帶你了解算子開發及測試全流程。
為什么要自定義算子
深度學習算法由一個個計算單元組成,我們稱這些計算單元為算子(Operator,簡稱Op)。算子是一個函數空間到函數空間上的映射O:X→X;從廣義上講,對任何函數進行某一項操作都可以認為是一個算子。於我們而言,我們所開發的算子是網絡模型中涉及到的計算函數。在Caffe中,算子對應層中的計算邏輯,例如:卷積層(Convolution Layer)中的卷積算法,是一個算子;全連接層(Fully-connected Layer, FC layer)中的權值求和過程,也是一個算子。
Ascend 模型轉換導航
絕大多數情況下,由於昇騰AI軟件棧支持絕大多數算子,開發者不需要進行自定義算子的開發,只需提供深度學習模型文件,通過離線模型生成器(OMG)轉換就能夠得到離線模型文件,從而進一步利用流程編排器(Matrix)生成具體的應用程序。既然如此,為什么還需要自定義算子呢?這是因為在模型轉換過程中出現了算子不支持的情況,例如昇騰AI軟件棧不支持模型中的算子、開發者想修改現有算子中的計算邏輯、或者開發者想自己開發算子來提高計算性能,這時就需要進行自定義算子的開發了。
TBE算子開發流程
昇騰AI軟件棧提供了TBE算子開發框架,開發者可以基於此框架使用Python語言開發自定義算子。首先,我們來了解一下什么是TBE。TBE的全稱為Tensor Boost Engine,即張量加速引擎,是一款華為自研的算子開發工具,用於開發能夠運行在NPU(Neural-network Processing Unit:神經網絡處理器)上的TBE算子,該工具是在業界著名的開源項目TVM(Tensor Virtual Machine)基礎上擴展的,提供了一套Python API來實施開發活動。在本次開發實踐中,NPU特指昇騰AI處理器。
通過TBE進行算子開發的方式有兩種:特定域語言開發(DSL開發)和TVM原語開發(TIK開發)。DSL開發相對簡單,適用於入門級的開發者。其特點是TBE工具提供自動優化機制,給出較優的調度流程,開發者僅需要了解神經網絡和TBE DSL相關知識,便可指定目標生成代碼,進一步被編譯成專用內核。TIK開發難度較高,適用於對於TVM編程及達芬奇結構都非常了解的開發者使用。這種方式的接口偏底層,需開發者自己控制數據流及算子的硬件調度。作為入門課程,我們這次使用的DSL開發方式。
TBE算子開發流程
接下來,我們就以一個簡單的單算子開發為例,了解一下開發過程。
- 目標:
用TBE-DSL方式開發一個Sqrt算子
- 確定算子功能:
Sqrt算子功能是對Tensor中每個原子值求開方,數學表達式為y=
- 確定使用的計算接口:
根據當前TBE框架可支持的計算描述API,可采用如下公式來表達Sqrt算子的計算過程
算子代碼的實現可分為以下步驟:
1)算子入參
shape:Tensor的屬性,表示Tensor的形狀,用list或tuple類型表示,例如(3, 2, 3)、(4, 10);
dtype:Tensor的數據類型,用字符串類型表示,例如“float32”、“float16”、“int8”等。
2)輸入Tensor占位符
data = tvm.placeholder(shape, name="data", dtype=input_dtype)
tvm.placeholder()是TVM框架的API,用來為算子執行時接收的數據占位,通俗理解與C語言中%d、%s一樣,返回的是一個Tensor對象,上例中使用data表示;入參為shape,name,dtype,是為Tensor對象的屬性。
3)定義計算過程
4)定義調度過程
5)算子構建
6)測試驗證
誒等一等,還沒結束呢。只有在仿真環境中驗證了算子功能的正確性,自定義算子的開發才算完成。
ST測試流程
我們需要用ST測試(即System Test系統測試)在仿真環境中測試算子邏輯的正確性以及能否正確地生成.o和.json文件。想知道具體是怎么測試的嗎?與其看一大段枯燥的文字描述,不如來沙箱實驗室親自體驗一番,一定更加直觀。
讀到這里,你是不是對自己的自定義算子開發能力更加有信心了?何不來華為雲學院學課程、做實驗、考證書來驗證一下呢?喏,就是這門微認證啦:基於昇騰AI處理器的算子開發