如何部署模型到ModelArts并远程调用 (三):编写推理代码

举报
RoyalKun 发表于 2020/07/31 11:49:19 2020/07/31
【摘要】 编写推理代码, customize_service.py 。在该文件中编写推理逻辑。

编写推理代码


推理代码中的四个方法

推理代码固定名称为customize_service.py,只允许放置一个,customize_service.py依赖的py文件可以直接放推理代码的相同目录下。

推理代码包含四个方法,会按照顺序依次调用customize_service.py中的初始化方法,前处理方法,推理方法,后处理方法。

四个方法的作用如下表所示:

方法名 说明
 __init__(self, model_name, model_path) 初始化方法,该方法内加载模型及标签等(pytorch和caffe类型模型必须重写,实现模型加载逻辑)。
 _preprocess(self, data) 预处理方法,在推理请求前调用,用于将API接口用户原始请求数据转换为模型期望输入数据。
 _inference(self, data) 实际推理请求方法(不建议重写,重写后会覆盖modelarts内置的推理过程,运行自定义的推理逻辑)
 _postprocess(self, data) 后处理方法,在推理请求完成后调用,用于将模型输出转换为API接口输出

通常,用户需要重写_preprocess_postprocess方法,以实现数据的API输入的预处理和推理结果输出的后处理。 pytorch和caffe类型模型必须重写初始化方法,实现模型加载逻辑。对于其他类的模型,初始化方法和推理接口已经封装在BaseService类中,不建议重写,因为重写不当可能会导致模型加载和推理失败,运行异常 。

所有自定义的python代码必须继承自BaseService类。不同类型的模型父类导入语句见此表格

数据输入格式

当前支持两种content-type的接口传入,multipart/form-data”“application/json”,在推理配置文件中定义。这两种格式的数据的读取方式见下面样例。

样例解读

样例一:TensorFlow2.1推理脚本示例

这是一个手写数字识别模型的图像分类的推理脚本,模型基于TensorFlow2.1。TensorFlow2.1的模型可以参考此示例以及其中的注释来编写推理代码。

import logging
import threading

import numpy as np
import tensorflow as tf # 导入tensorflow
from PIL import Image

from model_service.tfserving_model_service import TfServingBaseService

logger = logging.getLogger()
logger.setLevel(logging.INFO)


class mnist_service(TfServingBaseService): # 继承平台定义的tensorflow基类
    
    def __init__(self, model_name, model_path):
        '''模型初始化方法,直接复用即可。
        实际使用中,可以不写该方法,此处为了展示平台封装的细节。
        '''
        self.model_name = model_name
        self.model_path = model_path
        self.model = None
        self.predict = None

        # label.txt文件可以在这里加载,在后处理函数里使用,label.txt文件中记录的是类别编号和类别名称的映射。label.txt放在obs的模型包的目录
        with open(os.path.join(self.model_path, 'label.txt')) as f:
            self.label = json.load(f)
        # 非阻塞方式加载saved_model模型,防止阻塞超时
        thread = threading.Thread(target=self.load_model)
        thread.start()

    def load_model(self):
        '''加载模型,从model_path中加载模型
        实际使用中,可以不写该方法,此处为了展示平台封装的细节。
        '''
        # load saved_model 格式的模型
        self.model = tf.saved_model.load(self.model_path)
        signature_defs = self.model.signatures.keys()
        signature = []
        # only one signature allowed
        for signature_def in signature_defs:
            signature.append(signature_def)

        if len(signature) == 1:
            model_signature = signature[0]
        else:
            logging.warning("signatures more than one, use serving_default signature from %s", signature)
            model_signature = tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY

        self.predict = self.model.signatures[model_signature]

    def _preprocess(self, data):
        '''前处理方法
        
        输入参数:
        	data:API的输入数据,数据的格式在推理配置文件中定义。
        	在该样例中,data的输入格式定义为了form-data,可以以字典的格式读取
        	
        返回:
        	preprocessed_data:数据经过前处理之后的格式。
        '''
        images = []
        # 从data字典中逐个取出输入图片
        for k, v in data.items():
            # 逐个以文件格式读取图片
            for file_name, file_content in v.items():
                image1 = Image.open(file_content)
                image1 = np.array(image1, dtype=np.float32)
                image1.resize((28, 28, 1))
                images.append(image1)
        images = tf.convert_to_tensor(images, dtype=tf.dtypes.float32)
        preprocessed_data = images
        
        return preprocessed_data

    def _inference(self, data):
        '''推理方法
        
        输入参数:
        	data:前处理输出的数据
        	
        返回:
        	模型推理的结果。
        '''
        return self.predict(data)

    def _postprocess(self, data):
        '''后处理方法
        
        输入参数:
        	data:模型推理结果
        	
        返回:
        	模型推理结果经过后处理的结果。
        '''
        # 在此处,可以使用label.txt中的类别编号和名称映射信息。
        return {
            "result": int(data["output"].numpy()[0].argmax())
        }

代码参考此文档 ,该文档中还有相应的模型训练代码可以参考。

样例二:sklearn推理脚本示例

该样例是基于sklearn框架的推理代码,基于sklearn的模型可以复用该代码。sklearn的模型可以参考此示例以及其中的注释来编写推理代码。

# coding:utf-8
import collections
import json
from sklearn.externals import joblib # 导入sklearn
from model_service.python_model_service import XgSklServingBaseService

class user_Service(XgSklServingBaseService):

    # request data preprocess
    def _preprocess(self, data):
        '''前处理方法
        
        输入参数:
        	data:API的输入数据,数据的格式在推理配置文件中定义。
        	在该样例中,data的输入格式定义为了json
        	
        返回:
        	list_data:数据经过前处理之后的格式。
        '''
        list_data = []
        # 以json格式加载数据,并用字典来保存
        json_data = json.loads(data, object_pairs_hook=collections.OrderedDict)
        for element in json_data["data"]["req_data"]:
            array = []
            for each in element:
                array.append(element[each])
                list_data.append(array)
        return list_data

    # predict
    def _inference(self, data):
        '''推理方法
        
        输入参数:
        	data:前处理输出的数据
        	
        返回:
        	pre_result:模型推理的结果。
        '''
        sk_model = joblib.load(self.model_path)
        pre_result = sk_model.predict(data)
        pre_result = pre_result.tolist()
        return pre_result

    # predict result process
    def _postprocess(self, data):
        '''后处理方法
        
        输入参数:
        	data:模型推理结果
        	
        返回:
        	resp_data:模型推理结果经过后处理的结果。
        '''
        resp_data = []
        for element in data:
            resp_data.append({"predict_result": element})
        return resp_data

代码参考此文档,该文档中还有相应的模型训练代码可以参考。

其他样例

ModelArts帮助文档中还有其他引擎的训练和推理代码示例,见此文档。可以参考。

更多代码样例

通过几个特定领域的AI大赛的推理代码样例,学习推理代码的写法。

图像分类猫狗分类样例

https://github.com/huaweicloud/ModelArts-Lab/tree/master/train_inference/image_recognition/codes

其中,dog_and_cat_train.py是训练代码,另外两个是推理代码和推理配置文件。

图像分类大赛样例

即将发布。

物体检测大赛样例

即将发布。

语音分类样例

即将发布。

附:

如何部署模型到ModelArts并远程调用 (一):保存模型为平台支持的格式

如何部署模型到ModelArts并远程调用 (三):编写推理代码

如何部署模型到ModelArts并远程调用 (四):导入模型

如何部署模型到ModelArts并远程调用 (五):如何调用在线API服务

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。