【MindStudio訓(xùn)練營(yíng)第一季】基于U-Net網(wǎng)絡(luò)的圖像分割的MindStudio實(shí)踐

前情說(shuō)明

本作業(yè)基于Windows版MindStudio 5.0.RC3,遠(yuǎn)程連接ECS服務(wù)器使用,ECS是基于官方分享的CANN6.0.RC1_MindX_Vision3.0.RC3鏡像創(chuàng)建的。

基于ECS(Ascend310)的U-Net網(wǎng)絡(luò)的圖像分割

1. U-Net網(wǎng)絡(luò)介紹:

U-Net模型基于二維圖像分割。在2015年ISBI細(xì)胞跟蹤競(jìng)賽中,U-Net獲得了許多最佳獎(jiǎng)項(xiàng)。論文中提出了一種用于醫(yī)學(xué)圖像分割的網(wǎng)絡(luò)模型和數(shù)據(jù)增強(qiáng)方法,有效利用標(biāo)注數(shù)據(jù)來(lái)解決醫(yī)學(xué)領(lǐng)域標(biāo)注數(shù)據(jù)不足的問(wèn)題。U型網(wǎng)絡(luò)結(jié)構(gòu)也用于提取上下文和位置信息。

[U-Net 論文]: Olaf Ronneberger, Philipp Fischer, Thomas Brox. “U-Net: Convolutional Networks for Biomedical Image Segmentation.”?conditionally accepted at MICCAI 2015. 2015.

2. ECS運(yùn)行說(shuō)明

我們的操作基本都在root用戶下執(zhí)行。

首先,修改bash,具體命令和結(jié)果如下。

本項(xiàng)目支持MindStudio運(yùn)行和終端運(yùn)行。

(1)下載項(xiàng)目代碼

下載鏈接:https://alexed.obs.cn-north-4.myhuaweicloud.com/unet_sdk.zip

將項(xiàng)目文件unet_sdk.zip上傳至華為云ECS彈性云服務(wù)器/root/目錄下,并解壓;或者下載到本地電腦,用MindStudio打開(kāi)。

將之前unet_hw960_bs1.air模型放到/unet_sdk/model/目錄下。

項(xiàng)目文件結(jié)構(gòu)

├── unet_sdk? ? ├──README.md├── data//數(shù)據(jù)集│? ? ├──1│? │? ├──image.png//圖片│? │? ├──mask.png//標(biāo)簽│...├── model? ? │? ├──air2om.sh// air模型轉(zhuǎn)om腳本│? ├──xxx.air//air模型│? ├──xxx.om//om模型│? ├──aipp_unet_simple_opencv.cfg// aipp文件├── pipeline? ? ? ? ? ? │? ├──unet_simple_opencv.pipeline// pipeline文件├── main.py// 推理文件? ? ├── run.sh// 執(zhí)行文件├── requirements.txt// 需要的三方庫(kù)

(2) 模型轉(zhuǎn)換

將unet_hw960_bs1.air模型轉(zhuǎn)為昇騰AI處理器支持的.om格式離線模型,此處模型轉(zhuǎn)換需要用到ATC工具。

昇騰張量編譯器(Ascend Tensor Compiler,簡(jiǎn)稱ATC)是昇騰CANN架構(gòu)體系下的模型轉(zhuǎn)換工具,它可以將開(kāi)源框架的網(wǎng)絡(luò)模型或Ascend IR定義的單算子描述文件(json格式)轉(zhuǎn)換為昇騰AI處理器支持的.om格式離線模型。模型轉(zhuǎn)換過(guò)程中可以實(shí)現(xiàn)算子調(diào)度的優(yōu)化、權(quán)值數(shù)據(jù)重排、內(nèi)存使用優(yōu)化等,可以脫離設(shè)備完成模型的預(yù)處理。

ATC參數(shù)概覽

(3) 運(yùn)行腳本

運(yùn)行腳本:

cd unet_sdk/model/# 切換至模型存儲(chǔ)目錄atc--framework=1--model=unet_hw960_bs1.air--output=unet_hw960_bs1--input_format=NCHW--soc_version=Ascend310--log=error--insert_op_conf=aipp_unet_simple_opencv.cfg

注意air模型轉(zhuǎn)om只支持靜態(tài)batch,這里batchsize=1。

參數(shù)說(shuō)明:

?framework:原始框架類型。?model:原始模型文件路徑與文件名。?output:轉(zhuǎn)換后的離線模型的路徑以及文件名。?input_format:輸入數(shù)據(jù)格式。?soc_version:模型轉(zhuǎn)換時(shí)指定芯片版本。?log:顯示日志的級(jí)別。?insert_op_conf:插入算子的配置文件路徑與文件名,這里使用AIPP預(yù)處理配置文件,用于圖像數(shù)據(jù)預(yù)處理。

輸出結(jié)果:

ATC run success,表示模型轉(zhuǎn)換成功,得到unet_hw960_bs1.om模型。

模型轉(zhuǎn)換成功之后,可以使用MindX SDK mxVision運(yùn)行腳本,在Ascend 310上進(jìn)行推理。

(4) MindX SDK mxVision 執(zhí)行推理

MindX SDK文檔請(qǐng)參考:https://support.huaweicloud.com/ug-vis-mindxsdk203/atlasmx_02_0051.html

MindX SDK執(zhí)行推理的業(yè)務(wù)流程:

通過(guò)stream配置文件,Stream manager可識(shí)別需要構(gòu)建的element以及element之間的連接關(guān)系,并啟動(dòng)業(yè)務(wù)流程。Stream manager對(duì)外提供接口,用于向stream發(fā)送數(shù)據(jù)和獲取結(jié)果,幫助用戶實(shí)現(xiàn)業(yè)務(wù)對(duì)接。

plugin表示業(yè)務(wù)流程中的基礎(chǔ)模塊,通過(guò)element的串接構(gòu)建成一個(gè)stream。buffer用于內(nèi)部掛載解碼前后的視頻、圖像數(shù)據(jù),是element之間傳遞的數(shù)據(jù)結(jié)構(gòu),同時(shí)也允許用戶掛載元數(shù)據(jù)(Metadata),用于存放結(jié)構(gòu)化數(shù)據(jù)(如目標(biāo)檢測(cè)結(jié)果)或過(guò)程數(shù)據(jù)(如縮放后的圖像)。

MindX SDK基礎(chǔ)概念介紹:

MindX SDK基礎(chǔ)插件:

MindX SDK業(yè)務(wù)流程編排:

Stream配置文件以json格式編寫,用戶必須指定業(yè)務(wù)流名稱、元件名稱和插件名稱,并根據(jù)需要,補(bǔ)充元件屬性和下游元件名稱信息。

以下表格為本實(shí)驗(yàn)pipeline/unet_simple_opencv.pipeline文件及其對(duì)應(yīng)的名稱及描述:

pipeline/unet_simple_opencv.pipeline文件內(nèi)容如下,可根據(jù)實(shí)際開(kāi)發(fā)情況進(jìn)行修改。

{"unet_mindspore":{"stream_config":{"deviceId":"0"},"appsrc0":{"props":{"blocksize":"4096000"},"factory":"appsrc","next":"mxpi_imagedecoder0"},"mxpi_imagedecoder0":{"props":{"cvProcessor":"opencv","outputDataFormat":"BGR"},"factory":"mxpi_imagedecoder","next":"mxpi_imagecrop0"},"mxpi_imagecrop0":{"props":{"cvProcessor":"opencv","dataSource":"ExternalObjects"},"factory":"mxpi_imagecrop","next":"mxpi_imageresize0"},"mxpi_imageresize0":{"props":{"handleMethod":"opencv","resizeType":"Resizer_Stretch","resizeHeight":"960","resizeWidth":"960"},"factory":"mxpi_imageresize","next":"mxpi_tensorinfer0"},"mxpi_tensorinfer0":{"props":{"dataSource":"mxpi_imageresize0","modelPath":"model/unet_hw960_bs1_AIPP.om"},"factory":"mxpi_tensorinfer","next":"mxpi_dumpdata0"},"mxpi_dumpdata0":{"props":{"requiredMetaDataKeys":"mxpi_tensorinfer0"},"factory":"mxpi_dumpdata","next":"appsink0"},"appsink0":{"props":{"blocksize":"4096000"},"factory":"appsink"}}}

(5) 修改modelPath

打開(kāi)pipeline/unet_simple_opencv.pipeline文件,將"mxpi_tensorinfer0"元件的屬性"modelPath"(模型導(dǎo)入路徑)修改為模型轉(zhuǎn)換后保存的om模型"model/unet_hw960_bs1.om"。

修改結(jié)果:

"modelPath":"model/unet_hw960_bs1.om"

modelPath修改完成之后,保存pipeline/unet_simple_opencv.pipeline文件。

StreamManagerApi:

StreamManagerApi文檔請(qǐng)參考:

https://support.huaweicloud.com/ug-vis-mindxsdk203/atlasmx_02_0320.html

StreamManagerApi用于對(duì)Stream流程的基本管理:加載流程配置、創(chuàng)建流程、向流程發(fā)送數(shù)據(jù)、獲得執(zhí)行結(jié)果、銷毀流程。

這里用到的StreamManagerApi有:

InitManager:初始化一個(gè)StreamManagerApi。

CreateMultipleStreams:根據(jù)指定的配置創(chuàng)建多個(gè)Stream。

SendData:向指定Stream上的輸入元件發(fā)送數(shù)據(jù)(appsrc)。

GetResult:獲得Stream上的輸出元件的結(jié)果(appsink)

DestroyAllStreams:銷毀所有的流數(shù)據(jù)。

main.py文件內(nèi)容如下,可根據(jù)實(shí)際開(kāi)發(fā)情況進(jìn)行修改。

importargparseimportbase64importjsonimportosimportcv2importnumpyasnpfrom StreamManagerApiimport*importMxpiDataType_pb2asMxpiDataTypex0=2200# w:2200~4000;h:1000~2800y0=1000x1=4000y1=2800ori_w=x1-x0ori_h=y1-y0def_parse_arg():parser=argparse.ArgumentParser(description="SDK infer")parser.add_argument("-d","--dataset",type=str,default="data/",help="Specify the directory of dataset")parser.add_argument("-p","--pipeline",type=str,default="pipeline/unet_simple_opencv.pipeline",help="Specify the path of pipeline file")returnparser.parse_args()def_get_dataset(dataset_dir):img_ids=sorted(next(os.walk(dataset_dir))[1])forimg_idinimg_ids:img_path=os.path.join(dataset_dir,img_id)yieldimg_pathdef_process_mask(mask_path):# 手動(dòng)裁剪? ? mask=cv2.imread(mask_path,cv2.IMREAD_GRAYSCALE)[y0:y1,x0:x1]returnmaskdef_get_stream_manager(pipeline_path):stream_mgr_api=StreamManagerApi()ret=stream_mgr_api.InitManager()#初始化streamifret!=0:print(f"Failed to init Stream manager, ret={ret}")exit(1)withopen(pipeline_path,'rb')asf:pipeline_content=f.read()ret=stream_mgr_api.CreateMultipleStreams(pipeline_content)# 創(chuàng)建streamifret!=0:print(f"Failed to create stream, ret={ret}")exit(1)returnstream_mgr_apidef_do_infer_image(stream_mgr_api,image_path):stream_name=b'unet_mindspore'# 與pipeline中stream name一致? ? data_input=MxDataInput()withopen(image_path,'rb')asf:data_input.data=f.read()# 插入摳圖的功能,扣1800*1800大小? ? roiVector=RoiBoxVector()roi=RoiBox()roi.x0=x0? ? roi.y0=y0? ? roi.x1=x1? ? roi.y1=y1? ? roiVector.push_back(roi)data_input.roiBoxs=roiVector? ? unique_id=stream_mgr_api.SendData(stream_name,0,data_input)#向指定Stream上的輸入元件發(fā)送數(shù)據(jù)(appsrc)ifunique_id<0:print("Failed to send data to stream.")exit(1)infer_result=stream_mgr_api.GetResult(stream_name,unique_id)# 獲得Stream上的輸出元件的結(jié)果(appsink)ifinfer_result.errorCode!=0:print(f"GetResult error. errorCode={infer_result.errorCode},"f"errorMsg={infer_result.data.decode()}")exit(1)# 用dumpdata獲取數(shù)據(jù)? ? infer_result_data=json.loads(infer_result.data.decode())content=json.loads(infer_result_data['metaData'][0]['content'])tensor_vec=content['tensorPackageVec'][0]['tensorVec'][1]#1是argmax結(jié)果? ? data_str=tensor_vec['dataStr']tensor_shape=tensor_vec['tensorShape']argmax_res=np.frombuffer(base64.b64decode(data_str),dtype=np.float32).reshape(tensor_shape)np.save("argmax_result.npy",argmax_res)tensor_vec=content['tensorPackageVec'][0]['tensorVec'][0]#0是softmax結(jié)果? ? data_str=tensor_vec['dataStr']tensor_shape=tensor_vec['tensorShape']softmax_res=np.frombuffer(base64.b64decode(data_str),dtype=np.float32).reshape(tensor_shape)np.save("softmax_result.npy",softmax_res)returnsoftmax_res? # ndarray# 自定義dice系數(shù)和iou函數(shù)def_calculate_accuracy(infer_image,mask_image):mask_image=cv2.resize(mask_image,infer_image.shape[1:3])mask_image=mask_image/255.0mask_image=(mask_image>0.5).astype(np.int)mask_image=(np.arange(2)==mask_image[...,None]).astype(np.int)infer_image=np.squeeze(infer_image,axis=0)inter=np.dot(infer_image.flatten(),mask_image.flatten())union=np.dot(infer_image.flatten(),infer_image.flatten())+\? ? ? ? np.dot(mask_image.flatten(),mask_image.flatten())single_dice=2*float(inter)/float(union+1e-6)single_iou=single_dice/(2-single_dice)returnsingle_dice,single_ioudefmain(_args):dice_sum=0.0iou_sum=0.0cnt=0stream_mgr_api=_get_stream_manager(_args.pipeline)forimage_pathin_get_dataset(_args.dataset):infer_image=_do_infer_image(stream_mgr_api,os.path.join(image_path,'image.png'))# 摳圖并且reshape后的shape,1hw? ? ? ? mask_image=_process_mask(os.path.join(image_path,'mask.png'))# 摳圖后的shape, hw? ? ? ? dice,iou=_calculate_accuracy(infer_image,mask_image)dice_sum+=dice? ? ? ? iou_sum+=iou? ? ? ? cnt+=1print(f"image: {image_path}, dice: {dice}, iou: {iou}")print(f"========== Cross Valid dice coeff is: {dice_sum / cnt}")print(f"========== Cross Valid IOU is: {iou_sum / cnt}")stream_mgr_api.DestroyAllStreams()# 銷毀streamif__name__=="__main__":args=_parse_arg()main(args)

run.sh文件內(nèi)容如下,可根據(jù)實(shí)際開(kāi)發(fā)情況進(jìn)行修改。參考SDK軟件包sample腳本,需要按照實(shí)際路徑修改各個(gè)環(huán)境變量路徑。

set-eCUR_PATH=$(cd"$(dirname "$0")"||{warn"Failed to check path/to/run.sh";exit;};pwd)# Simple log helper functionsinfo(){echo-e"\033[1;34m[INFO ][MxStream] $1\033[1;37m";}warn(){echo>&2-e"\033[1;31m[WARN ][MxStream] $1\033[1;37m";}#exportMX_SDK_HOME=${CUR_PATH}/../../..exportLD_LIBRARY_PATH=${MX_SDK_HOME}/lib:${MX_SDK_HOME}/opensource/lib:${MX_SDK_HOME}/opensource/lib64:/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64:${LD_LIBRARY_PATH}exportGST_PLUGIN_SCANNER=${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scannerexportGST_PLUGIN_PATH=${MX_SDK_HOME}/opensource/lib/gstreamer-1.0:${MX_SDK_HOME}/lib/plugins#tosetPYTHONPATH,importthe StreamManagerApi.pyexportPYTHONPATH=$PYTHONPATH:${MX_SDK_HOME}/pythonpython3 main.pyexit0

(6) 運(yùn)行腳本

激活mxVision環(huán)境變量(本作業(yè)無(wú)需此步驟):

./root/mxVision/set_env.sh

運(yùn)行腳本:

cd/root/unet_sdk/# 切換至推理腳本目錄bash run.sh

運(yùn)行截圖如下:

通過(guò)MindStudio運(yùn)行,會(huì)自動(dòng)上傳代碼到預(yù)設(shè)路徑,并執(zhí)行,運(yùn)行結(jié)果如下:

MindStudio專家系統(tǒng)工具

專家系統(tǒng)工具當(dāng)前支持專家系統(tǒng)自有知識(shí)庫(kù)和生態(tài)知識(shí)庫(kù)對(duì)模型/算子進(jìn)行性能分析,支持性能調(diào)優(yōu)一鍵式閉環(huán)實(shí)現(xiàn)一鍵式性能問(wèn)題優(yōu)化能力。

專家系統(tǒng)自有知識(shí)庫(kù)當(dāng)前提供的功能:基于Roofline模型的算子瓶頸識(shí)別與優(yōu)化建議、基于Timeline的AI CPU算子優(yōu)化、算子融合推薦、TransData算子識(shí)別和算子優(yōu)化分析。

生態(tài)知識(shí)庫(kù)的專家系統(tǒng)性能調(diào)優(yōu)功能:由生態(tài)開(kāi)發(fā)者使用Python編程語(yǔ)言進(jìn)行開(kāi)發(fā),用戶通過(guò)調(diào)用專家系統(tǒng)提供的接口,對(duì)生態(tài)開(kāi)發(fā)者提供的模型/算子進(jìn)行性能分析。

MindStudio IDE當(dāng)前版本僅支持的生態(tài)知識(shí)庫(kù)創(chuàng)建功能,可以在上面完成生態(tài)知識(shí)庫(kù)代碼開(kāi)發(fā),暫不支持對(duì)生態(tài)知識(shí)庫(kù)的專家系統(tǒng)分析功能。性能調(diào)優(yōu)一鍵式閉環(huán)提供一鍵式性能問(wèn)題分析和優(yōu)化能力,有效提升用戶性能分析和優(yōu)化效率。

下面介紹如何使用專家系統(tǒng)工具對(duì)模型和算子進(jìn)行性能瓶頸識(shí)別并輸出優(yōu)化建議。

1. 單擊菜單欄“Ascend > Advisor”,彈出專家系統(tǒng)工具界面 。如圖所示。

2. 單擊上圖界面左上角紅框中的按鈕,打開(kāi)專家系統(tǒng)配置界面,各參數(shù)配置示例如圖所示。

各參數(shù)具體說(shuō)明如下:

3. 配置完成后單擊“Start”啟動(dòng)分析。

之后開(kāi)始運(yùn)行,如圖所示,具體時(shí)間與網(wǎng)絡(luò)情況有關(guān)。

運(yùn)行完成后,會(huì)自動(dòng)跳轉(zhuǎn)到如下圖所示界面。

這里的Model Performance Report是模型性能的總結(jié)報(bào)告。根據(jù)該頁(yè)面,可以知道模型性能是好是壞,也可以知道模型的吞吐率和運(yùn)行時(shí)間,AI Core的利用率,Tiling策略是否合理,部分字段說(shuō)明如下所示,具體可參見(jiàn)https://www.hiascend.com/document/detail/zh/mindstudio/50RC3/msug/msug_000285.html。

從上述截圖的分析結(jié)果可以看出我們所用的U-Net模型的芯片利用率是偏低的,甚至可以說(shuō)是很差,有很大的優(yōu)化的空間。下面我們來(lái)詳細(xì)分析。

先來(lái)看根據(jù)總體性能數(shù)據(jù)匯總計(jì)算得出的Model Performance,顯示為Bad,情況不樂(lè)觀啊。接著看看匯總信息。

可以看到Cube吞吐量Cube Throughput約393 GOps,Vector吞吐量Vector Throughput約0.89 GOps,AI Core執(zhí)行時(shí)間88712us,任務(wù)執(zhí)行時(shí)間177183us,平均BlockDim利用率Avg BlockDim Usage,算子執(zhí)行時(shí)的平均核心數(shù),數(shù)值為1,這反映了反映芯片利用情況,考慮到我們ECS的Ascend 310總計(jì)2個(gè)AI Core,且由系統(tǒng)自動(dòng)調(diào)度,這里為1還可以接收。但下面的數(shù)據(jù)可難看了。

如圖所示,芯片利用率Chip Utilization。按照規(guī)則,80為優(yōu),顯示為綠色;小于80則為差,顯示為紅色。根據(jù)Pipeline Bound的數(shù)值計(jì)算得出。而我們這里直接為0了。再看Cube利用率Cube Ratio約為0.41,Vector利用率Vector Ratio約為0.29,Scalar利用率Scalar Ratio約為0.26,還有優(yōu)化空間,而MTE1瓶頸、MTE2瓶頸、MTE3瓶頸都還不小。特別是MTE2瓶頸,約為0.39。下面接著看。

來(lái)看內(nèi)存讀入量的數(shù)據(jù)切片策略Tiling Strategy為5.23,情況糟糕。根據(jù)規(guī)則,數(shù)值達(dá)到80為優(yōu),顯示為綠色;小于80則為差,顯示為紅色。這是根據(jù)Memory Redundant的數(shù)值計(jì)算得出。同時(shí),可以看到真實(shí)內(nèi)存讀入量Real Memory Input(GB)約為1.44GB,真實(shí)內(nèi)存寫出量Real Memory Output(GB)約為0.60GB,都在可用范圍內(nèi)。

接下來(lái)進(jìn)入Computational Graph Optimization界面,如圖紅框所示兩處都可以,二者就是簡(jiǎn)版和精裝版的區(qū)別了。在這里,我們可以看到計(jì)算圖優(yōu)化,算子融合推薦功能專家系統(tǒng)分析建議,會(huì)分行展示可融合的算子。

先來(lái)看看需要進(jìn)行UB融合的算子,點(diǎn)擊算子,會(huì)自動(dòng)跳轉(zhuǎn)相應(yīng)的計(jì)算圖,既直觀又方便啊。同時(shí)我們看到可融合算子的執(zhí)行時(shí)間Fusion Operator Duration達(dá)到了約9585us,接近10ms了,算是比較大了。本模型沒(méi)有AIPP融合推薦和L2Cache融合推薦。

我們直接看TransData算子融合推薦,如圖所示。該算子執(zhí)行持續(xù)時(shí)間在2.5ms左右,也不算小了,也是一個(gè)值得優(yōu)化的地方啊。

但遺憾的是本次Roofline頁(yè)面(基于Roofline模型的算子瓶頸識(shí)別與優(yōu)化建議功能輸出結(jié)果)和Model Graph Optimization頁(yè)面(基于Timeline的AICPU算子優(yōu)化功能輸出結(jié)果)都沒(méi)什么結(jié)果展示,具體分別如下圖所示。

這里提個(gè)建議,看了下運(yùn)行日志(顯示了這一句[ERROR] Analyze model(RooflineModel) failed, please check dfx log.),Roofline之所以沒(méi)有結(jié)果顯示,可能是Roofline運(yùn)行失敗,不過(guò)這個(gè)日志有點(diǎn)太簡(jiǎn)潔了,不太友好,也沒(méi)有給出 dfx log的具體路徑或位置,哪怕彈出一個(gè)鏈接給用戶,讓用戶去自行查找呢,這都沒(méi)有,感覺(jué)界面不太友好啊。

專家系統(tǒng)提供對(duì)推理模型和算子的性能瓶頸分析能力并輸出專家建議,但實(shí)際性能調(diào)優(yōu)還需用戶自行修改,不能做到性能調(diào)優(yōu)一鍵式閉環(huán)。而性能調(diào)優(yōu)一鍵式閉環(huán)提供一鍵式性能問(wèn)題分析和優(yōu)化能力,有效提升用戶性能分析和優(yōu)化效率。同時(shí),性能調(diào)優(yōu)一鍵式閉環(huán)當(dāng)前實(shí)現(xiàn)生態(tài)知識(shí)庫(kù)ONNX模型的部分推理場(chǎng)景瓶頸識(shí)別和自動(dòng)化調(diào)優(yōu)能力。

但這需要準(zhǔn)備待優(yōu)化的ONNX模型文件(.onnx)以及ONNX模型經(jīng)過(guò)ATC轉(zhuǎn)換后的OM模型文件(.om),而我們這次是.air模型轉(zhuǎn)om模型,雖然可以獲得onnx模型,但太麻煩了,我們這次就不嘗試了。

這里再提個(gè)建議,性能調(diào)優(yōu)一鍵式閉環(huán)還需要下載ONNX模型調(diào)優(yōu)知識(shí)庫(kù),我按照文檔(文檔鏈接:https://www.hiascend.com/document/detail/zh/mindstudio/50RC3/msug/msug_000303.html)中提供Link跳轉(zhuǎn)下載(如下圖所示),未能找到文檔后續(xù)所說(shuō)的KnowledgeBase?Configuration知識(shí)庫(kù)配置文件echosystem.json。不知道是不是我的問(wèn)題,建議工程師看看,驗(yàn)證一下。

MindStudio Profiling工具

Profiling作為專業(yè)的昇騰AI任務(wù)性能分析工具,其功能涵蓋AI任務(wù)運(yùn)行時(shí)關(guān)鍵數(shù)據(jù)采集和性能指標(biāo)分析。熟練使用Profiling,可以快速定位性能瓶頸,顯著提升AI任務(wù)性能分析的效率。

下面介紹使用Profiling工具采集性能數(shù)據(jù)并作簡(jiǎn)單的性能數(shù)據(jù)分析。

1. 更換python鏈接(可選)

這里先給大家排下雷,如果大家遇到如下報(bào)錯(cuò),那么按照下面的操作修復(fù)下就行了,報(bào)錯(cuò)信息如下圖所示:

個(gè)人認(rèn)為,這應(yīng)該是本地電腦沒(méi)安裝Python或者安裝了,但是沒(méi)有添加到系統(tǒng)Path,以致無(wú)法調(diào)用,這應(yīng)該P(yáng)rofiling需要在Windows上調(diào)用Python做一些操作,但無(wú)法調(diào)用Python導(dǎo)致的。那么我們只要安裝Python的時(shí)候,選擇添加到Path,或者已經(jīng)安裝Python的同學(xué),將Python添加到Path,最終使得能夠在Windows終端下直接調(diào)用Python即可。最終效果示例如下:

此外,因?yàn)镋CS終端默認(rèn)啟動(dòng)的Python是/usr/bin/python,而在ECS默認(rèn)是Python2直接運(yùn)行程序會(huì)報(bào)錯(cuò),而我們需要用Python3,所以需要重新鏈接符號(hào),具體流程為:刪除python鏈接文件–>>新建鏈接文件到python3,下面是操作步驟:

那么有人可能就要問(wèn)了,為什么是/usr/local/python3.9.5/bin/python3呢?因?yàn)槲覀冊(cè)谕ㄟ^(guò)MindStudio直接在遠(yuǎn)程ECS上運(yùn)行的時(shí)候,就是用的這個(gè)啊,來(lái)張圖看看:

這里提個(gè)建議,我之前運(yùn)行會(huì)報(bào)錯(cuò),詳情見(jiàn)https://www.hiascend.com/forum/thread-0229107014330773104-1-1.html,連著兩天重啟,試了好幾次,就是不行,后來(lái)又試了一次,突然就可以了,感覺(jué)很奇怪,莫明其妙地報(bào)錯(cuò),莫名其秒地好了,這給我一種IDE很不穩(wěn)定的感覺(jué)。建議優(yōu)化一下,提升下穩(wěn)定性。

2. 執(zhí)行Profiling采集

(1)單擊菜單欄“Ascend > System Profiler > New Project”,彈出Profiling配置窗口 。

配置“Project Properties”,配置工程名稱“Project Name”和選擇工程路徑“Project Location”。單擊“Next”進(jìn)入下一步。

(2)進(jìn)入“Executable Properties”配置界面。

(3)進(jìn)入“Profiling Options”配置界面,配置項(xiàng)按默認(rèn)配置

完成上述配置后單擊窗口右下角的“Start”按鈕,啟動(dòng)Profiling。工程執(zhí)行完成后,MindStudio自動(dòng)彈出Profiling結(jié)果視圖。

先來(lái)看下全量迭代耗時(shí)數(shù)據(jù),在Timeline視圖下查看Step Trace數(shù)據(jù)迭代耗時(shí)情況,識(shí)別耗時(shí)較長(zhǎng)迭代進(jìn)行分析。注意,可選擇導(dǎo)出對(duì)應(yīng)迭代Timeline數(shù)據(jù),單擊耗時(shí)較長(zhǎng)迭代按鈕

彈出對(duì)話框,單擊“Yes”導(dǎo)出對(duì)應(yīng)迭代Timeline數(shù)據(jù)。如圖所示,如果最初看不見(jiàn),建議將鼠標(biāo)放到圖上,之后滑動(dòng)放大,就能看見(jiàn)了。

還可以查看迭代內(nèi)耗時(shí)情況:存在較長(zhǎng)耗時(shí)算子時(shí),可以進(jìn)一步找算子詳細(xì)信息輔助定位;存在通信耗時(shí)或調(diào)度間隙較長(zhǎng)時(shí),分析調(diào)用過(guò)程中接口耗時(shí)。如圖所示。

在界面下方還能查看對(duì)應(yīng)的算子統(tǒng)計(jì)表:查看迭代內(nèi)每個(gè)AICORE和AICPU算子的耗時(shí)及詳細(xì)信息,進(jìn)一步定位分析算子的Metrics指標(biāo)數(shù)據(jù),分析算子數(shù)據(jù)搬運(yùn)、執(zhí)行流水的占比情況,識(shí)別算子瓶頸點(diǎn)。

此外,這里還能查看組件接口耗時(shí)統(tǒng)計(jì)表:查看迭代內(nèi)AscendCL API和Runtime API的接口耗時(shí)情況,輔助分析接口調(diào)用對(duì)性能的影響。

這個(gè)要說(shuō)一下,限于屏幕大小,上述這次數(shù)據(jù)的完整展示,可能需要放大或縮小,或者調(diào)整某些部分大小,這些操作很卡頓,操作起來(lái)沒(méi)什么反應(yīng),仿佛這個(gè)界面卡死了,可用性差,用戶體驗(yàn)不好,建議優(yōu)化一下。

我們可以看到下圖中這個(gè)Op的Task Wait Time要9.895us,而其他Op基本為0,所以可以考慮試試能不能減少這個(gè)Wait Time,從而提升性能。

這里說(shuō)一下,上圖中這個(gè)Op Name很長(zhǎng),我需要將這欄橫向拉伸很長(zhǎng)才能完整顯示,這有點(diǎn)麻煩,我本來(lái)想將鼠標(biāo)懸停此處,讓其自動(dòng)顯示完整名稱,但好像不行,能否考慮加一下這個(gè)懸停顯示全部?jī)?nèi)容的操作,否則我要先拉伸看,之后再拉回去看其他,比較麻煩。

還記得之前我們?cè)趯<蚁到y(tǒng)工具那時(shí)提到的MTE2瓶頸相比之下有些大(約0.39)嘛?這里從下圖看到Mte2時(shí)間較長(zhǎng),約3.7ms,說(shuō)一下,mte2類型指令應(yīng)該是DDR->AI Core搬運(yùn)類指令,這里我們量化一下看看,如下圖所示,AI Core時(shí)間約為6.8ms,但Task Duration約12.5ms,幾乎翻倍了,說(shuō)明我們Task只有約一半時(shí)間是真正用于AI Core計(jì)算,很明顯很多時(shí)間被浪費(fèi)了。

說(shuō)明這一點(diǎn)還是比較值得優(yōu)化的。而各個(gè)工具之間也是可以相互輔助,相互驗(yàn)證更好地幫助我們定位問(wèn)題。下面我們?cè)倏纯矗却_認(rèn)下Timeline顏色配置調(diào)色板,如下圖所示。而我們之前看到的Timeline基本是綠色,未見(jiàn)黃色或紅色,估計(jì)沒(méi)什么優(yōu)化空間了。還是優(yōu)先做明顯地值得優(yōu)化地點(diǎn)吧,這也算抓大放小吧。

好了,我們?cè)倏袋c(diǎn)其他的,比如Analysis Summary,這里展示了比較詳細(xì)的軟硬件信息,比如Host Computer Name、Host Operating System等,還有我們ECS上用的CPU的詳細(xì)信息,包括型號(hào)、邏輯核心數(shù)量等,令我感興趣的是,還有Ascend 310的信息,包括AI Core數(shù)量2, AI CPU數(shù)量4,Control CPU數(shù)量4,Control CPU Type為ARMv8_Cortex_A55,以及一個(gè)TS CPU,很詳細(xì)了,很好地展示了Ascend 310的內(nèi)部硬件信息,更有助于我們了解這款處理器。

同時(shí),再來(lái)看看Baseline Comparison吧。

總的來(lái)說(shuō),MindStudio提供了Host+Device側(cè)豐富的性能數(shù)據(jù)采集能力和全景Timeline交互分析能力,展示了Host+Device側(cè)各項(xiàng)性能指標(biāo),幫助用戶快速發(fā)現(xiàn)和定位AI應(yīng)用、芯片及算子的性能瓶頸,包括資源瓶頸導(dǎo)致的AI算法短板,指導(dǎo)算法性能提升和系統(tǒng)資源利用率的優(yōu)化。MindStudio支持Host+Device側(cè)的資源利用可視化統(tǒng)計(jì)分析,具體包括Host側(cè)CPU、Memory、Disk、Network利用率和Device側(cè)APP工程的硬件和軟件性能數(shù)據(jù)。

通過(guò)Profiling性能分析工具前后兩次對(duì)網(wǎng)絡(luò)應(yīng)用推理的運(yùn)行時(shí)間進(jìn)行分析,并對(duì)比兩次執(zhí)行時(shí)間可以得出結(jié)論,可以幫助我們?nèi)ヲ?yàn)證替換函數(shù)或算子后,是否又性能提升,是否提升了推理效率。此外,還可以幫助我們挑選應(yīng)該優(yōu)先選擇的網(wǎng)絡(luò)模型,或者測(cè)試自定義算子是否達(dá)到最優(yōu)性能,是否還存在優(yōu)化空間等等,還是挺有用的。

MindStudio精度比對(duì)工具

1. 定義

為了幫助開(kāi)發(fā)人員快速解決算子精度問(wèn)題,需要提供自有實(shí)現(xiàn)的算子運(yùn)算結(jié)果與業(yè)界標(biāo)準(zhǔn)算子運(yùn)算結(jié)果之間進(jìn)行精度差異對(duì)比的工具。

2. 功能

提供Tensor比對(duì)能力,包含余弦相似度、歐氏相對(duì)距離、絕對(duì)誤差(最大絕對(duì)誤差、平均絕對(duì)誤差、均方根誤差)、相對(duì)誤差(最大相對(duì)誤差、平均相對(duì)誤差、累積相對(duì)誤差)、KL散度、標(biāo)準(zhǔn)差算法比對(duì)維度。

總結(jié)

MindStudio的安裝過(guò)于繁瑣

暫不談Linux下的安裝和配置,以本次的Windows下MindSutido搭配遠(yuǎn)程ECS使用來(lái)說(shuō),Windows下除了要安裝MindStudio安裝包,還要安裝Python依賴,安裝MinGW依賴,以及安裝CMake等,太麻煩了。能否做成一鍵安裝,畢竟這是個(gè)IDE,感覺(jué)使用其他IDE都是一鍵安裝,就算有其他依賴,一般也是在IDE內(nèi)部根據(jù)需要,自行選擇安裝即可,這個(gè)MindStudio可麻煩了,安裝的依賴還很分散。

還是性能問(wèn)題,性能優(yōu)化不好

Windows下MindStudio的CPU、內(nèi)存等資源占用很大,遠(yuǎn)大于其他類型IDE(比如PyCharm、IntelliJ IEDA等),而且還卡頓,這還是遠(yuǎn)程連接ECS使用,可就是這樣,感覺(jué)本地電腦也快起飛了,遠(yuǎn)不如PyCharm、IntelliJ IEDA等使用起來(lái)順暢,感覺(jué)是軟件優(yōu)化不行,如果是全部在物理機(jī)上運(yùn)行,可能資源開(kāi)銷就更大了,這也太增加負(fù)載了,如果是這樣,IDE的可視化操作意義就不大了,很多操作不如在終端執(zhí)行,將更多資源留給更有用的地方。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容