基于昇騰計(jì)算語(yǔ)言AscendCL開(kāi)發(fā)AI推理應(yīng)用
01?初識(shí)AscendCL
AscendCL(Ascend Computing Language,昇騰計(jì)算語(yǔ)言)是昇騰計(jì)算開(kāi)放編程框架,是對(duì)底層昇騰計(jì)算服務(wù)接口的封裝,它提供運(yùn)行時(shí)資源(例如設(shè)備、內(nèi)存等)管理、模型加載與執(zhí)行、算子加載與執(zhí)行、圖片數(shù)據(jù)編解碼/裁剪/縮放處理等API庫(kù),實(shí)現(xiàn)在昇騰CANN平臺(tái)上進(jìn)行深度學(xué)習(xí)推理計(jì)算、圖形圖像預(yù)處理、單算子加速計(jì)算等能力。簡(jiǎn)單來(lái)說(shuō),就是統(tǒng)一的API框架,實(shí)現(xiàn)對(duì)所有資源的調(diào)用。

02?如何基于AscendCL開(kāi)發(fā)推理應(yīng)用

首先,我們得先了解下,使用AscendCL時(shí),經(jīng)常會(huì)提到的“數(shù)據(jù)類(lèi)型的操作接口” ,這是什么呢?為啥會(huì)存在?
在C/C++中,對(duì)用戶開(kāi)放的數(shù)據(jù)類(lèi)型通常以Struct結(jié)構(gòu)體方式定義、以聲明變量的方式使用,但這種方式一旦結(jié)構(gòu)體要增加成員參數(shù),用戶的代碼就涉及兼容性問(wèn)題,不便于維護(hù),因此AscendCL對(duì)用戶開(kāi)放的數(shù)據(jù)類(lèi)型,均以接口的方式操作該數(shù)據(jù)類(lèi)型,例如,調(diào)用某個(gè)數(shù)據(jù)類(lèi)型的Create接口創(chuàng)建該數(shù)據(jù)類(lèi)型、調(diào)用Get接口獲取數(shù)據(jù)類(lèi)型內(nèi)參數(shù)值、調(diào)用Set接口設(shè)置數(shù)據(jù)類(lèi)型內(nèi)的參數(shù)值、調(diào)用Destroy接口銷(xiāo)毀該數(shù)據(jù)類(lèi)型,用戶無(wú)需關(guān)注定義數(shù)據(jù)類(lèi)型的結(jié)構(gòu)體長(zhǎng)什么樣,這樣即使后續(xù)數(shù)據(jù)類(lèi)型需擴(kuò)展,只需增加該數(shù)據(jù)類(lèi)型的操作接口即可,也不會(huì)引起兼容性問(wèn)題。
所以,總結(jié)下,“數(shù)據(jù)類(lèi)型的操作接口”就是創(chuàng)建數(shù)據(jù)類(lèi)型、Get/Set數(shù)據(jù)類(lèi)型中的參數(shù)值、銷(xiāo)毀數(shù)據(jù)類(lèi)型的一系列接口,存在的最大好處就是減少兼容性問(wèn)題。
接下來(lái),進(jìn)入我們今天的主題,怎么用AscendCL的接口開(kāi)發(fā)網(wǎng)絡(luò)模型推理場(chǎng)景下的應(yīng)用??赐瓯疚慕榻B的關(guān)鍵知識(shí)點(diǎn),也可以到?“昇騰文檔中心[1]”查閱詳細(xì)的文檔介紹。
03 AscendCL初始化與去初始化
使用AscendCL接口開(kāi)發(fā)應(yīng)用時(shí),必須先初始化AscendCL ,否則可能會(huì)導(dǎo)致后續(xù)系統(tǒng)內(nèi)部資源初始化出錯(cuò),進(jìn)而導(dǎo)致其它業(yè)務(wù)異常。在初始化時(shí),還支持以下跟推理相關(guān)的配置項(xiàng)(例如,性能相關(guān)的采集信息配置),以json格式的配置文件傳入AscendCL初始化接口。如果當(dāng)前的默認(rèn)配置已滿足需求(例如,默認(rèn)不開(kāi)啟性能相關(guān)的采集信息配置),無(wú)需修改,可向AscendCL初始化接口中傳入NULL,或者可將配置文件配置為空json串(即配置文件中只有{})。
有初始化就有去初始化,在確定完成了AscendCL的所有調(diào)用之后,或者進(jìn)程退出之前,需調(diào)用AscendCL接口實(shí)現(xiàn)AscendCL去初始化。
04?運(yùn)行管理資源申請(qǐng)與釋放
運(yùn)行管理資源包括Device、Context、Stream、Event等,此處重點(diǎn)介紹Device、Context、Stream,其基本概念如下圖所示 。

您需要按順序依次申請(qǐng)如下運(yùn)行管理資源:Device、Context、Stream,確??梢允褂眠@些資源執(zhí)行運(yùn)算、管理任務(wù)。所有數(shù)據(jù)處理都結(jié)束后,需要按順序依次釋放運(yùn)行管理資源:Stream、Context、Device。
在申請(qǐng)運(yùn)行管理資源時(shí),Context、Stream支持隱式創(chuàng)建和顯式創(chuàng)建兩種申請(qǐng)方式。

05?媒體數(shù)據(jù)處理
如果模型對(duì)輸入圖片的寬高要求與用戶提供的源圖不一致,AscendCL提供了媒體數(shù)據(jù)處理的接口,可實(shí)現(xiàn)摳圖、縮放、格式轉(zhuǎn)換、視頻或圖片的編解碼等,將源圖裁剪成符合模型的要求。后續(xù)期刊中會(huì)展開(kāi)說(shuō)明這個(gè)功能,本期著重介紹模型推理的部分,以輸入圖片滿足模型的要求為例。
06?模型加載
模型推理場(chǎng)景下,必須要有適配昇騰AI處理器的離線模型(*.om文件),我們可以使用ATC(Ascend Tensor Compiler)來(lái)構(gòu)建模型。如果模型推理涉及動(dòng)態(tài)Batch、動(dòng)態(tài)分辨率等特性,需在構(gòu)建模型增加相關(guān)配置。關(guān)于如何使用ATC來(lái)構(gòu)建模型,請(qǐng)參見(jiàn)“昇騰文檔中心[1]”。
有了模型,就可以開(kāi)始加載了,當(dāng)前AscendCL支持以下幾種方式加載模型:
從*.om文件中加載模型數(shù)據(jù),由AscendCL管理內(nèi)存
從*.om文件中加載模型數(shù)據(jù),由用戶自行管理內(nèi)存
從內(nèi)存中加載模型數(shù)據(jù),由AscendCL管理內(nèi)存
從內(nèi)存中加載模型數(shù)據(jù),由用戶自行管理內(nèi)存
由用戶自行管理內(nèi)存時(shí),需關(guān)注工作內(nèi)存、權(quán)值內(nèi)存。工作內(nèi)存用于存放模型執(zhí)行過(guò)程中的臨時(shí)數(shù)據(jù),權(quán)值內(nèi)存用于存放權(quán)值數(shù)據(jù)。這個(gè)時(shí)候,是不是有疑問(wèn)了,我怎么知道工作內(nèi)存、權(quán)值內(nèi)存需要多大?不用擔(dān)心,AscendCL不僅提供了加載模型的接口,同時(shí)也提供了“根據(jù)模型文件獲取模型執(zhí)行時(shí)所需的工作內(nèi)存和權(quán)值內(nèi)存大小”的接口,方便用戶使用 。

07?模型執(zhí)行
在調(diào)用AscendCL接口進(jìn)行模型推理時(shí),模型推理有輸入、輸出數(shù)據(jù),輸入、輸出數(shù)據(jù)需要按照AscendCL規(guī)定的數(shù)據(jù)類(lèi)型存放。相關(guān)數(shù)據(jù)類(lèi)型如下:
使用aclmdlDesc類(lèi)型的數(shù)據(jù)描述模型基本信息(例如輸入/輸出的個(gè)數(shù)、名稱(chēng)、數(shù)據(jù)類(lèi)型、Format、維度信息等)。
模型加載成功后,用戶可根據(jù)模型的ID,調(diào)用該數(shù)據(jù)類(lèi)型下的操作接口獲取該模型的描述信息,進(jìn)而從模型的描述信息中獲取模型輸入/輸出的個(gè)數(shù)、內(nèi)存大小、維度信息、Format、數(shù)據(jù)類(lèi)型等信息。
使用aclDataBuffer類(lèi)型的數(shù)據(jù)來(lái)描述每個(gè)輸入/輸出的內(nèi)存地址、內(nèi)存大小。
調(diào)用aclDataBuffer類(lèi)型下的操作接口獲取內(nèi)存地址、內(nèi)存大小等,便于向內(nèi)存中存放輸入數(shù)據(jù)、獲取輸出數(shù)據(jù)。
使用aclmdlDataset類(lèi)型的數(shù)據(jù)描述模型的輸入/輸出數(shù)據(jù)。
模型可能存在多個(gè)輸入、多個(gè)輸出,調(diào)用aclmdlDataset類(lèi)型的操作接口添加多個(gè)aclDataBuffer類(lèi)型的數(shù)據(jù)。

準(zhǔn)備好模型執(zhí)行所需的輸入和輸出數(shù)據(jù)類(lèi)型、且存放好模型執(zhí)行的輸入數(shù)據(jù)后,可以執(zhí)行模型推理了,如果模型的輸入涉及動(dòng)態(tài)Batch、動(dòng)態(tài)分辨率等特性,則在模型執(zhí)行前,還需要調(diào)用AscendCL接口告訴模型本次執(zhí)行時(shí)需要用的Batch數(shù)、分辨率等。
當(dāng)前AscendCL支持同步模型執(zhí)行、異步模型執(zhí)行兩種方式,這里說(shuō)的同步、異步是站在調(diào)用者和執(zhí)行者的角度。
若調(diào)用模型執(zhí)行的接口后需等待推理完成再返回,則表示模型執(zhí)行是同步的。當(dāng)用戶調(diào)用同步模型執(zhí)行接口后,可直接從該接口的輸出參數(shù)中獲取模型執(zhí)行的結(jié)果數(shù)據(jù),如果需要推理的輸入數(shù)據(jù)量很大,同步模型執(zhí)行時(shí),需要等所有數(shù)據(jù)都處理完成后,才能獲取推理的結(jié)果數(shù)據(jù)。
若調(diào)用模型執(zhí)行的接口后不等待推理完成完成再返回,則表示模型執(zhí)行是異步的。當(dāng)用戶調(diào)用異步模型執(zhí)行接口時(shí),需指定Stream(Stream用于維護(hù)一些異步操作的執(zhí)行順序,確保按照應(yīng)用程序中的代碼調(diào)用順序在Device上執(zhí)行),另外,還需調(diào)用aclrtSynchronizeStream接口阻塞程序運(yùn)行,直到指定Stream中的所有任務(wù)都完成,才可以獲取推理的結(jié)果數(shù)據(jù)。如果需要推理的輸入數(shù)據(jù)量很大,異步模型執(zhí)行時(shí),AscendCL提供了Callback機(jī)制,觸發(fā)回調(diào)函數(shù),在指定時(shí)間內(nèi)一旦有推理的結(jié)果數(shù)據(jù),就獲取出來(lái),達(dá)到分批獲取推理結(jié)果數(shù)據(jù)的目的,提高效率。
推理結(jié)束后,如果需要獲取并進(jìn)一步處理推理結(jié)果數(shù)據(jù),則由用戶自行編碼實(shí)現(xiàn)。最后,別忘了,我們還要銷(xiāo)毀aclmdlDataset、aclDataBuffer等數(shù)據(jù)類(lèi)型,釋放相關(guān)內(nèi)存,防止內(nèi)存泄露。
08?模型卸載
在模型推理結(jié)束后,還需要通過(guò)aclmdlUnload接口卸載模型,并銷(xiāo)毀aclmdlDesc類(lèi)型的模型描述信息、釋放模型運(yùn)行的工作內(nèi)存和權(quán)值內(nèi)存。
以上就是基于AscendCL開(kāi)發(fā)基礎(chǔ)推理應(yīng)用的相關(guān)知識(shí)點(diǎn),您也可以在“昇騰社區(qū)在線課程[2]”板塊學(xué)習(xí)視頻課程,學(xué)習(xí)過(guò)程中的任何疑問(wèn),都可以在“昇騰論壇[3]”互動(dòng)交流!
09?編譯及運(yùn)行應(yīng)用
此處我們以一個(gè)“基于Caffe ResNet-50網(wǎng)絡(luò)實(shí)現(xiàn)圖片分類(lèi)”的應(yīng)用為例,來(lái)說(shuō)明編譯運(yùn)行應(yīng)用的基本步驟以及運(yùn)行應(yīng)用后如何查看圖片所屬分類(lèi)。編譯運(yùn)行應(yīng)用依賴CANN軟件,因此您需要先根據(jù)對(duì)應(yīng)版本的安裝指南安裝CANN軟件。
接下來(lái)可以通過(guò)下面鏈接體驗(yàn)下編譯運(yùn)行。
https://v.qq.com/x/page/w3271yntt45.html
10?更多介紹?
[1]昇騰文檔中心:https://www.hiascend.com/zh/document
[2]昇騰社區(qū)在線課程:https://www.hiascend.com/zh/edu/courses
[3]昇騰論壇:https://www.hiascend.com/forum