更新时间:2024-10-24 GMT+08:00

在Notebook中通过镜像保存功能制作自定义镜像用于推理

场景说明

本文详细介绍如何将本地已经制作好的模型包导入ModelArts的开发环境Notebook中进行调试和保存,然后将保存后的镜像部署到推理。本案例仅适用于华为云北京四和上海一站点。

操作流程如下:

  1. Step1 在Notebook中复制模型包
  2. Step2 在Notebook中调试模型
  3. Step3 Notebook中保存镜像
  4. Step4 使用保存成功的镜像用于推理部署

Step1 在Notebook中复制模型包

  1. 登录ModelArts控制台,在左侧导航栏中选择“开发环境 > Notebook”,进入“Notebook”管理页面。
  2. 单击右上角“创建”,进入“创建Notebook”页面,请参见如下说明填写参数。
    1. 填写Notebook基本信息,包含名称、描述、是否自动停止。
    2. 填写Notebook详细参数,如选择镜像、资源规格等。
  3. 参数填写完成后,单击“立即创建”进行规格确认。参数确认无误后,单击“提交”,完成Notebook的创建操作。

    进入Notebook列表,正在创建中的Notebook状态为“创建中”,创建过程需要几分钟,请耐心等待。

  4. 当Notebook状态变为“运行中”时,表示Notebook已创建并启动完成。单击“操作列”“打开”,进入JupyterLab的Launcher界面。
    图1 打开后进入JupyterLab的Launcher界面
  5. 通过功能,上传模型包文件到Notebook中,默认工作目录/home/ma-user/work/。模型包文件需要用户自己准备,样例内容参见模型包文件样例
    图2 上传模型包
  6. 打开Terminal终端,解压model.zip,解压后删除zip文件。
    #解压命令
    unzip model.zip
    图3 在Terminal终端中解压model.zip
  7. 在Terminal运行界面,执行复制命令。
    cp -rf model/*  /home/ma-user/infer/model/1

    然后执行如下命令查看镜像文件复制成功。

    cd /home/ma-user/infer/model/1
    ll
    图4 查看镜像文件复制成功

模型包文件样例

模型包文件model.zip中需要用户自己准备模型文件,此处仅是举例示意说明,以一个手写数字识别模型为例。

Model目录下必须要包含推理脚本文件customize_service.py,目的是为开发者提供模型预处理和后处理的逻辑。

图5 推理模型model目录示意图(需要用户自己准备模型文件)

推理脚本customize_service.py的具体写法要求可以参考模型推理代码编写说明

本案例中提供的customize_service.py文件具体内容如下:

import logging
import threading

import numpy as np
import tensorflow as tf
from PIL import Image

from model_service.tfserving_model_service import TfServingBaseService


class mnist_service(TfServingBaseService):

    def __init__(self, model_name, model_path):
        self.model_name = model_name
        self.model_path = model_path
        self.model = None
        self.predict = None

        # 非阻塞方式加载saved_model模型,防止阻塞超时
        thread = threading.Thread(target=self.load_model)
        thread.start()

    def load_model(self):
        # 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):
        images = []
        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):

        return self.predict(data)

    def _postprocess(self, data):

        return {
            "result": int(data["output"].numpy()[0].argmax())
        }

Step2 在Notebook中调试模型

  1. 打开一个新的Terminal终端,进入“/home/ma-user/infer/”目录,运行启动脚本run.sh,并预测模型。基础镜像中默认提供了run.sh作为启动脚本。启动命令如下:
    sh  run.sh
    图6 运行启动脚本
  2. 上传一张预测图片(手写数字图片)到Notebook中。
    图7 手写数字图片
    图8 上传预测图片
  3. 重新打开一个新的Terminal终端,执行如下命令进行预测。
    curl -kv -F 'images=@/home/ma-user/work/test.png' -X POST http://127.0.0.1:8080/
    图9 预测

    在调试过程中,如果有修改模型文件或者推理脚本文件,需要重启run.sh脚本。执行如下命令先停止nginx服务,再运行run.sh脚本。

    #查询nginx进程
    ps -ef |grep nginx 
    #关闭所有nginx相关进程
    kill -9 {进程ID}  
    #运行run.sh脚本
    sh run.sh

    也可以执行pkill nginx命令直接关闭所有nginx进程。

    #关闭所有nginx进程
    pkill nginx
    #运行run.sh脚本
    sh run.sh
    图10 重启run.sh脚本

Step3 Notebook中保存镜像

Notebook实例状态必须为“运行中”才可以一键进行镜像保存。

  1. 在Notebook列表中,对于要保存的Notebook实例,单击右侧“操作”列中的更多 > 保存镜像,进入“保存镜像”对话框。
  2. 在保存镜像对话框中,设置组织、镜像名称、镜像版本和描述信息。单击“确认”保存镜像。

    “组织”下拉框中选择一个组织。如果没有组织,可以单击右侧的“立即创建”,创建一个组织。

    同一个组织内的用户可以共享使用该组织内的所有镜像。

  3. 镜像会以快照的形式保存,保存过程约5分钟,请耐心等待。此时不可再操作实例(对于打开的JupyterLab界面和本地IDE仍可操作)。

    快照中耗费的时间仍占用实例的总运行时长,如果在快照中时,实例因运行时间到期停止,将导致镜像保存失败。

  4. 镜像保存成功后,实例状态变为“运行中”,用户可在“镜像管理”页面查看到该镜像详情。
  5. 单击镜像的名称,进入镜像详情页,可以查看镜像版本/ID,状态,资源类型,镜像大小,SWR地址等。

Step4 使用保存成功的镜像用于推理部署

Step2 在Notebook中调试模型的自定义镜像导入到AI应用中,并部署为在线服务。

  1. 登录ModelArts控制台,在左侧导航栏中选择“模型管理”,单击“创建模型”,进入创建模型。
  2. 设置模型的参数,如图11所示。
    • 元模型来源:从容器镜像中选择。
    • 容器镜像所在的路径:单击选择镜像文件。具体路径查看5SWR地址。
    • 容器调用接口:选择HTTPS。
    • host:设置为8443。
    • 部署类型:选择在线服务。
    图11 设置模型参数
  3. 填写启动命令,启动命令内容如下:
    sh /home/ma-user/infer/run.sh
  4. 填写apis定义,单击“保存”生效。apis定义中指定输入为文件,具体内容参见下面代码样例。
    图12 填写apis定义

    apis定义具体内容如下:

    [{
    	"url": "/",
    	"method": "post",
    	"request": {
    		"Content-type": "multipart/form-data",
    		"data": {
    			"type": "object",
    			"properties": {
    				"images": {
    					"type": "file"
    				}
    			}
    		}
    	},
    	"response": {
    		"Content-type": "applicaton/json",
    		"data": {
    			"type": "object",
    			"properties": {
    				"result": {
    					"type": "integer"
    				}
    			}
    		}
    	}
    }]

    apis定义提供AI应用对外Restfull api数据定义,用于定义AI应用的输入、输出格式。

    • 创建AI应用填写apis。在创建的AI应用部署服务成功后,进行预测时,会自动识别预测类型。
    • 创建AI应用时不填写apis。在创建的AI应用部署服务成功后,进行预测,需选择“请求类型”。“请求类型”可选择“application/json”或“multipart/form-data”。请根据元模型,选择合适的类型。
  5. 设置完成后,单击“立即创建”,等待AI应用状态变为“正常”
  6. 单击新建的AI应用名称左侧的小三角形,展开AI应用的版本列表。在操作列单击“部署 > 在线服务”,跳转至在线服务的部署页面。
  7. 在部署页面,参考如下说明填写关键参数。

    “名称”:自定义一个在线服务的名称,也可以使用默认值。

    “资源池”:选择“公共资源池”

    “AI应用来源”“选择AI应用及版本”:会自动选择AI应用和版本号。

    “计算节点规格”:在下拉框中选择“限时免费”资源,勾选并阅读免费规格说明。

    其他参数可使用默认值。

    如果限时免费资源售罄,建议选择收费CPU资源进行部署。当选择收费CPU资源部署在线服务时会收取少量资源费用,具体费用以界面信息为准。

  8. 参数配置完成后,单击“下一步”,确认规格参数后,单击“提交”启动在线服务的部署。
  9. 进入“部署上线 > 在线服务”页面,等待服务状态变为“运行中”时,表示服务部署成功。单击操作列的“预测”,进入服务详情页的“预测”页面。上传图片,预测结果。