diff --git a/doc/UWSGI_DEPLOY.md b/doc/UWSGI_DEPLOY.md index 02c0488d1bc0c43e050421e0991125fb3a4d644e..cb3fb506bf6fd4461240ebe43234fa3bed3d4784 100644 --- a/doc/UWSGI_DEPLOY.md +++ b/doc/UWSGI_DEPLOY.md @@ -1,6 +1,8 @@ -# 使用uwsgi启动HTTP预测服务 +# Deploy HTTP service with uWSGI -在提供的fit_a_line示例中,启动HTTP预测服务后会看到有以下信息: +([简体中文](./UWSGI_DEPLOY_CN.md)|English) + +In fit_a_line example, after starting the HTTP prediction service, you will see the following information: ```shell web service address: @@ -13,46 +15,31 @@ http://10.127.3.150:9393/uci/prediction * Running on http://0.0.0.0:9393/ (Press CTRL+C to quit) ``` -这里会提示启动的HTTP服务是开发模式,并不能用于生产环境的部署。Flask启动的服务环境不够稳定也无法承受大量请求的并发,实际部署过程中配合需要WSGI(Web Server Gateway Interface)使用。 +Here you will be prompted that the HTTP service started is in development mode and cannot be used for production deployment. +The prediction service started by Flask is not stable enough to withstand the concurrency of a large number of requests. In the actual deployment process, WSGI (Web Server Gateway Interface) is used. -下面我们展示一下如何使用[uWSGI](https://github.com/unbit/uwsgi)模块来部署HTTP预测服务用于生产环境。 +Next, we will show how to use the [uWSGI] (https://github.com/unbit/uwsgi) module to deploy HTTP prediction services for production environments. -编写HTTP服务脚本 ```python #uwsgi_service.py from paddle_serving_server.web_service import WebService -from flask import Flask, request -#配置预测服务 +#Define prediction service uci_service = WebService(name = "uci") uci_service.load_model_config("./uci_housing_model") uci_service.prepare_server(workdir="./workdir", port=int(9500), device="cpu") uci_service.run_server() - -#配置flask服务 -app_instance = Flask(__name__) -@app_instance.before_first_request -def init(): - global uci_service - uci_service._launch_web_service() - -service_name = "/" + uci_service.name + "/prediction" -@app_instance.route(service_name, methods=["POST"]) -def run(): - return uci_service.get_prediction(request) - -#run方法用于直接调试中直接启动服务 -if __name__ == "__main__": - app_instance.run() +#Get flask application +app_instance = uci_service.get_app_instance() ``` -使用uwsgi启动HTTP服务 +Start service with uWSGI ```bash -uwsgi --http :9000 --wsgi-file uwsgi_service.py --callable app_instance --processes 4 +uwsgi --http :9393 --module uwsgi_service:app_instance ``` -使用--processes参数可以指定服务的进程数,请注意目前Serving HTTP 服务暂时不支持多线程的方式使用。 +Use the --processes parameter to specify the number of service processes. -更多uWSGI的信息请参考[uWSGI使用文档](https://uwsgi-docs.readthedocs.io/en/latest/) +For more information about uWSGI, please refer to [uWSGI documentation](https://uwsgi-docs.readthedocs.io/en/latest/) diff --git a/doc/UWSGI_DEPLOY_CN.md b/doc/UWSGI_DEPLOY_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..5bb87e26bbae729f8c21b4681413a4c9f5c4e7c8 --- /dev/null +++ b/doc/UWSGI_DEPLOY_CN.md @@ -0,0 +1,45 @@ +# 使用uwsgi启动HTTP预测服务 + +(简体中文|[English](./UWSGI_DEPLOY.md)) + +在提供的fit_a_line示例中,启动HTTP预测服务后会看到有以下信息: + +```shell +web service address: +http://10.127.3.150:9393/uci/prediction + * Serving Flask app "serve" (lazy loading) + * Environment: production + WARNING: This is a development server. Do not use it in a production deployment. + Use a production WSGI server instead. + * Debug mode: off + * Running on http://0.0.0.0:9393/ (Press CTRL+C to quit) +``` + +这里会提示启动的HTTP服务是开发模式,并不能用于生产环境的部署。Flask启动的服务环境不够稳定也无法承受大量请求的并发,实际部署过程中配合需要WSGI(Web Server Gateway Interface)使用。 + +下面我们展示一下如何使用[uWSGI](https://github.com/unbit/uwsgi)模块来部署HTTP预测服务用于生产环境。 + +编写HTTP服务脚本 + +```python +#uwsgi_service.py +from paddle_serving_server.web_service import WebService + +#配置预测服务 +uci_service = WebService(name = "uci") +uci_service.load_model_config("./uci_housing_model") +uci_service.prepare_server(workdir="./workdir", port=int(9500), device="cpu") +uci_service.run_server() +#获取flask服务 +app_instance = uci_service.get_app_instance() +``` + +使用uwsgi启动HTTP服务 + +```bash +uwsgi --http :9393 --module uwsgi_service:app_instance +``` + +使用--processes参数可以指定服务的进程数。 + +更多uWSGI的信息请参考[uWSGI使用文档](https://uwsgi-docs.readthedocs.io/en/latest/) diff --git a/python/examples/senta/senta_web_service.py b/python/examples/senta/senta_web_service.py index 0c0205e73cdd26231a94b2f0c9c41da84aaca961..5d20020c46d3b5ed23914cb9813ac889e232a2b3 100644 --- a/python/examples/senta/senta_web_service.py +++ b/python/examples/senta/senta_web_service.py @@ -51,13 +51,11 @@ class SentaService(WebService): def init_lac_service(self): ps = Process(target=self.start_lac_service()) ps.start() - #self.init_lac_client() + self.init_lac_client() def lac_predict(self, feed_data): - self.init_lac_client() lac_result = self.lac_client.predict( feed={"words": feed_data}, fetch=["crf_decode"]) - self.lac_client.release() return lac_result def init_lac_client(self): diff --git a/python/paddle_serving_app/local_predict.py b/python/paddle_serving_app/local_predict.py index 6620994165306a550204498e5185bb3aacca8ffd..93039c6fdd467357b589bbb2889f3c2d3208b538 100644 --- a/python/paddle_serving_app/local_predict.py +++ b/python/paddle_serving_app/local_predict.py @@ -115,6 +115,13 @@ class Debugger(object): inputs = [] for name in self.feed_names_: + if isinstance(feed[name], list): + feed[name] = np.array(feed[name]).reshape(self.feed_shapes_[ + name]) + if self.feed_types_[name] == 0: + feed[name] = feed[name].astype("int64") + else: + feed[name] = feed[name].astype("float32") inputs.append(PaddleTensor(feed[name][np.newaxis, :])) outputs = self.predictor.run(inputs) diff --git a/python/paddle_serving_server/web_service.py b/python/paddle_serving_server/web_service.py index 7e69b241f50255aa69d34c1405b72eacb675be04..f8c43707660e08e1bc44fdd62e40e20523f6cb6d 100755 --- a/python/paddle_serving_server/web_service.py +++ b/python/paddle_serving_server/web_service.py @@ -101,7 +101,6 @@ class WebService(object): p_rpc = Process(target=self._launch_rpc_service) p_rpc.start() - def run_flask(self): app_instance = Flask(__name__) @app_instance.before_first_request @@ -114,10 +113,16 @@ class WebService(object): def run(): return self.get_prediction(request) - app_instance.run(host="0.0.0.0", - port=self.port, - threaded=False, - processes=4) + self.app_instance = app_instance + + def run_flask(self): + self.app_instance.run(host="0.0.0.0", + port=self.port, + threaded=False, + processes=1) + + def get_app_instance(self): + return self.app_instance def preprocess(self, feed=[], fetch=[]): return feed, fetch diff --git a/python/paddle_serving_server_gpu/web_service.py b/python/paddle_serving_server_gpu/web_service.py index 2ec996b1db89bdff3c4550caa566bec5af2d9506..e64e73197d02a80e43bbc77a7589ab43efe2f244 100644 --- a/python/paddle_serving_server_gpu/web_service.py +++ b/python/paddle_serving_server_gpu/web_service.py @@ -151,7 +151,6 @@ class WebService(object): for p in server_pros: p.start() - def run_flask(self): app_instance = Flask(__name__) @app_instance.before_first_request @@ -164,10 +163,16 @@ class WebService(object): def run(): return self.get_prediction(request) - app_instance.run(host="0.0.0.0", - port=self.port, - threaded=False, - processes=4) + self.app_instance = app_instance + + def run_flask(self): + self.app_instance.run(host="0.0.0.0", + port=self.port, + threaded=False, + processes=1) + + def get_app_instance(self): + return app_instance def preprocess(self, feed=[], fetch=[]): return feed, fetch