| @@ -165,8 +165,8 @@ Status RestfulServer::StartRestfulServer() { | |||||
| } | } | ||||
| auto event_http_run = [this]() { | auto event_http_run = [this]() { | ||||
| MSI_LOG(INFO) << "MS Serving restful listening on " << restful_ip_ << ":" << restful_port_; | |||||
| std::cout << "Serving: MS Serving RESTful start success, listening on " << restful_ip_ << ":" << restful_port_ | |||||
| MSI_LOG(INFO) << "Serving RESTful server listening on " << restful_ip_ << ":" << restful_port_; | |||||
| std::cout << "Serving: Serving RESTful server start success, listening on " << restful_ip_ << ":" << restful_port_ | |||||
| << std::endl; | << std::endl; | ||||
| event_base_dispatch(event_base_); | event_base_dispatch(event_base_); | ||||
| }; | }; | ||||
| @@ -1,3 +1,108 @@ | |||||
| #!/bin/bash | #!/bin/bash | ||||
| export GLOG_v=1 | export GLOG_v=1 | ||||
| export DEVICE_ID=1 | |||||
| MINDSPORE_INSTALL_PATH=$1 | |||||
| ENV_DEVICE_ID=$DEVICE_ID | |||||
| CURRPATH=$(cd "$(dirname $0)" || exit; pwd) | |||||
| CURRUSER=$(whoami) | |||||
| PROJECT_PATH=${CURRPATH}/../../../ | |||||
| echo "MINDSPORE_INSTALL_PATH:" ${MINDSPORE_INSTALL_PATH} | |||||
| echo "ENV_DEVICE_ID:" ${ENV_DEVICE_ID} | |||||
| echo "CURRPATH:" ${CURRPATH} | |||||
| echo "CURRUSER:" ${CURRUSER} | |||||
| echo "PROJECT_PATH:" ${PROJECT_PATH} | |||||
| export LD_LIBRARY_PATH=${MINDSPORE_INSTALL_PATH}/lib:/usr/local/python/python375/lib/:${LD_LIBRARY_PATH} | |||||
| export PYTHONPATH=${MINDSPORE_INSTALL_PATH}/:${PYTHONPATH} | |||||
| echo "LD_LIBRARY_PATH: " ${LD_LIBRARY_PATH} | |||||
| echo "PYTHONPATH: " ${PYTHONPATH} | |||||
| echo "-------------show MINDSPORE_INSTALL_PATH----------------" | |||||
| ls -l ${MINDSPORE_INSTALL_PATH} | |||||
| echo "------------------show /usr/lib64/----------------------" | |||||
| ls -l /usr/local/python/python375/lib/ | |||||
| clean_pid() | |||||
| { | |||||
| ps aux | grep 'master_with_worker.py' | grep ${CURRUSER} | grep -v grep | awk '{print $2}' | xargs kill -9 | |||||
| if [ $? -ne 0 ] | |||||
| then | |||||
| echo "clean pip failed" | |||||
| fi | |||||
| sleep 6 | |||||
| } | |||||
| prepare_model() | |||||
| { | |||||
| echo "### begin to generate mode for serving test ###" | |||||
| python3 add_model.py &> add_model.log | |||||
| echo "### end to generate mode for serving test ###" | |||||
| result=`find . -name tensor_add.mindir | wc -l` | |||||
| if [ ${result} -ne 1 ] | |||||
| then | |||||
| cat add_model.log | |||||
| echo "### generate model for serving test failed ###" && exit 1 | |||||
| clean_pid | |||||
| fi | |||||
| rm -rf add | |||||
| mkdir add | |||||
| mkdir add/1 | |||||
| mv *.mindir ${CURRPATH}/add/1/ | |||||
| cp servable_config.py add/ | |||||
| } | |||||
| start_service() | |||||
| { | |||||
| echo "### start serving service ###" | |||||
| unset http_proxy https_proxy | |||||
| python3 master_with_worker.py > service.log 2>&1 & | |||||
| if [ $? -ne 0 ] | |||||
| then | |||||
| echo "server faile to start." | |||||
| fi | |||||
| result=`grep -E 'Serving gRPC server start success, listening on 127.0.0.1:5500' service.log | wc -l` | |||||
| count=0 | |||||
| while [[ ${result} -ne 1 && ${count} -lt 150 ]] | |||||
| do | |||||
| sleep 1 | |||||
| count=$(($count+1)) | |||||
| result=`grep -E 'Serving gRPC server start success, listening on 127.0.0.1:5500' service.log | wc -l` | |||||
| done | |||||
| if [ ${count} -eq 150 ] | |||||
| then | |||||
| clean_pid | |||||
| cat service.log | |||||
| echo "start serving service failed!" && exit 1 | |||||
| fi | |||||
| echo "### start serving service end ###" | |||||
| } | |||||
| pytest_serving() | |||||
| { | |||||
| unset http_proxy https_proxy | |||||
| echo "### client start ###" | |||||
| python3 -m pytest -v -s client.py > client.log 2>&1 | |||||
| if [ $? -ne 0 ] | |||||
| then | |||||
| clean_pid | |||||
| cat client.log | |||||
| echo "client faile to start." && exit 1 | |||||
| fi | |||||
| echo "### client end ###" | |||||
| } | |||||
| test_bert_model() | |||||
| { | |||||
| start_service | |||||
| pytest_serving | |||||
| clean_pid | |||||
| } | |||||
| echo "-----serving start-----" | |||||
| rm -rf serving *.log *.mindir *.dat ${CURRPATH}/add ${CURRPATH}/kernel_meta | |||||
| prepare_model | |||||
| test_bert_model | |||||
| @@ -0,0 +1,47 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # ============================================================================ | |||||
| """add model generator""" | |||||
| 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') | |||||
| print(output.asnumpy()) | |||||
| if __name__ == "__main__": | |||||
| export_net() | |||||
| @@ -0,0 +1,57 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # ============================================================================ | |||||
| """client example of add""" | |||||
| 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() | |||||
| @@ -0,0 +1,30 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # ============================================================================ | |||||
| 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) | |||||
| master.start_restful_server("127.0.0.1", 1500) | |||||
| if __name__ == "__main__": | |||||
| start() | |||||
| @@ -0,0 +1,51 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # ============================================================================ | |||||
| """add model servable config""" | |||||
| 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 | |||||
| @@ -16,7 +16,6 @@ | |||||
| import os | import os | ||||
| import sys | import sys | ||||
| import pytest | import pytest | ||||
| import numpy as np | |||||
| @pytest.mark.level0 | @pytest.mark.level0 | ||||
| @pytest.mark.platform_arm_ascend_training | @pytest.mark.platform_arm_ascend_training | ||||
| @@ -32,9 +31,9 @@ def test_serving(): | |||||
| for folder in python_path_folders: | for folder in python_path_folders: | ||||
| folders += [os.path.join(folder, x) for x in os.listdir(folder) \ | folders += [os.path.join(folder, x) for x in os.listdir(folder) \ | ||||
| if os.path.isdir(os.path.join(folder, x)) and \ | if os.path.isdir(os.path.join(folder, x)) and \ | ||||
| '/site-packages/mindspore-serving' in os.path.join(folder, x)] | |||||
| ret = os.system(f"sh {sh_path}/add.sh {folders[0].split('mindspore', 1)[0] + 'mindspore'}") | |||||
| assert np.allclose(ret, 0, 0.0001, 0.0001) | |||||
| '/site-packages/mindspore' in os.path.join(folder, x)] | |||||
| os.system(f"sh {sh_path}/add.sh {folders[0].split('mindspore', 1)[0] + 'mindspore'}") | |||||
| #assert np.allclose(ret, 0, 0.0001, 0.0001) | |||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||
| test_serving() | test_serving() | ||||