如何提高算子的計(jì)算性能?怎樣修改現(xiàn)有算子的計(jì)算邏輯?昇騰AI軟件棧不支持模型中的算子怎么辦?別急別急,和我一起從單算子開發(fā)學(xué)習(xí)自定義算子開發(fā)吧!
為什么要自定義算子
深度學(xué)習(xí)算法由一個(gè)個(gè)計(jì)算單元組成,我們稱這些計(jì)算單元為算子(Operator,簡稱Op)。算子是一個(gè)函數(shù)空間到函數(shù)空間上的映射O:X→X;從廣義上講,對(duì)任何函數(shù)進(jìn)行某一項(xiàng)操作都可以認(rèn)為是一個(gè)算子。于我們而言,我們所開發(fā)的算子是網(wǎng)絡(luò)模型中涉及到的計(jì)算函數(shù)。在Caffe中,算子對(duì)應(yīng)層中的計(jì)算邏輯,例如:卷積層(ConvolutionLayer)中的卷積算法,是一個(gè)算子;全連接層(Fully-connectedLayer,F(xiàn)Clayer)中的權(quán)值求和過程,也是一個(gè)算子。

Ascend模型轉(zhuǎn)換導(dǎo)航
絕大多數(shù)情況下,由于昇騰AI軟件棧支持絕大多數(shù)算子,開發(fā)者不需要進(jìn)行自定義算子的開發(fā),只需提供深度學(xué)習(xí)模型文件,通過離線模型生成器(OMG)轉(zhuǎn)換就能夠得到離線模型文件,從而進(jìn)一步利用流程編排器(Matrix)生成具體的應(yīng)用程序。既然如此,為什么還需要自定義算子呢?這是因?yàn)樵谀P娃D(zhuǎn)換過程中出現(xiàn)了算子不支持的情況,例如昇騰AI軟件棧不支持模型中的算子、開發(fā)者想修改現(xiàn)有算子中的計(jì)算邏輯、或者開發(fā)者想自己開發(fā)算子來提高計(jì)算性能,這時(shí)就需要進(jìn)行自定義算子的開發(fā)了。
TBE算子開發(fā)流程
昇騰AI軟件棧提供了TBE算子開發(fā)框架,開發(fā)者可以基于此框架使用Python語言開發(fā)自定義算子。首先,我們來了解一下什么是TBE。TBE的全稱為TensorBoostEngine,即張量加速引擎,是一款華為自研的算子開發(fā)工具,用于開發(fā)能夠運(yùn)行在NPU(Neural-networkProcessingUnit:神經(jīng)網(wǎng)絡(luò)處理器)上的TBE算子,該工具是在業(yè)界著名的開源項(xiàng)目TVM(TensorVirtualMachine)基礎(chǔ)上擴(kuò)展的,提供了一套PythonAPI來實(shí)施開發(fā)活動(dòng)。在本次開發(fā)實(shí)踐中,NPU特指昇騰AI處理器。
通過TBE進(jìn)行算子開發(fā)的方式有兩種:特定域語言開發(fā)(DSL開發(fā))和TVM原語開發(fā)(TIK開發(fā))。DSL開發(fā)相對(duì)簡單,適用于入門級(jí)的開發(fā)者。其特點(diǎn)是TBE工具提供自動(dòng)優(yōu)化機(jī)制,給出較優(yōu)的調(diào)度流程,開發(fā)者僅需要了解神經(jīng)網(wǎng)絡(luò)和TBEDSL相關(guān)知識(shí),便可指定目標(biāo)生成代碼,進(jìn)一步被編譯成專用內(nèi)核。TIK開發(fā)難度較高,適用于對(duì)于TVM編程及達(dá)芬奇結(jié)構(gòu)都非常了解的開發(fā)者使用。這種方式的接口偏底層,需開發(fā)者自己控制數(shù)據(jù)流及算子的硬件調(diào)度。作為入門課程,我們這次使用的DSL開發(fā)方式。

TBE算子開發(fā)流程
接下來,我們就以一個(gè)簡單的單算子開發(fā)為例,了解一下開發(fā)過程。
-目標(biāo):
用TBE-DSL方式開發(fā)一個(gè)Sqrt算子
-確定算子功能:
Sqrt算子功能是對(duì)Tensor中每個(gè)原子值求開方,數(shù)學(xué)表達(dá)式為y=
-確定使用的計(jì)算接口:
根據(jù)當(dāng)前TBE框架可支持的計(jì)算描述API,可采用如下公式來表達(dá)Sqrt算子的計(jì)算過程

算子代碼的實(shí)現(xiàn)可分為以下步驟:

1.算子入?yún)?/p>

shape:Tensor的屬性,表示Tensor的形狀,用list或tuple類型表示,例如(3,2,3)、(4,10);
dtype:Tensor的數(shù)據(jù)類型,用字符串類型表示,例如“float32”、“float16”、“int8”等。
2.輸入Tensor占位符
data=tvm.placeholder(shape,name="data",dtype=input_dtype)
tvm.placeholder()是TVM框架的API,用來為算子執(zhí)行時(shí)接收的數(shù)據(jù)占位,通俗理解與C語言中%d、%s一樣,返回的是一個(gè)Tensor對(duì)象,上例中使用data表示;入?yún)閟hape,name,dtype,是為Tensor對(duì)象的屬性。
3.定義計(jì)算過程

4.定義調(diào)度過程

5.算子構(gòu)建

6.測試驗(yàn)證
誒等一等,還沒結(jié)束呢。只有在仿真環(huán)境中驗(yàn)證了算子功能的正確性,自定義算子的開發(fā)才算完成。

ST測試流程
我們需要用ST測試(即SystemTest系統(tǒng)測試)在仿真環(huán)境中測試算子邏輯的正確性以及能否正確地生成.o和.json文件。想知道具體是怎么測試的嗎?與其看一大段枯燥的文字描述,不如來 沙箱實(shí)驗(yàn)室 親自體驗(yàn)一番,一定更加直觀。
讀到這里,你是不是對(duì)自己的自定義算子開發(fā)能力更加有信心了?何不來華為云學(xué)院學(xué)課程、做實(shí)驗(yàn)、考證書來驗(yàn)證一下呢?喏,就是這門微認(rèn)證啦:基于昇騰AI處理器的算子開發(fā)