You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

example.md 8.7 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. # 实现一个Add网络示例
  2. `Linux` `Ascend` `Serving` `初级` `中级` `高级`
  3. <!-- TOC -->
  4. - [实现一个Add网络示例](#实现一个add网络示例)
  5. - [概述](#概述)
  6. - [导出模型](#导出模型)
  7. - [部署Serving推理服务](#部署serving推理服务)
  8. - [执行推理](#执行推理)
  9. <!-- /TOC -->
  10. <a href="https://gitee.com/mindspore/serving/blob/master/docs/example.md" target="_blank"><img src="image/logo_source.png"></a>
  11. ## 概述
  12. 以一个简单的Add网络为例,演示MindSpore Serving如何使用。
  13. ### 导出模型
  14. 使用[add_model.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/export_model/add_model.py),构造一个只有Add算子的网络,并导出MindSpore推理部署模型。
  15. ```python
  16. import os
  17. from shutil import copyfile
  18. import numpy as np
  19. import mindspore.context as context
  20. import mindspore.nn as nn
  21. from mindspore.ops import operations as P
  22. from mindspore import Tensor
  23. from mindspore.train.serialization import export
  24. context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
  25. class Net(nn.Cell):
  26. def __init__(self):
  27. super(Net, self).__init__()
  28. self.add = P.TensorAdd()
  29. def construct(self, x_, y_):
  30. return self.add(x_, y_)
  31. def export_net():
  32. x = np.ones([2, 2]).astype(np.float32)
  33. y = np.ones([2, 2]).astype(np.float32)
  34. add = Net()
  35. output = add(Tensor(x), Tensor(y))
  36. export(add, Tensor(x), Tensor(y), file_name='tensor_add', file_format='MINDIR')
  37. dst_dir = '../add/1'
  38. try:
  39. os.mkdir(dst_dir)
  40. except OSError:
  41. pass
  42. try:
  43. dst_file = os.path.join(dst_dir, 'tensor_add.mindir')
  44. if os.path.exists('tensor_add.mindir'):
  45. copyfile('tensor_add.mindir', dst_file)
  46. print("copy tensor_add.mindir to " + dst_dir + " success")
  47. elif os.path.exists('tensor_add'):
  48. copyfile('tensor_add', dst_file)
  49. print("copy tensor_add to " + dst_dir + " success")
  50. except:
  51. print("copy tensor_add.mindir to " + dst_dir + " failed")
  52. print(x)
  53. print(y)
  54. print(output.asnumpy())
  55. if __name__ == "__main__":
  56. export_net()
  57. ```
  58. 使用MindSpore定义神经网络需要继承mindspore.nn.Cell。Cell是所有神经网络的基类。神经网络的各层需要预先在__init__方法中定义,然后通过定义construct方法来完成神经网络的前向构造。使用mindspore.train.serialization模块的export即可导出模型文件。
  59. 更为详细完整的示例可以参考[实现一个图片分类应用](https://www.mindspore.cn/tutorial/training/zh-CN/master/quick_start/quick_start.html)。
  60. 执行add_model.py脚本,生成`tensor_add.mindir`文件,该模型的输入为两个shape为[2,2]的二维Tensor,输出结果是两个输入Tensor之和。
  61. ### 部署Serving推理服务
  62. 启动Serving服务,当前目录下需要有模型文件夹,如add,文件夹下放置版本模型文件和配置文件,文件目录结果如下图所示:
  63. <pre><font color="#268BD2"><b>test_dir/</b></font>
  64. ├── <font color="#268BD2"><b>add/</b></font>
  65. │   └── servable_config.py
  66. │  └─<font color="#268BD2"><b>1/</b></font>
  67. │   └── tensor_add.mindir
  68. └── master_with_worker.py
  69. </pre>
  70. 其中,模型文件为上一步网络生成的,即`tensor_add.mindir`文件,放置在文件夹1下,1为版本号,不同的版本放置在不同的文件夹下。
  71. 配置文件为[servable_config.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/add/servable_config.py),其定义了模型的处理函数。
  72. ```python
  73. from mindspore_serving.worker import register
  74. import numpy as np
  75. # define preprocess pipeline, the function arg is multi instances, every instance is tuple of inputs
  76. # this example has one input and one output
  77. def add_trans_datatype(instances):
  78. """preprocess python implement"""
  79. for instance in instances:
  80. x1 = instance[0]
  81. x2 = instance[1]
  82. yield x1.astype(np.float32), x2.astype(np.float32)
  83. # when with_batch_dim set to False, only support 2x2 add
  84. # when with_batch_dim set to True(default), support Nx2 add, while N is view as batch
  85. # float32 inputs/outputs
  86. register.declare_servable(servable_file="tensor_add.mindir", model_format="MindIR", with_batch_dim=False)
  87. # register add_common method in add
  88. @register.register_method(output_names=["y"])
  89. def add_common(x1, x2): # only support float32 inputs
  90. """method add_common data flow definition, only call model servable"""
  91. y = register.call_servable(x1, x2)
  92. return y
  93. # register add_cast method in add
  94. @register.register_method(output_names=["y"])
  95. def add_cast(x1, x2):
  96. """method add_cast data flow definition, only call preprocess and model servable"""
  97. x1, x2 = register.call_preprocess(add_trans_datatype, x1, x2) # cast input to float32
  98. y = register.call_servable(x1, x2)
  99. return y
  100. ```
  101. 该文件定义了add_common和add_cast两个方法。
  102. MindSpore Serving提供两种部署方式,轻量级部署和集群部署,用户可根据需要进行选择部署。
  103. **轻量级部署:**
  104. 服务端调用python接口直接启动推理进程(master和worker共进程),客户端直接连接推理服务后下发推理任务。
  105. 执行[master_with_worker.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/master_with_worker.py),完成轻量级部署服务如下:
  106. ```python
  107. import os
  108. from mindspore_serving import master
  109. from mindspore_serving import worker
  110. def start():
  111. servable_dir = os.path.abspath(".")
  112. worker.start_servable_in_master(servable_dir, "add", device_id=0)
  113. master.start_grpc_server("127.0.0.1", 5500)
  114. if __name__ == "__main__":
  115. start()
  116. ```
  117. 当服务端打印日志`Serving gRPC start success, listening on 0.0.0.0:5500`时,表示Serving服务已加载推理模型完毕。
  118. **集群部署:**
  119. 服务端由master进程和worker进程组成,master用来管理集群内所有的worker节点,并进行推理任务的分发。 部署方式如下:
  120. 部署master:
  121. ```python
  122. import os
  123. from mindspore_serving import master
  124. def start():
  125. servable_dir = os.path.abspath(".")
  126. master.start_grpc_server("127.0.0.1", 5500)
  127. master.start_master_server("127.0.0.1", 6500)
  128. if __name__ == "__main__":
  129. start()
  130. ```
  131. 部署worker:
  132. ```python
  133. import os
  134. from mindspore_serving import master
  135. def start():
  136. servable_dir = os.path.abspath(".")
  137. worker.start_servable(servable_dir, "add", device_id=0,
  138. master_ip="127.0.0.1", master_port=6500,
  139. host_ip="127.0.0.1", host_port=6600)
  140. if __name__ == "__main__":
  141. start()
  142. ```
  143. 轻量级部署和集群部署除了master和woker进程是否隔离,worker使用的接口也不同,轻量级部署使用worker的start_servable_in_master接口,集群部署使用worker的start_servable接口。
  144. ### 执行推理
  145. 使用[client.py](https://gitee.com/mindspore/serving/blob/master/mindspore_serving/example/add/client.py),启动Python客户端。
  146. ```python
  147. import numpy as np
  148. from mindspore_serving.client import Client
  149. def run_add_common():
  150. """invoke servable add method add_common"""
  151. client = Client("localhost", 5500, "add", "add_common")
  152. instances = []
  153. # instance 1
  154. x1 = np.asarray([[1, 1], [1, 1]]).astype(np.float32)
  155. x2 = np.asarray([[1, 1], [1, 1]]).astype(np.float32)
  156. instances.append({"x1": x1, "x2": x2})
  157. # instance 2
  158. x1 = np.asarray([[2, 2], [2, 2]]).astype(np.float32)
  159. x2 = np.asarray([[2, 2], [2, 2]]).astype(np.float32)
  160. instances.append({"x1": x1, "x2": x2})
  161. # instance 3
  162. x1 = np.asarray([[3, 3], [3, 3]]).astype(np.float32)
  163. x2 = np.asarray([[3, 3], [3, 3]]).astype(np.float32)
  164. instances.append({"x1": x1, "x2": x2})
  165. result = client.infer(instances)
  166. print(result)
  167. def run_add_cast():
  168. """invoke servable add method add_cast"""
  169. client = Client("localhost", 5500, "add", "add_cast")
  170. instances = []
  171. x1 = np.ones((2, 2), np.int32)
  172. x2 = np.ones((2, 2), np.int32)
  173. instances.append({"x1": x1, "x2": x2})
  174. result = client.infer(instances)
  175. print(result)
  176. if __name__ == '__main__':
  177. run_add_common()
  178. run_add_cast()
  179. ```
  180. 使用mindspore_serving.client定义的Client类,分别调用模型的两个方法,显示如下返回值说明Serving服务已正确执行Add网络的推理。
  181. ```bash
  182. [{'y': array([[2. , 2.],
  183. [2., 2.]], dtype=float32)},{'y': array([[4. , 4.],
  184. [4., 4.]], dtype=float32)},{'y': array([[6. , 6.],
  185. [6., 6.]], dtype=float32)}]
  186. [{'y': array([[2. , 2.],
  187. [2., 2.]], dtype=float32)}]
  188. ```

A lightweight and high-performance service module that helps MindSpore developers efficiently deploy online inference services in the production environment.