diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 55e162c3ba916652a5de29b315a7326546f19661..ea0ec0ec1245ea79dbcec7201062c41cd72dea35 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,29 +1,66 @@ +if (CLIENT_ONLY) file(GLOB_RECURSE SERVING_CLIENT_PY_FILES serving_client/*.py) set(PY_FILES ${SERVING_CLIENT_PY_FILES}) SET(PACKAGE_NAME "serving_client") -set(SETUP_LOG_FILE "setup.py.log") +set(SETUP_LOG_FILE "setup.py.client.log") +endif() + +if (NOT CLIENT_ONLY) +file(GLOB_RECURSE SERVING_SERVER_PY_FILES serving_server/*.py) +set(PY_FILES ${SERVING_SERVER_PY_FILES}) +SET(PACKAGE_NAME "serving_server") +set(SETUP_LOG_FILE "setup.py.server.log") +endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in +if (CLIENT_ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.client.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py) +endif() + +if (NOT CLIENT_ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.server.in + ${CMAKE_CURRENT_BINARY_DIR}/setup.py) +endif() set(SERVING_CLIENT_CORE ${PADDLE_SERVING_BINARY_DIR}/core/general-client/serving_client.so) +set(SERVING_SERVER_CORE ${PADDLE_SERVING_BINARY_DIR}/core/predictor/serving_server.so) message("python env: " ${py_env}) +if (CLIENT_ONLY) add_custom_command( OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving/ ${PADDLE_SERVING_BINARY_DIR}/python/ COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_SERVING_BINARY_DIR}/core/general-client/serving_client.so ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/serving_client/ COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel DEPENDS ${SERVING_CLIENT_CORE} sdk_configure_py_proto ${PY_FILES}) - add_custom_target(paddle_python ALL DEPENDS serving_client ${PADDLE_SERVING_BINARY_DIR}/.timestamp) +endif() + +if (NOT CLIENT_ONLY) +add_custom_command( + OUTPUT ${PADDLE_SERVING_BINARY_DIR}/.timestamp + COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/paddle_serving/ ${PADDLE_SERVING_BINARY_DIR}/python/ + COMMAND ${CMAKE_COMMAND} -E copy ${PADDLE_SERVING_BINARY_DIR}/core/predictor/serving_server.so ${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/serving_server/ + COMMAND env ${py_env} ${PYTHON_EXECUTABLE} setup.py bdist_wheel + DEPENDS ${SERVING_SERVER_CORE} server_config_py_proto ${PY_FILES}) +add_custom_target(paddle_python ALL DEPENDS serving_server ${PADDLE_SERVING_BINARY_DIR}/.timestamp) +endif() set(SERVING_CLIENT_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/) +set(SERVING_SERVER_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/) +if (CLIENT_ONLY) install(DIRECTORY ${SERVING_CLIENT_PYTHON_PACKAGE_DIR} DESTINATION opt/serving_client/share/wheels ) +endif() + +if (NOT CLIENT_ONLY) +install(DIRECTORY ${SERVING_SERVER_PYTHON_PACKAGE_DIR} + DESTINATION opt/serving_server/share/wheels +) +endif() find_program(PATCHELF_EXECUTABLE patchelf) if(NOT PATCHELF_EXECUTABLE) diff --git a/python/paddle_serving/serving_server/__init__.py b/python/paddle_serving/serving_server/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..afbc4eaaa7ec252231d1757acde5f8c35537a54e --- /dev/null +++ b/python/paddle_serving/serving_server/__init__.py @@ -0,0 +1,118 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# 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. + +from ..proto import server_configure_pb2 as server_sdk + +class OpMaker(object): + def __init__(self): + self.op_dict = {"general_model":"GeneralModelOp", + "general_reader":"GeneralReaderOp", + "general_single_kv":"GeneralSingleKVOp", + "general_dist_kv":"GeneralDistKVOp"} + + def create(self, name, inputs=[], outputs=[]): + if name not in self.op_dict: + raise Exception("Op name {} is not supported right now".format(name)) + node = server_sdk.DAGNode() + node.name = "{}_op".format(name) + node.type = self.op_dict[name] + return node + +class OpSeqMaker(object): + def __init__(self): + self.workflow = server_sdk.Workflow() + self.workflow.name = "workflow1" + self.workflow.workflow_type = "Sequence" + + def add_op(self, node): + self.workflow.nodes.extend([node]) + + def get_op_sequence(self): + workflow_conf = server_sdk.WorkflowConf() + workflow_conf.workflows.extend([self.workflow]) + return workflow_conf + +class Server(object): + def __init__(self): + self.server_handle_ = None + self.infer_service_conf = None + self.model_toolkit_conf = None + self.engine = None + + def set_op_sequence(self, op_seq): + self.workflow_conf = op_seq + + def _prepare_engine(self, model_config_path, device): + if self.model_toolkit_conf == None: + self.model_toolkit_conf = server_sdk.ModelToolkitConf() + if self.engine == None: + self.engine = server_sdk.EngineDesc() + self.engine.name = "general_model" + self.engine.reloadable_type = "tiemstamp_ne" + self.engine.runtime_thread_num = 0 + self.engine.batch_infer_size = 0 + self.engine.enable_batch_align = 0 + self.engine.model_data_path = model_path + if device == "cpu": + self.engine.type = "FLUID_CPU_ANALYSIS_DIR" + elif device == "gpu": + self.engine.type = "FLUID_GPU_ANALYSIS_DIR" + self.model_toolkit_conf.engines.extend([engine]) + + def _prepare_infer_service(self, port): + if self.infer_service_conf == None: + self.infer_service_conf = server_sdk.InferServiceConf() + self.infer_service_conf.port = port + infer_service = server_sdk.InferService() + infer_service.name = "GeneralModelService" + infer_service.workflows.extend(["workflow1"]) + self.infer_service_conf.services.extend([infer_service]) + + def _prepare_resource(self, workdir): + if self.resource_conf == None: + self.resource_conf = server_sdk.ResourceConf() + self.resource_conf.model_toolkit_path = workdir + self.resource_conf.model_toolkit_file = "server_model_toolkit.prototxt" + + def _write_pb_str(self, filepath, pb_obj): + with open(filepath, "w") as fout: + fout.write(str(pb_obj)) + + def load_model_config(self, path): + self.config_file = "{}/inference.conf".format(path) + # check config here + + def prepare_server(self, port=9292, device="cpu", workdir=None): + if workdir == None: + workdir = "./tmp" + os.system("mkdir {}".format(workdir)) + self._prepare_resource(workdir) + self._prepare_engine(self.config_file, device) + self._prepare_infer_service(port) + self.workdir = workdir + + infer_service_fn = "{}/server_infer_service.prototxt".format(workdir) + workflow_fn = "{}/server_workflow.prototxt".format(workdir) + resource_fn = "{}/server_resource.prototxt".format(workdir) + model_toolkit_fn = "{}/server_model_toolkit.prototxt".format(workdir) + + self._write_pb_str(infer_service_fn, self.infer_service_conf) + self._write_pb_str(workflow_fn, self.workflow_conf) + self._write_pb_str(resource_fn, self.resource_conf) + self._write_pb_str(model_toolkit_fn, self.model_toolkit_conf) + + def run_server(self): + # just run server with system command + os.system("./pdserving {}".format(self.workdir)) + diff --git a/python/paddle_serving/version.py b/python/paddle_serving/version.py index e199e2080bb1ec137a6c0e22b81ee4782defa34f..d67c284b10a57ec866bafcb4a1f28a2529d5073d 100644 --- a/python/paddle_serving/version.py +++ b/python/paddle_serving/version.py @@ -13,4 +13,5 @@ # limitations under the License. """ Paddle Serving Client version string """ serving_client_version = "0.1.0" +serving_server_version = "0.1.0" module_proto_version = "0.1.0" diff --git a/python/setup.py.client.in b/python/setup.py.client.in new file mode 100644 index 0000000000000000000000000000000000000000..90d2fcd59ff83c3f16f01830f690b83277e2c326 --- /dev/null +++ b/python/setup.py.client.in @@ -0,0 +1,80 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# 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. +"""Setup for pip package.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import platform + +from setuptools import setup, Distribution, Extension +from setuptools import find_packages +from setuptools import setup +from paddle_serving.version import serving_client_version + +def python_version(): + return [int(v) for v in platform.python_version().split(".")] + +max_version, mid_version, min_version = python_version() + +REQUIRED_PACKAGES = [ + 'six >= 1.10.0', 'protobuf >= 3.1.0','paddlepaddle' +] + +packages=['paddle_serving', + 'paddle_serving.serving_client', + 'paddle_serving.proto', + 'paddle_serving.io'] +package_data={'paddle_serving.serving_client': ['serving_client.so']} +package_dir={'paddle_serving.serving_client': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/serving_client', + 'paddle_serving.proto': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/proto', + 'paddle_serving.io': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/io'} + +setup( + name='paddle-serving-client', + version=serving_client_version.replace('-', ''), + description= + ('Paddle Serving Package for saved model with PaddlePaddle'), + url='https://github.com/PaddlePaddle/Serving', + author='PaddlePaddle Author', + author_email='guru4elephant@gmail.com', + install_requires=REQUIRED_PACKAGES, + packages=packages, + package_data=package_data, + package_dir=package_dir, + # PyPI package information. + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Mathematics', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], + license='Apache 2.0', + keywords=('paddle-serving serving-client deployment industrial easy-to-use')) + diff --git a/python/setup.py.server.in b/python/setup.py.server.in new file mode 100644 index 0000000000000000000000000000000000000000..7ee7cb4d8e598a5819677b3174e405baab0d5328 --- /dev/null +++ b/python/setup.py.server.in @@ -0,0 +1,81 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# 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. +"""Setup for pip package.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import platform + +from setuptools import setup, Distribution, Extension +from setuptools import find_packages +from setuptools import setup +from paddle_serving.version import serving_client_version +from paddle_serving.version import serving_server_version + +def python_version(): + return [int(v) for v in platform.python_version().split(".")] + +max_version, mid_version, min_version = python_version() + +REQUIRED_PACKAGES = [ + 'six >= 1.10.0', 'protobuf >= 3.1.0','paddlepaddle' +] + +packages=['paddle_serving', + 'paddle_serving.serving_server', + 'paddle_serving.proto', + 'paddle_serving.io'] +package_data={'paddle_serving.serving_server': ['serving_server.so']} +package_dir={'paddle_serving.serving_server': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/serving_server', + 'paddle_serving.proto': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/proto', + 'paddle_serving.io': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving/io'} + +setup( + name='paddle-serving-server', + version=serving_server_version.replace('-', ''), + description= + ('Paddle Serving Package for saved model with PaddlePaddle'), + url='https://github.com/PaddlePaddle/Serving', + author='PaddlePaddle Author', + author_email='guru4elephant@gmail.com', + install_requires=REQUIRED_PACKAGES, + packages=packages, + package_data=package_data, + package_dir=package_dir, + # PyPI package information. + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Mathematics', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], + license='Apache 2.0', + keywords=('paddle-serving serving-server deployment industrial easy-to-use')) +