【华为云-上云之路】【昇腾】【每天进步一点点】在Atlas 200 DK创建模型推理引擎,实现基于自己模型的部署

网友投稿 762 2022-05-25

前言

在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就可以了。

【华为云-上云之路】【昇腾】【每天进步一点点】在Atlas 200 DK创建模型推理引擎,实现基于自己模型的部署

还有一点,不同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小时内删除侵权内容。

上一篇:cacti安装步骤文档(基于centos6.5环境)&备份恢复cacti0.8.8b数据库-测试成功的
下一篇:【图像分类】实战——使用DenseNet实现识别秃头(pytorch)
相关文章