離線模型生成以卷積神經(jīng)網(wǎng)絡(luò)為例,在深度學(xué)習(xí)框架下構(gòu)造好相應(yīng)的網(wǎng)絡(luò)模型,并且訓(xùn)練好原始數(shù)據(jù),再通過離線模型生成器進(jìn)行算子調(diào)度優(yōu)化、權(quán)重?cái)?shù)據(jù)重排和壓縮、內(nèi)存優(yōu)化等,最終生成調(diào)優(yōu)好的離線模型。離線模型生成器主要用來生成可以高效執(zhí)行在昇騰AI處理器上的離線模型。

離線模型生成器的工作原理如上圖所示,在接收到原始模型后,對(duì)卷積神經(jīng)網(wǎng)絡(luò)模型進(jìn)行模型解析、量化、編譯和序列化四個(gè)步驟:
1、解析
在解析過程中,離線模型生成器支持不同框架下的原始網(wǎng)絡(luò)模型解析,提煉出原始模型的網(wǎng)絡(luò)結(jié)構(gòu)、權(quán)重參數(shù),再通過圖的表示法,由統(tǒng)一的中間圖(IR Graph)來重新定義網(wǎng)絡(luò)結(jié)構(gòu)。中間圖由計(jì)算節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)構(gòu)成,計(jì)算節(jié)點(diǎn)有不同功能的TBE算子組成,而數(shù)據(jù)節(jié)點(diǎn)專門接收不同的張量數(shù)據(jù),為整個(gè)網(wǎng)絡(luò)提供計(jì)算需要的各種輸入數(shù)據(jù)。這個(gè)中間圖是由計(jì)算圖和權(quán)值構(gòu)成,涵蓋了所有原始模型的信息。中間圖為不同深度學(xué)習(xí)框架到昇騰AI軟件棧搭起了一座橋梁,使得外部框架構(gòu)造的神經(jīng)網(wǎng)絡(luò)模型可以輕松轉(zhuǎn)化為昇騰AI處理器支持的離線模型。
2、量化

如圖所示,解析完成后生成了中間圖,如果模型還需要進(jìn)行量化處理,則可以基于中間圖的結(jié)構(gòu)和權(quán)重,通過自動(dòng)量化工具來進(jìn)行量化。在算子中,可以對(duì)權(quán)重、偏置進(jìn)行量化,在離線模型生成過程中,量化后的權(quán)重、偏置會(huì)保存在離線模型中,推理計(jì)算時(shí)可以使用量化后的權(quán)重和偏置對(duì)輸入數(shù)據(jù)進(jìn)行計(jì)算,而校準(zhǔn)集用于在量化過程中訓(xùn)練量化參數(shù),保證量化精度。如果不需要量化,則直接進(jìn)行離線模型編譯生成離線模型。
量化方式分為數(shù)據(jù)偏移量化和無偏移量化,需要輸出量化度(Scale)和量化偏移(Offset)兩個(gè)參數(shù)。在數(shù)據(jù)量化過程中,指定無偏移量化時(shí),數(shù)據(jù)都采用無偏移量化模式,計(jì)算出量化數(shù)據(jù)的量化度;如果指定數(shù)據(jù)偏移量化,則數(shù)據(jù)采用偏移模式,則會(huì)計(jì)算輸出數(shù)據(jù)的量化度和量化偏移。在權(quán)重量化過程中,由于權(quán)重對(duì)量化精度要求較高,因此始終采用無偏移量化模式。比如根據(jù)量化算法對(duì)權(quán)重文件進(jìn)行INT8類型量化,即可輸出INT8權(quán)重和量化度。而在偏置量化過程中,根據(jù)權(quán)重的量化度和數(shù)據(jù)的量化度,可將FP32類型偏置數(shù)據(jù)量化成INT32類型數(shù)據(jù)輸出。
在對(duì)模型大小和性能有更高要求的時(shí)候可以選擇執(zhí)行量化操作。離線模型生成過程中量化會(huì)將高精度數(shù)據(jù)向低比特?cái)?shù)據(jù)進(jìn)行量化,讓最終的離線模型更加輕量化,從而達(dá)到節(jié)約網(wǎng)絡(luò)存儲(chǔ)空間、降低傳輸時(shí)延以及提高運(yùn)算執(zhí)行效率的目的。在量化過程中,由于模型存儲(chǔ)大小受參數(shù)影響很大,因此離線模型生成器重點(diǎn)支持卷積算子、全連接算子以及深度可分離卷積(ConvolutionDepthwise)等帶有參數(shù)算子的量化。
3、編譯
在完成模型量化后,需要對(duì)模型進(jìn)行編譯,編譯分為算子編譯和模型編譯兩個(gè)部分,算子編譯提供算子的具體實(shí)現(xiàn),模型編譯將算子模型聚合連接生成離線模型結(jié)構(gòu)。
-算子編譯
算子編譯進(jìn)行算子生成,主要是生成算子特定的離線結(jié)構(gòu)。算子生成分為輸入張量描述、權(quán)重?cái)?shù)據(jù)轉(zhuǎn)換和輸出張量描述三個(gè)流程。在輸入張量描述中,計(jì)算每個(gè)算子的輸入維度、內(nèi)存大小等信息,并且在離線模型生成器中定義好算子輸入數(shù)據(jù)的形式。在權(quán)重?cái)?shù)據(jù)轉(zhuǎn)換中,對(duì)算子使用的權(quán)重參數(shù)進(jìn)行數(shù)據(jù)格式(比如FP32到FP16的轉(zhuǎn)換)、形狀轉(zhuǎn)換(如分形重排)、數(shù)據(jù)壓縮等處理。在輸出張量描述中,計(jì)算算子的輸出維度、內(nèi)存大小等信息。

算子生成流程如圖所示,算子生成過程中需要通過TBE算子加速庫(kù)的接口對(duì)輸出數(shù)據(jù)的形狀進(jìn)行分析確定與描述,通過TBE算子加速庫(kù)接口也可實(shí)現(xiàn)數(shù)據(jù)格式的轉(zhuǎn)換。離線模型生成器收到神經(jīng)網(wǎng)絡(luò)生成的中間圖并對(duì)中間圖中的每一節(jié)點(diǎn)進(jìn)行描述,逐個(gè)解析每個(gè)算子的輸入和輸出。離線模型生成器分析當(dāng)前算子的輸入數(shù)據(jù)來源,獲取上一層中與當(dāng)前算子直接進(jìn)行銜接的算子類型,通過TBE算子加速庫(kù)的接口進(jìn)入算子庫(kù)中尋找來源算子的輸出數(shù)據(jù)描述,然后將來源算子的輸出數(shù)據(jù)信息返回給離線模型生成器,作為當(dāng)前算子的具體輸入張量描述。因此了解了來源算子的輸出信息就可以自然的獲得當(dāng)前算子輸入數(shù)據(jù)的描述。
如果在中間圖中的節(jié)點(diǎn)不是算子,而是數(shù)據(jù)節(jié)點(diǎn),則不需要進(jìn)行輸入張量描述。如果算子帶有權(quán)值數(shù)據(jù),如卷積算子和全連接算子等,則需要進(jìn)行權(quán)重?cái)?shù)據(jù)的描述和處理。如果輸入權(quán)重?cái)?shù)據(jù)類型為FP32,則需要通過離線模型生成器調(diào)用類型轉(zhuǎn)化(ccTransTensor)接口,將權(quán)重轉(zhuǎn)換成FP16數(shù)據(jù)類型,滿足AI Core的數(shù)據(jù)類型需求。完成類型轉(zhuǎn)換后,離線模型生成器調(diào)用形狀設(shè)置(ccTransFilter)接口對(duì)權(quán)重?cái)?shù)據(jù)進(jìn)行分形重排,讓權(quán)重的輸入形狀可以滿足AI Core的格式需求。在獲得固定格式的權(quán)重后,離線模型生成器調(diào)用TBE提供的壓縮優(yōu)化(ccCompressWeight)接口,對(duì)權(quán)重進(jìn)行壓縮優(yōu)化,縮小權(quán)重存儲(chǔ)空間,使得模型更加輕量化。在對(duì)權(quán)重?cái)?shù)據(jù)轉(zhuǎn)換完后返回滿足計(jì)算要求的權(quán)重?cái)?shù)據(jù)給離線模型生成器。
權(quán)重?cái)?shù)據(jù)轉(zhuǎn)化完成后,離線模型生成器還需要對(duì)算子的輸出數(shù)據(jù)信息進(jìn)行描述,確定輸出張量形式。對(duì)于高層次復(fù)雜算子,如卷積算子和池化算子等,離線模型生成器可以直接通過TBE算子加速庫(kù)提供的計(jì)算接口,并結(jié)合算子的輸入張量信息和權(quán)重信息來獲取算子的輸出張量信息。如果是低層次簡(jiǎn)單算子,如加法算子等,則直接通過算子的輸入張量信息來確定輸出張量信息,最終再存入離線模型生成器中。按照上述運(yùn)行流程,離線模型生成器遍歷網(wǎng)絡(luò)中間圖中所有算子,循環(huán)執(zhí)行算子生成步驟,對(duì)所有算子的輸入輸出張量和權(quán)重?cái)?shù)據(jù)描述,完成算子的離線結(jié)構(gòu)表示,為下一步模型生成提供算子模型。
-模型編譯
編譯過程中完成算子生成后,離線模型生成器還要進(jìn)行模型生成,獲取模型的離線結(jié)構(gòu)。離線模型生成器獲取中間圖,對(duì)算子進(jìn)行并發(fā)的調(diào)度分析,將多個(gè)中間圖節(jié)點(diǎn)進(jìn)行執(zhí)行流拆分,獲得多個(gè)由算子和數(shù)據(jù)輸入組成的執(zhí)行流,執(zhí)行流可以看作是算子的執(zhí)行序列。對(duì)于沒有相互依賴的節(jié)點(diǎn),直接分配到不同的執(zhí)行流中。如果不同執(zhí)行流中節(jié)點(diǎn)存在依賴關(guān)系,則通過rtEvent同步接口進(jìn)行多執(zhí)行流間同步。在AI Core運(yùn)算資源富余的情況下,多執(zhí)行流拆分可以為AI Core提供多流調(diào)度,從而提升網(wǎng)絡(luò)模型的計(jì)算性能。但是如果AI Core并行處理任務(wù)較多時(shí),會(huì)加劇資源搶占程度,惡化執(zhí)行性能,一般默認(rèn)情況下采用單執(zhí)行流對(duì)網(wǎng)絡(luò)進(jìn)行處理,可防止因多任務(wù)并發(fā)執(zhí)行導(dǎo)致阻塞的風(fēng)險(xiǎn)。
同時(shí),基于多個(gè)算子的執(zhí)行序列的具體執(zhí)行關(guān)系,離線模型生成器可以進(jìn)行獨(dú)立于硬件的算子融合優(yōu)化以及內(nèi)存復(fù)用優(yōu)化操作。根據(jù)算子輸入、輸出內(nèi)存信息,進(jìn)行計(jì)算內(nèi)存復(fù)用,將相關(guān)復(fù)用信息寫入模型和算子描述中,生成高效的離線模型。這些優(yōu)化操作可以將多個(gè)算子執(zhí)行時(shí)的計(jì)算資源進(jìn)行重新分配,最大化減小運(yùn)行時(shí)內(nèi)存占用,同時(shí)避免運(yùn)行過程中頻繁進(jìn)行內(nèi)存分配和釋放,實(shí)現(xiàn)以最小的內(nèi)存使用和最低的數(shù)據(jù)搬移頻率來完成多個(gè)算子的執(zhí)行,提升性能,而且降低對(duì)硬件資源的需求。
4、序列化
編譯后產(chǎn)生的離線模型存放于內(nèi)存中,還需要進(jìn)行序列化。序列化過程中主要提供簽名功能給模型文件,對(duì)離線模型進(jìn)行進(jìn)一步封裝和完整性保護(hù)。序列化完成后可以將離線模型從內(nèi)存輸出到外部文件中以供異地的昇騰AI芯片調(diào)用和執(zhí)行。