ModelArts模型导入tensorflow frozenGraph格式模型
背景:
线下有一个tensorflow frozenGraph格式的yolov3模型, 并且已经有推理代码demo.py可以加载模型并进行推理
问题:
如何导入到ModelArts模型管理中?
文中引用到的参考代码已保存在附件中
1 本地代码介绍
本地代码结构如下:
其中demo.py是推理入口脚本,demo.py调用了yolov3_utils.py中的方法。frozen_darknet_yolov3_model2.pb是需要导入的模型文件。
2 Modelarts推理代码结构
适配模型导入后的代码结构如下
l 所有的文件需要保存在model的目录下,然后上传到obs
l config.json用于定义容器的执行环境与依赖的python包。
l demo.py变为了customize_service.py
3 代码迁移
3.1 ModelArts模型导入都做了哪些事情?
l 通过读取config.json的runtime字段信息,后台启动一个runtime对应的docker镜像,并在docker镜像中安装config.json中定义的依赖python包。
l 然后将obs上配置的模型文件目录整体拷贝到docker镜像中,放到指定的目录下。
l Docker镜像中有推理框架,自动加载customize_service.py中的方法,初始化,对应的customize_service.py中定义的__init__方法也会被执行,如果customize_service.py没有覆写__init__方法,那么会执行框架原有的init方法,对模型进行加载。
l 服务启动,等待传入推理数据。
3.2 编写config.json文件
config.json主要功能是定义模型运行环境信息,例如如果我推理代码使用了numpy的版本是1.15.0可以在配置文件中添加如下内容。
Runtime字段指定了是否使用带cuda的docker环境,如果模型是基于python 3.6 tensorflow 1.13 gpu环境构建的,这个时候runtime字段就要选择
Config.json中的信息内容参考如下链接,
https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0092.html
一般来说物体检测和图像分类的输入输出都是固定,因此可以直接运行一个预置算法,预置算法默认会将config.json进行输出,直接复用就可以。
3.3 编写customize_service.py
参考文档 https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0093.html
首先自定义的代码需要继承一个固定的类,这个和框架有关,例如我当前使用的tensorflow框架,那么我需要继承的类是
在代码中实际上这样体现,我创建了一个新的类,类名为 Yolov3Service()这个类名随便起,只要是你继承了TfServingBaseService这个类,框架就知道了你这个类下面的方法就是你自己定义的方法。运行时,框架能够调用到你的方法。
ModelArts推理框架将推理服务分成了4个流程。分别是
__init__(self, model_name, model_path):此方法只会在服务启动时调用一次,可以在此方法内实现模型的加载,变量初始化。如果是tensorflow savedmodel格式的模型,可以不覆写此方法,框架默认的__init__方法会自动加载模型。
model_name没什么用,model_path是系统层传进来的,这个目录是此脚本所在docker容器中的运行目录, model_path=os.path.abspath(__file__)
_preprocess(self, data):前处理,在推理请求前调用,用于将API接口用户原始请求数据转换为模型期望输入数据。
_inference(self, data):实际推理请求方法
_postprocess(self, data):后处理方法,在推理请求完成后调用,用于将模型输出转换为API接口输出
_preprocess,_inference,_postprocess这三个方法会在每次推理时调用,并且以此顺序进行调用。
3.3.1 依赖包导入
customize_service.py相比demo.py,依赖包增加导入红框中的内容
入参由tf.app.flags.FLAGS变为通过环境变量获取,例如demo.py里面通过
进行动态参数的传递而customize_service.py通过如下方式进行入参的解析。
此环境变量在模型部署时传入
当然这些传参也可以硬编码
3.3.2 __init__编写
Demo.py中初始化模型逻辑如下
customize_service.py迁移后的代码为
Demo.py 55行到60行被简化为tf.ConfigProto(),因为云上一个模型占用一个GPU,所以不需要设置gpu显存使用率。
Demo.py 67行对应customize_service.py 43行,session被保存起来,因为线上推理服务需要重复的使用
customize_service.py 36行通过model_path和model_filename,对于模型文件进行加载。为什么要进行路径拼接,请参考3.1章节
3.3.3 _preprocess编写
Demo.py里面对于图片进行了resize
customize_service.py迁移后的代码为
和读取本地文件不同,_preprocess收到的是一个data数组,里面存的是图片的信息。所以这里要对于每一个元素进行遍历。这次这么做的好处就是支持带batchsize的推理,一次可以传入多张图片。
3.3.4 _inference编写
Demo.py里面直接调用了session对文件进行了推理
customize_service.py迁移后的代码为
3.3.5 _postprocess编写
Demo.py里面
进行了非极大值抑制,然后将推理获得的坐标等比例扩大为原始尺寸。
对应customize_service.py的63行和74行。这里的代码比较多,是因为要将返回值构建成config.json定义的结构。
3.4 其推理模型编写教程
https://bbs.huaweicloud.com/forum/thread-66858-1-1.html
- 点赞
- 收藏
- 关注作者
评论(0)