MindSpore-Model-Development/tutorials/deployment_CN.md

6.3 KiB
Raw Permalink Blame History

部署推理服务

MindSpore Serving是一个轻量级、高性能的推理服务模块旨在帮助MindSpore开发者在生产环境中高效部署在线推理服务。当用户使用MindSpore完成模型训练后导出MindSpore模型即可使用MindSpore Serving创建该模型的推理服务。

本文以mobilenet_v3_small_100网络为例演示基于MindSpore Serving进行部署推理服务的方法。

环境准备

进行部署前需确保已经正确安装了MindSpore Serving并配置了环境变量。MindSpore Serving安装和配置可以参考MindSpore 安装页面

模型导出

实现跨平台或硬件执行推理如昇腾AI处理器、MindSpore端侧、GPU等需要通过网络定义和CheckPoint生成MindIR格式模型文件。在MindSpore中网络模型导出的函数为export,主要参数如下所示:

  • netMindSpore网络结构。
  • inputs网络的输入支持输入类型为Tensor。当输入有多个时需要一起传入ms.export(network, ms.Tensor(input1), ms.Tensor(input2), file_name='network', file_format='MINDIR')
  • file_name:导出模型的文件名称,如果file_name没有包含对应的后缀名(如.mindir),设置file_format后系统会为文件名自动添加后缀。
  • file_formatMindSpore目前支持导出”AIR””ONNX”和”MINDIR”格式的模型。

下面代码以mobilenet_v3_small_100为例导出MindCV的预训练网络模型获得MindIR格式模型文件。

from mindcv.models import create_model
import numpy as np
import mindspore as ms

model = create_model(model_name='mobilenet_v3_small_100', num_classes=1000, pretrained=True)

input_np = np.random.uniform(0.0, 1.0, size=[1, 3, 224, 224]).astype(np.float32)

# 导出文件mobilenet_v3_small_100.mindir到当前文件夹
ms.export(model, ms.Tensor(input_np), file_name='mobilenet_v3_small_100', file_format='MINDIR')

部署Serving推理服务

配置服务

启动Serving服务执行本教程需要如下文件列表:

demo
├── mobilenet_v3_small_100
│   ├── 1
│   │   └── mobilenet_v3_small_100.mindir
│   └── servable_config.py
│── serving_server.py
├── serving_client.py
└── test_image
    ├─ dog
    │   ├─ dog.jpg
    │   └─ ……
    └─ ……
  • mobilenet_v3_small_100为模型文件夹,文件夹名即为模型名。
  • mobilenet_v3_small_100.mindir为上一步网络生成的模型文件放置在文件夹1下1为版本号不同的版本放置在不同的文件夹下版本号需以纯数字串命名默认配置下启动最大数值的版本号的模型文件。
  • servable_config.py为模型配置脚本,对模型进行声明、入参和出参定义。
  • serving_server.py为启动服务脚本文件。
  • serving_client.py为启动客户端脚本文件。
  • test_image中为测试图片。

其中,模型配置文件servable_config.py内容如下:

from mindspore_serving.server import register

# 进行模型声明其中declare_model入参model_file指示模型的文件名称model_format指示模型的模型类别
model = register.declare_model(model_file="mobilenet_v3_small_100.mindir", model_format="MindIR")

# Servable方法的入参由Python方法的入参指定Servable方法的出参由register_method的output_names指定
@register.register_method(output_names=["score"])
def predict(image):
    x = register.add_stage(model, image, outputs_count=1)
    return x

启动服务

MindSpore的server函数提供两种服务部署一种是gRPC方式一种是通过RESTful方式本教程以gRPC方式为例。服务启动脚本serving_server.py把本地目录下的mobilenet_v3_small_100部署到设备0并启动地址为127.0.0.1:5500的gRPC服务器。脚本文件内容如下

import os
import sys
from mindspore_serving import server

def start():
    servable_dir = os.path.dirname(os.path.realpath(sys.argv[0]))

    servable_config = server.ServableStartConfig(servable_directory=servable_dir, servable_name="mobilenet_v3_small_100",
                                                 device_ids=0)
    server.start_servables(servable_configs=servable_config)
    server.start_grpc_server(address="127.0.0.1:5500")

if __name__ == "__main__":
    start()

当服务端打印如下日志时表示Serving gRPC服务启动成功。

Serving gRPC server start success, listening on 127.0.0.1:5500

执行推理

使用serving_client.py启动Python客户端。客户端脚本使用mindcv.datacreate_transforms, create_datasetcreate_loader函数进行图片预处理再传送给Serving服务器。对服务器返回的结果进行后处理打印图片的预测标签。

import os
from mindspore_serving.client import Client
import numpy as np
from mindcv.data import create_transforms, create_dataset, create_loader

num_workers = 1

# 数据集目录路径
data_dir = "./test_image/"

dataset = create_dataset(root=data_dir, split='', num_parallel_workers=num_workers)
transforms_list = create_transforms(dataset_name='ImageNet', is_training=False)
data_loader = create_loader(
        dataset=dataset,
        batch_size=1,
        is_training=False,
        num_classes=1000,
        transform=transforms_list,
        num_parallel_workers=num_workers
    )
with open("imagenet1000_clsidx_to_labels.txt") as f:
    idx2label = eval(f.read())

def postprocess(score):
    max_idx = np.argmax(score)
    return idx2label[max_idx]

def predict():
    client = Client("127.0.0.1:5500", "mobilenet_v3_small_100", "predict")
    instances = []
    images, _ = next(data_loader.create_tuple_iterator())
    image_np = images.asnumpy().squeeze()
    instances.append({"image": image_np})
    result = client.infer(instances)

    for instance in result:
        label = postprocess(instance["score"])
        print(label)

if __name__ == '__main__':
    predict()

执行后显示如下返回值说明Serving服务已正确执行mobilenet_v3_small_100网络模型的推理。

Labrador retriever