
# 在Notebook中通过镜像保存功能制作自定义镜像用于推理
#### 场景说明
本文详细介绍如何将本地已经制作好的模型包导入ModelArts的开发环境Notebook中进行调试和保存，然后将保存后的镜像部署到推理。本案例仅适用于华为云北京四和上海一站点。
操作流程如下：
1. [步骤一：在Notebook中复制模型包]
2. [步骤二：在Notebook中调试模型]
3. [步骤三：Notebook中保存镜像]
4. [步骤四：使用保存成功的镜像用于推理部署]
 
 #### 步骤一：在Notebook中复制模型包
1. 登录[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，在左侧导航栏按需选择以下操作。
   - 新版控制台：选择"模型开发与训练 \> Notebook"，进入"Notebook"页面。
   
   - 旧版控制台：选择"开发空间 \> Notebook"，进入"Notebook"页面。
    
2. 单击右上角"创建"，进入"创建Notebook"页面，请参见如下说明填写参数。
   1. 填写Notebook基本信息，包含名称、描述、是否自动停止。
   
   2. 填写Notebook详细参数，如选择镜像、资源规格等。
      - "镜像"：选择公共镜像**tensorflow_2.1-cuda_10.1-cudnn7-ubuntu_18.04** 或者**pytorch1.8-cuda10.2-cudnn7-ubuntu18.04**。
      
      - "资源类型"：选择公共资源池或专属资源池，此处以公共资源池为例。
      
      - "规格"：推荐选择GP Tnt004规格，如果没有再选择其他规格。
       
    
3. 参数填写完成后，单击"立即创建"进行规格确认。参数确认无误后，单击"提交"，完成Notebook的创建操作。 进入Notebook列表，正在创建中的Notebook状态为"创建中"，创建过程需要几分钟，请耐心等待。
   
4. 当Notebook状态变为"运行中"时，表示Notebook已创建并启动完成。单击"操作列"的"接入环境"，在"JupyterLab接入"右侧单击"接入"，进入JupyterLab的Launcher界面。
   图1打开后进入JupyterLab的Launcher界面   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586791919.png "点击放大") 
5. 通过![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556431984.png)功能，上传模型包文件到Notebook中，默认工作目录/home/ma-user/work/。模型包文件需要用户自己准备，样例内容参见[模型包文件样例]。
   图2上传模型包   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586951899.png) 
6. 打开Terminal终端，解压model.zip，解压后删除zip文件。
   ```
   #解压命令
   unzip model.zip
   ```
   图3在Terminal终端中解压model.zip   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556272346.png "点击放大") 
7. 在Terminal运行界面，执行复制命令。
   ```
   cp -rf model/*  /home/ma-user/infer/model/1
   ```
   然后执行如下命令查看镜像文件复制成功。
   ```
   cd /home/ma-user/infer/model/1
   ```
   ```
   ll
   ```
   图4查看镜像文件复制成功   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586791961.png "点击放大") 
 
 #### 模型包文件样例
模型包文件model.zip中需要用户自己准备模型文件，此处仅是举例示意说明，以一个手写数字识别模型为例。
Model目录下必须要包含推理脚本文件customize_service.py，目的是为开发者提供模型预处理和后处理的逻辑。
图5推理模型model目录示意图（需要用户自己准备模型文件）   
![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556432032.png "点击放大")
推理脚本customize_service.py的具体写法要求可以参考[模型推理代码编写说明](https://support.huaweicloud.com/usermanual-standard-modelarts/inference-modelarts-0057.html)。
本案例中提供的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())
        }
```
 #### 步骤二：在Notebook中调试模型
1. 打开一个新的Terminal终端，进入"/home/ma-user/infer/"目录，运行启动脚本run.sh，并预测模型。基础镜像中默认提供了run.sh作为启动脚本。启动命令如下：
   ```
   sh  run.sh
   ```
   图6运行启动脚本   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586951941.png "点击放大") 
2. 上传一张预测图片（手写数字图片）到Notebook中。
   图7手写数字图片   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556272418.png)
   图8上传预测图片   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586792015.png) 
3. 重新打开一个新的Terminal终端，执行如下命令进行预测。
   ```
   curl -kv -F 'images=@/home/ma-user/work/test.png' -X POST http://127.0.0.1:8080/
   ```
   图9预测   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556432076.png "点击放大")
   在调试过程中，如果有修改模型文件或者推理脚本文件，需要重启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脚本   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586951999.png "点击放大") 
 
 #### 步骤三：Notebook中保存镜像
Notebook实例状态必须为"运行中"才可以一键进行镜像保存。具体操作，请参见[保存Notebook实例](https://support.huaweicloud.com/devtool-modelarts/devtool-modelarts_0008.html)。
 #### 步骤四：使用保存成功的镜像用于推理部署
将[步骤二：在Notebook中调试模型]的自定义镜像导入到模型中，并部署为在线服务。
1. 登录[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，在左侧导航栏中选择"资产管理 \> 模型管理"，单击"创建模型"，进入创建模型。
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/public_sys-resources/note_3.0-zh-cn.png)
   如果您使用的是新版控制台，请在左侧导航栏最下方单击"返回旧版"，然后在"资产管理 \> 模型管理"页面创建模型。
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556272444.png)
   
2. 设置模型的参数，如[图11]所示。
   - 元模型来源：从容器镜像中选择。
   
   - 容器镜像所在的路径：单击![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586792037.png)选择镜像文件。
   
   - 容器调用接口：选择HTTPS。
   
   - host：设置为8443。
   
   - 部署类型：选择在线服务。
   
   
   图11设置模型参数   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556432100.png "点击放大") 
3. 填写启动命令，启动命令内容如下：
   ```
   sh /home/ma-user/infer/run.sh
   ```
   
4. 填写apis定义，单击"保存"生效。apis定义中指定输入为文件，具体内容参见下面代码样例。
   图12填写apis定义   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586952017.png "点击放大")
   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"
   }
   }
   }
   }
   }]
   ```
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/public_sys-resources/notice_3.0-zh-cn.png)
   apis定义提供模型对外RESTful api数据定义，用于定义模型的输入、输出格式。
   - 创建模型填写apis。在创建的模型部署服务成功后，进行预测时，会自动识别预测类型。
   
   - 创建模型时不填写apis。在创建的模型部署服务成功后，进行预测，需选择"请求类型"。"请求类型"可选择"application/json"或"multipart/form-data"。请根据元模型，选择合适的类型。
     - 选择"application/json"时，直接填写"预测代码"进行文本预测。
     
     - 选择"multipart/form-data"时，需填写"请求参数"，请求参数取值等同于[方式一：使用图形界面的软件进行预测（以Postman为例）](https://support.huaweicloud.com/inference-modelarts/inference2.0-modelarts-0007.html#section2)Body页签中填写的"KEY"的取值，也等同于[方式二：使用curl命令发送预测请求](https://support.huaweicloud.com/inference-modelarts/inference2.0-modelarts-0007.html#section3)上传数据的参数名。
      
     
5. 设置完成后，单击"立即创建"，等待模型状态变为"正常"。
6. 单击新建的模型名称左侧的小三角形，展开模型的版本列表。在操作列单击"部署 \> 在线服务"，跳转至在线服务的部署页面。
7. 在部署页面，参考如下说明填写关键参数。 "名称"：自定义一个在线服务的名称，也可以使用默认值。
   "资源池"：选择"公共资源池"。
   "模型来源"和"选择模型及版本"：会自动选择模型和版本号。
   "实例规格"：在下拉框中选择"限时免费"资源，勾选并阅读免费规格说明。
   其他参数可使用默认值。
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/public_sys-resources/note_3.0-zh-cn.png)
   如果限时免费资源售罄，建议选择收费CPU资源部署。当选择收费CPU资源部署在线服务时会收取少量资源费用，具体费用以界面信息为准。
   
8. 参数配置完成后，单击"下一步"，确认规格参数后，单击"提交"启动在线服务的部署。
9. 进入"部署上线 \> 在线服务"页面，等待服务状态变为"运行中"时，表示服务部署成功。单击操作列的"预测"，进入服务详情页的"预测"页面。上传图片，预测结果。
