【華為云-上云之路】【昇騰】【每天進步一點點】在Atlas 200 DK創建模型推理引擎,實現基于自己模型的部署
前言
在Atlas 200 DK上開發部署自己的模型,我覺得最為關鍵部分是模型的轉換和對推理結果的后處理,做好了這兩步,開發就成功了一大半,剩下的基本就是優化設計了。而模型轉換后在Atlas 200 DK上需要自己創建模型推理引擎,完成數據的輸入和推理結果的輸出及解析。在這里,以行人檢測的Demo為例,說一下自己對推理引擎創建的了解。
這里省略了如果模型轉換失敗,要進行修改的步驟,如果不幸遇到了這個問題,就要根據轉換模型的報錯,具體問題具體分析了,這里推薦一位大神發的關于模型轉換遇到問題時解決辦法的總結,該總結也被轉發在了昇騰論壇里,推薦大家看看,絕對干貨滿滿,特地奉上鏈接:https://bbs.huaweicloud.com/forum/thread-57916-1-1.html
行人檢測Demo鏈接:https://bbs.huaweicloud.com/blogs/170452
代碼介紹
推理引擎的創建,模型是關鍵。首先,需要得到轉換好的.om模型,這一步十分重要,因為模型的創建中可能需要根據模型做一些設置。來看代碼來理解吧。這里使用的是行人檢測Demo里行人檢測推理部分的代碼,代碼比單純的講解更能幫助人理解實現過程,我在代碼中加了注釋,可以根據注釋理解。
#?-*-?coding:?utf-8?-*- #?!/usr/bin/python3 #?行人檢測,基于開源數據集和ModelArts中YOLOv3_Resnet18算法 #?行人檢測推理部分 #?引入ConstManager,?這是一個自行創建的.py文件,用來存放模型的路徑 from?ConstManager?import?* #?引入ModelManager,這也是一個.py文件,用來做模型推理創建的模板,按照這個模板,可以輕松創建推理引擎 import?ModelManager #?引入hiai庫,這是華為的一個庫,用來將輸入圖片做向量化和推理,直接用就好 import?hiai from?hiai.nn_tensor_lib?import?DataType #?numpy和cv2就不用說了吧,很著名的兩個Python庫 import?numpy?as?np import?cv2 #?引入utils,這是自行創建的一個.py文件,這里用來對推理結果解析,輸入模型推理結果,返回我們想要的類別,框 #?的坐標等,這樣做個封裝,方便使用和移植,會使整體代碼較為簡潔 import?utils #?引入Python庫datetime,用來計算程序執行時間,這里沒用的,是在測試的時候用的。 import?datetime ''' Yolo3_Resnet18模型,?輸入H?=?352,?W?=?640,圖像輸入必須處理成numpy格式 bj_threshold?置信度閾值,取值范圍為0~1。推理的時候,如果預測框的置信度小于該值,那么就會過濾掉,?默認為0.3 nms_threshold NMS閾值,取值范圍為0~1。默認為0.4 ''' #?創建Yolo3_Resnet18Inference類 class?Yolo3_Resnet18Inference(object): ????def?__init__(self): ????????#?由用戶指定推理引擎的所在Graph的id號 ????????self.graph_id?=?1000 ????????self.model_engine_id?=?100 ????????#?基于輸入圖片框坐標 ????????self.boxList?=?[] ????????#?置信度 ????????self.confList?=?[] ????????#?概率 ????????self.scoresList?=?[] ????????#?輸入圖片中行人部分 ????????self.personList?=?[] ????????#?實例化模型管理類 ????????self.model?=?ModelManager.ModelManager() ????????self.width?=?640 ????????self.height?=?352 ????????#?描述推理模型以及初始化Graph ????????self.graph?=?None ????????self._getgraph() ????def?__del__(self): ????????self.graph.destroy() ????def?_getgraph(self): ????????#?描述推理模型 ????????inferenceModel?=?hiai.AIModelDescription('Yolo3_Resnet18',?yolo3_resnet18_model_path) ????????#?初始化Graph ????????self.graph?=?self.model.CreateGraph(inferenceModel,?self.graph_id,?self.model_engine_id) ????????if?self.graph?is?None: ????????????print("Init?Graph?failed") ????''' ????1.定義輸入Tensor的格式 ????2.調用推理接口 ????3.對一幀推理的正確結果保存到self.resultList中 ????4.根據返回值True和False判斷是否推理成功 ????''' ????def?Inference(self,?input_image): ????????if?isinstance(input_image,?np.ndarray)?is?None: ????????????return?False ????????#?Image?PreProcess ????????resized_image_opencv?=?cv2.resize(input_image,?(self.width,?self.height)) ????????resized_image?=?resized_image_opencv ????????inputImageTensor?=?hiai.NNTensor(resized_image) ????????nntensorList?=?hiai.NNTensorList(inputImageTensor) ????????#?調用推理接口 ????????resultList?=?self.model.Inference(self.graph,?nntensorList) ????????if?resultList?is?not?None: ????????????bboxes?=?utils.get_result(resultList,?self.width,?self.height)??#?獲取檢測結果 ????????????#?print("bboxes:",?bboxes) ????????????#?Yolov_resnet18?Inference ????????????output_image?=?utils.draw_boxes(resized_image,?bboxes)???????#?在圖像上畫框 ????????????output_image?=?cv2.resize(output_image,?(input_image.shape[1],?input_image.shape[0])) ????????????img_name?=?datetime.datetime.now().strftime("%Y-%m-%d%H-%M-%S-%f") ????????????cv2.imwrite('output_image/'?+?str(img_name)?+?'.jpg',?output_image) ????????else: ????????????print('no?person?in?this?frame.') ????????????return?False ????????return?True #?程序執行的主要部分,調用前面定義的推理函數Inference完成推理和后處理 def?dowork(src_img,?yolo3_resnet18_app): ????res?=?yolo3_resnet18_app.Inference(src_img) ????if?res?is?None: ????????print("[ERROR]?Please?Check?yolo3_resnet18_app.Inference!") ????????return?False ????else: ????????print("[ERROR]?Run?Failed,?dowork?function?failed.") ????return?True
得益于ModelManager.py推理引擎創建模板的使用,我們可以很輕松創建一個推理引擎,而這個ModelManager.py這里并沒有放出代碼,可在本文開頭的行人檢測Demo的百度網盤鏈接中下載壓縮包,解壓后就能看到這個.py文件了。需要注意的是,如果要使用的話,需要在主函數先完成初始化工作,詳情可參見Demo中的main.py,很簡單的,就幾行代碼。
此外,模型創建需要指定Graph和engine的ID號,即告訴處理器,你具體想用的Engine,這里使用的graph_id = 1000, model_engine_id =100:
注意這里的graph_id應該是從1000開始,可以到1003吧,即可選為1000,1001,1002,1003,我試過到1003應該是沒問題的,1004可能也可以。model_engine_id是從100開始,可以向后延伸,應該到104都可以吧,不過不建議使用這么多,ID號到103就可以了。
還有一點,不同ID的Graph中的Engine的ID互不干擾,可以相同。簡單來說,Graph像是一個國家,而Engine是國家的國民,不同ID的Graph是不同的國家,那么他們國民的名字,也就是ID號即使重復也沒什么關系。
那么問題來了,如果我想使用多個模型推理怎么辦呢?很簡單,有兩種方法:
創建一個Graph,在里面創建多個Engine,用于模型推理。
創建多個Graph,在每個Graph里面創建一個Engine,用于模型推理。
個人建議,一個Graph里面不要創建太多用于推理的Engine,兩個就差不多了,如果要用的模型較多,可以在創建一個Graph。
最后,說說Graph和Engine的關系吧。對于一個簡單的單模型項目,一個Graph和一個模型推理Engine就足夠了,比如這個Demo就是一個Graph和一個模型推理的Engine,也即是說一個Graph對應一個項目,但如果項目使用多個模型,比如4個模型,那我覺得創建兩個Graph比較好,每個Graph里創建兩個Engine,那么上面的代碼就變成了四份,每份對應一個Engine。這里要注意下數據的傳遞,好像不同Graph之間數據傳遞比較慢,可根據具體的代碼去調整Engine。
以上是我個人在使用Python實現Demo時,自己的一點感悟,可能有不對的地方,還請批評指正,博客中寫的不完善或看不懂的地方,可以在下面評論或私信我哈,我看到會回復的。有時間,歡迎大家到昇騰論壇發帖提問或交流,一起打造昇騰良好的社區生態。
昇騰 AI
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。