Browse Source

!36 fix readme

Merge pull request !36 from zhangyinxia/master
tags/v1.1.0
徐永飞 Gitee 5 years ago
parent
commit
d1d888ddfc
5 changed files with 232 additions and 95 deletions
  1. +17
    -91
      README_CN.md
  2. +1
    -1
      docs/GRPC.md
  3. +1
    -1
      docs/MODEL.md
  4. +211
    -0
      docs/example.md
  5. +2
    -2
      mindspore_serving/example/add/master_with_worker.py

+ 17
- 91
README_CN.md View File

@@ -3,14 +3,10 @@
[View English](./README.md)

- [概述](#概述)
- [安装部署](#安装部署)
- [安装MindSpore Serving](#安装MindSpore-Serving)
- [安装](#安装)
- [安装Serving](#安装Serving)
- [配置环境变量](#配置环境变量)
- [部署MindSpore Serving](#部署MindSpore-Serving)
- [快速入门](#快速入门)
- [导出模型](#导出模型)
- [部署Serving推理服务](#部署serving推理服务)
- [执行推理](#执行推理)
- [文档](#文档)
- [开发者教程](#开发者教程)
- [社区](#社区)
@@ -34,15 +30,15 @@ MindSpore Serving是一个轻量级、高性能的服务模块,旨在帮助Min
- 支持batch功能
- 提供客户端python简易接口

## 安装部署
## 安装
MindSpore Serving依赖MindSpore训练推理框架,安装完[MindSpore](https://gitee.com/mindspore/mindspore#%E5%AE%89%E8%A3%85) ,再安装MindSpore Serving。

### 安装MindSpore Serving
### 安装Serving
使用pip命令安装,安装方式如下:

**1、请从MindSpore Serving下载页面下载并安装whl包。**
```python
pip install mindspore_serving-1.0.0-cp37-cp37m-linux_x86_64.whl
pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.0.1/Serving/ascend/ubuntu_x86/mindspore_serving-0.0.1-cp37-cp37m-linux_x86_64.whl
```
**2、源码安装。**
下载[源码](https://gitee.com/mindspore/serving)。
@@ -60,104 +56,34 @@ sh build.sh -eacl
# ascend 910
sh build.sh -ed
```

编译完后,在output/目录下找到安装包进行安装:
```python
pip install mindspore_serving-0.1.0-cp37-cp37m-linux_x86_64.whl
```
### 配置环境变量
Asend 910环境上安装mindspore,需要完成[环境变量配置](https://gitee.com/mindspore/docs/blob/master/install/mindspore_ascend_install_pip.md#%E9%85%8D%E7%BD%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F)。
运行MindSpore Serving,还需要增加额外mindspore软件包的安装路径下的lib路径到LD_LIBRARY_PATH。
```shell
export LD_LIBRARY_PATH=$MINDSPORE_LIB_PATH:${LD_LIBRARY_PATH}
pip install mindspore_serving-0.0.1-cp37-cp37m-linux_x86_64.whl
```

### 部署MindSpore Serving
MindSpore Serving提供两种部署方式,用户可根据需要进行选择部署。

**轻量级部署:**
服务端调用python接口直接启动推理进程(master和worker共进程),客户端直接连接推理服务后下发推理任务。
启动服务:
**执行以下命令,验证安装结果。导入python模块不报错即安装成功。**
```python
import os
from mindspore_serving import master
from mindspore_serving import worker
servable_dir = os.path.abspath(".")
worker.start_servable_in_master(servable_dir, "xxx", device_id=0)
master.start_grpc_server("127.0.0.1", 5500)
```

**集群部署:**
服务端由master进程和worker进程组成,master用来管理集群内所有的worker节点,并进行推理任务的分发。
启动worker:
```python
import os
from mindspore_serving import worker
servable_dir = os.path.abspath(".")
worker.start_servable(servable_dir, "lenet", device_id=0,
master_ip="127.0.0.1", master_port=5500,
host_ip="127.0.0.1", host_port=5600)
```
启动master:
```python
from mindspore_serving import master
master.start_grpc_server("127.0.0.1", 5500)
### 配置环境变量
Asend 910环境上安装mindspore,需要完成[环境变量配置](https://gitee.com/mindspore/docs/blob/master/install/mindspore_ascend_install_pip.md#%E9%85%8D%E7%BD%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F)。
运行MindSpore Serving,还需要增加额外mindspore软件包的安装路径下的lib路径到LD_LIBRARY_PATH。
```shell
export LD_LIBRARY_PATH=$MINDSPORE_LIB_PATH:${LD_LIBRARY_PATH}
```
完成服务端部署后,即可启用客户端程序执行推理操作。

## 快速入门
以一个简单的Add网络为例,演示MindSpore Serving如何使用。

### 导出模型
使用[add_model.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/export_model/add_model.py),构造一个只有Add算子的网络,并导出MindSpore推理部署模型。

```python
python add_model.py
```
执行脚本,生成`tensor_add.mindir`文件,该模型的输入为两个shape为[2,2]的二维Tensor,输出结果是两个输入Tensor之和。

### 部署Serving推理服务
执行以下[python程序](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/master_with_worker.py),启动服务:
```bash
import os
from mindspore_serving import master
from mindspore_serving import worker
def start():
servable_dir = os.path.abspath(".")
worker.start_servable_in_master(servable_dir, "add", device_id=0)
master.start_grpc_server("127.0.0.1", 5500)
```
启动过程需要使用servable_dir路径下的模型文件和配置文件,文件目录结果如下图所示:
<pre><font color="#268BD2"><b>add/</b></font>
├── <font color="#268BD2"><b>1</b></font>
│   └── tensor_add.mindir
└── servable_config.py
</pre>
其中,模型文件为上一步网络生成的,即`tensor_add.mindir`文件。配置文件为[servable_config.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/add/servable_config.py),其定义了模型的处理函数,包含前处理和后处理过程。
当服务端打印日志`Serving gRPC start success, listening on 0.0.0.0:5500`时,表示Serving服务已加载推理模型完毕。

### 执行推理
使用[client.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/client.py),启动Python客户端。
```bash
python client.py
```

显示如下返回值说明Serving服务已正确执行Add网络的推理。
```bash
[{'y': array([[2. , 2.],
[2., 2.]], dtype=float32)}]
[{'y': array([[2. , 2.],
[2., 2.]], dtype=float32)}]
```
以一个简单的[Add网络示例](docs/example.md),演示MindSpore Serving如何使用。

## 文档

### 开发者教程
- [如何使用python接口开发客户端?](docs/GRPC.md)
- [如何启动Restful服务进行推理?](docs/RESTful.md)
- [如何实现模型前处理和后处理?](docs/MODEL.md)
- [gRPC接口使用说明](docs/GRPC.md)
- [RESTful接口使用说明](docs/RESTful.md)
- [模型配置接口使用说明](docs/MODEL.md)

有关安装指南、教程和API的更多详细信息,请参阅[用户文档](https://gitee.com/mindspore/serving/docs)。
有关安装指南、教程和API的更多详细信息,请参阅[用户文档](https://gitee.com/mindspore/serving/tree/master/docs)。

## 社区



+ 1
- 1
docs/GRPC.md View File

@@ -1,4 +1,4 @@
# gRPC接口使用
# gRPC接口使用说明

## 概述
MindSpore Serving提供gRPC接口访问Serving服务。在Python环境下,我们提供[mindspore_serving.client](../mindspore_serving/client/python/client.py) 接口填写请求、解析回复。接下来我们详细说明`mindspore_serving.client`如何使用。


+ 1
- 1
docs/MODEL.md View File

@@ -1,4 +1,4 @@
# 模型配置接口
# 模型配置接口使用说明

## 概述



+ 211
- 0
docs/example.md View File

@@ -0,0 +1,211 @@
# 实现一个Add网络示例

## 概述
以一个简单的Add网络为例,演示MindSpore Serving如何使用。

### 导出模型
使用[add_model.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/export_model/add_model.py),构造一个只有Add算子的网络,并导出MindSpore推理部署模型。

```python
import os
from shutil import copyfile
import numpy as np
import mindspore.context as context
import mindspore.nn as nn
from mindspore.ops import operations as P
from mindspore import Tensor
from mindspore.train.serialization import export

context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")

class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.add = P.TensorAdd()

def construct(self, x_, y_):
return self.add(x_, y_)

def export_net():
x = np.ones([2, 2]).astype(np.float32)
y = np.ones([2, 2]).astype(np.float32)
add = Net()
output = add(Tensor(x), Tensor(y))
export(add, Tensor(x), Tensor(y), file_name='tensor_add', file_format='MINDIR')
dst_dir = '../add/1'
try:
os.mkdir(dst_dir)
except OSError:
pass
try:
dst_file = os.path.join(dst_dir, 'tensor_add.mindir')
if os.path.exists('tensor_add.mindir'):
copyfile('tensor_add.mindir', dst_file)
print("copy tensor_add.mindir to " + dst_dir + " success")
elif os.path.exists('tensor_add'):
copyfile('tensor_add', dst_file)
print("copy tensor_add to " + dst_dir + " success")
except:
print("copy tensor_add.mindir to " + dst_dir + " failed")
print(x)
print(y)
print(output.asnumpy())

if __name__ == "__main__":
export_net()
```
使用MindSpore定义神经网络需要继承mindspore.nn.Cell。Cell是所有神经网络的基类。神经网络的各层需要预先在__init__方法中定义,然后通过定义construct方法来完成神经网络的前向构造。使用mindspore.train.serialization模块的export即可导出模型文件。
更为详细完整的示例可以参考[实现一个图片分类应用](https://www.mindspore.cn/tutorial/training/zh-CN/master/quick_start/quick_start.html)。

执行add_model.py脚本,生成`tensor_add.mindir`文件,该模型的输入为两个shape为[2,2]的二维Tensor,输出结果是两个输入Tensor之和。

### 部署Serving推理服务
启动Serving服务,当前目录下需要有模型文件夹,如add,文件夹下放置版本模型文件和配置文件,文件目录结果如下图所示:
<pre><font color="#268BD2"><b>test_dir/</b></font>
├── <font color="#268BD2"><b>add/</b></font>
│   └── servable_config.py
│  └─<font color="#268BD2"><b>1/</b></font>
│   └── tensor_add.mindir
└── master_with_worker.py
</pre>
其中,模型文件为上一步网络生成的,即`tensor_add.mindir`文件,放置在文件夹1下,1为版本号,不同的版本放置在不同的文件夹下。
配置文件为[servable_config.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/add/servable_config.py),其定义了模型的处理函数。
```python
from mindspore_serving.worker import register
import numpy as np

# define preprocess pipeline, the function arg is multi instances, every instance is tuple of inputs
# this example has one input and one output
def add_trans_datatype(instances):
"""preprocess python implement"""
for instance in instances:
x1 = instance[0]
x2 = instance[1]
yield x1.astype(np.float32), x2.astype(np.float32)


# when with_batch_dim set to False, only support 2x2 add
# when with_batch_dim set to True(default), support Nx2 add, while N is view as batch
# float32 inputs/outputs
register.declare_servable(servable_file="tensor_add.mindir", model_format="MindIR", with_batch_dim=False)


# register add_common method in add
@register.register_method(output_names=["y"])
def add_common(x1, x2): # only support float32 inputs
"""method add_common data flow definition, only call model servable"""
y = register.call_servable(x1, x2)
return y


# register add_cast method in add
@register.register_method(output_names=["y"])
def add_cast(x1, x2):
"""method add_cast data flow definition, only call preprocess and model servable"""
x1, x2 = register.call_preprocess(add_trans_datatype, x1, x2) # cast input to float32
y = register.call_servable(x1, x2)
return y
```
该文件定义了add_common和add_cast两个方法。

MindSpore Serving提供两种部署方式,轻量级部署和集群部署,用户可根据需要进行选择部署。
**轻量级部署:**
服务端调用python接口直接启动推理进程(master和worker共进程),客户端直接连接推理服务后下发推理任务。
执行[master_with_worker.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/master_with_worker.py),完成轻量级部署服务如下:
```python
import os
from mindspore_serving import master
from mindspore_serving import worker

def start():
servable_dir = os.path.abspath(".")
worker.start_servable_in_master(servable_dir, "add", device_id=0)
master.start_grpc_server("127.0.0.1", 5500)

if __name__ == "__main__":
start()
```
当服务端打印日志`Serving gRPC start success, listening on 0.0.0.0:5500`时,表示Serving服务已加载推理模型完毕。


**集群部署:**
服务端由master进程和worker进程组成,master用来管理集群内所有的worker节点,并进行推理任务的分发。 部署方式如下:
部署master:
```python
import os
from mindspore_serving import master

def start():
servable_dir = os.path.abspath(".")
master.start_grpc_server("127.0.0.1", 5500)
master.start_master_server("127.0.0.1", 6500)
if __name__ == "__main__":
start()
```
部署worker:
```python
import os
from mindspore_serving import master

def start():
servable_dir = os.path.abspath(".")
worker.start_servable(servable_dir, "add", device_id=0,
master_ip="127.0.0.1", master_port=6500,
host_ip="127.0.0.1", host_port=6600)

if __name__ == "__main__":
start()
```
轻量级部署和集群部署除了master和woker进程是否隔离,worker使用的接口也不同,轻量级部署使用worker的start_servable_in_master接口,集群部署使用worker的start_servable接口。

### 执行推理
使用[client.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/client.py),启动Python客户端。
```python
import numpy as np
from mindspore_serving.client import Client

def run_add_common():
"""invoke servable add method add_common"""
client = Client("localhost", 5500, "add", "add_common")
instances = []

# instance 1
x1 = np.asarray([[1, 1], [1, 1]]).astype(np.float32)
x2 = np.asarray([[1, 1], [1, 1]]).astype(np.float32)
instances.append({"x1": x1, "x2": x2})

# instance 2
x1 = np.asarray([[2, 2], [2, 2]]).astype(np.float32)
x2 = np.asarray([[2, 2], [2, 2]]).astype(np.float32)
instances.append({"x1": x1, "x2": x2})

# instance 3
x1 = np.asarray([[3, 3], [3, 3]]).astype(np.float32)
x2 = np.asarray([[3, 3], [3, 3]]).astype(np.float32)
instances.append({"x1": x1, "x2": x2})

result = client.infer(instances)
print(result)

def run_add_cast():
"""invoke servable add method add_cast"""
client = Client("localhost", 5500, "add", "add_cast")
instances = []
x1 = np.ones((2, 2), np.int32)
x2 = np.ones((2, 2), np.int32)
instances.append({"x1": x1, "x2": x2})
result = client.infer(instances)
print(result)

if __name__ == '__main__':
run_add_common()
run_add_cast()
```

使用mindspore_serving.client定义的Client类,分别调用模型的两个方法,显示如下返回值说明Serving服务已正确执行Add网络的推理。
```bash
[{'y': array([[2. , 2.],
[2., 2.]], dtype=float32)}]
[{'y': array([[2. , 2.],
[2., 2.]], dtype=float32)}]
```

+ 2
- 2
mindspore_serving/example/add/master_with_worker.py View File

@@ -22,8 +22,8 @@ def start():
servable_dir = os.path.abspath(".")
worker.start_servable_in_master(servable_dir, "add", device_id=0)

master.start_grpc_server("0.0.0.0", 5500)
master.start_restful_server("0.0.0.0", 1500)
master.start_grpc_server("127.0.0.1", 5500)
master.start_restful_server("127.0.0.1", 1500)


if __name__ == "__main__":


Loading…
Cancel
Save