From 11ef05ca32f55cc9e9f07f30ddec5c8a32eec4ef Mon Sep 17 00:00:00 2001
From: Tingquan Gao <gaotingquan@baidu.com>
Date: Mon, 28 Dec 2020 13:28:06 +0800
Subject: [PATCH] Update the hubserving (#517)

* Fix the timing of hubserving
---
 deploy/hubserving/clas/module.py | 17 +++++------------
 deploy/hubserving/clas/test.py   | 22 ++++++++++++++++++++++
 deploy/hubserving/readme.md      | 15 ++++++++++++---
 deploy/hubserving/readme_en.md   | 27 +++++++++++++++++++--------
 tools/test_hubserving.py         |  7 ++-----
 5 files changed, 60 insertions(+), 28 deletions(-)
 create mode 100644 deploy/hubserving/clas/test.py

diff --git a/deploy/hubserving/clas/module.py b/deploy/hubserving/clas/module.py
index a9db80856..f5651ace3 100644
--- a/deploy/hubserving/clas/module.py
+++ b/deploy/hubserving/clas/module.py
@@ -18,7 +18,7 @@ sys.path.insert(0, ".")
 
 import time
 
-from paddlehub.common.logger import logger
+from paddlehub.utils.log import logger
 from paddlehub.module.module import moduleinfo, serving
 import cv2
 import numpy as np
@@ -103,16 +103,16 @@ class ClasSystem(hub.Module):
                 logger.info("error in loading image")
                 all_results.append([])
                 continue
-            starttime = time.time()
 
             self.args.image_file = img
             self.args.top_k = top_k
+
+            starttime = time.time()
             classes, scores = paddle_predict.predict(self.args, self.predictor)
-
             elapse = time.time() - starttime
-            logger.info("Predict time: {}".format(elapse))
-            all_results.append([classes.tolist(), scores.tolist()])
 
+            logger.info("Predict time: {}".format(elapse))
+            all_results.append([classes.tolist(), scores.tolist(), elapse])
         return all_results
 
     @serving
@@ -124,10 +124,3 @@ class ClasSystem(hub.Module):
         images_decode = [to_cv2(image) for image in images]
         results = self.predict(images_decode, **kwargs)
         return results
-
-
-if __name__ == '__main__':
-    clas = ClasSystem()
-    image_path = ['./deploy/hubserving/ILSVRC2012_val_00006666.JPEG', ]
-    res = clas.predict(paths=image_path, top_k=5)
-    print(res)
diff --git a/deploy/hubserving/clas/test.py b/deploy/hubserving/clas/test.py
new file mode 100644
index 000000000..4555f29ee
--- /dev/null
+++ b/deploy/hubserving/clas/test.py
@@ -0,0 +1,22 @@
+# 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.
+
+import paddlehub as hub
+
+image_path = ["./deploy/hubserving/ILSVRC2012_val_00006666.JPEG", ]
+top_k = 5
+module = hub.Module(name="clas_system")
+res = module.predict(paths=image_path, top_k=top_k)
+for i, image in enumerate(image_path):
+    print("The returned result of {}: {}".format(image, res[i]))
diff --git a/deploy/hubserving/readme.md b/deploy/hubserving/readme.md
index ad41bf3cb..28dde4312 100644
--- a/deploy/hubserving/readme.md
+++ b/deploy/hubserving/readme.md
@@ -120,8 +120,15 @@ hub serving start -c deploy/hubserving/clas/config.json
 访问示例:  
 ```python tools/test_hubserving.py http://127.0.0.1:8866/predict/clas_system ./deploy/hubserving/ILSVRC2012_val_00006666.JPEG 5```
 
-## 返回结果格式说明
-返回结果为列表(list),包含 `clas`,以及所有得分组成的 `scores` (list类型), `scores` 包含前 `top_k` 个 `score` 。
+### 返回结果格式说明
+返回结果为列表(list),包含top-k个分类结果,以及对应的得分,还有此图片预测耗时,具体如下:
+```
+list: 返回结果
+└─ list: 第一张图片结果
+   └─ list: 前k个分类结果,依score递减排序
+   └─ list: 前k个分类结果对应的score,依score递减排序
+   └─ float: 该图分类耗时,单位秒
+```
 
 **说明:** 如果需要增加、删除、修改返回字段,可在相应模块的`module.py`文件中进行修改,完整流程参考下一节自定义修改服务模块。
 
@@ -132,7 +139,9 @@ hub serving start -c deploy/hubserving/clas/config.json
 ```hub serving stop --port/-p XXXX```  
 
 - 2、 到相应的`module.py`和`params.py`等文件中根据实际需求修改代码。  
-例如,例如需要替换部署服务所用模型,则需要到`params.py`中修改模型路径参数`cfg.model_file`和`cfg.params_file`。 **强烈建议修改后先直接运行`module.py`调试,能正确运行预测后再启动服务测试。**
+  例如,例如需要替换部署服务所用模型,则需要到`params.py`中修改模型路径参数`cfg.model_file`和`cfg.params_file`。
+
+  修改并安装(`hub install deploy/hubserving/clas/`)完成后,在进行部署前,可通过`python deploy/hubserving/clas/test.py`测试已安装服务模块。
 
 - 3、 卸载旧服务包  
 ```hub uninstall clas_system```  
diff --git a/deploy/hubserving/readme_en.md b/deploy/hubserving/readme_en.md
index b7af9262c..cc22d2449 100644
--- a/deploy/hubserving/readme_en.md
+++ b/deploy/hubserving/readme_en.md
@@ -124,29 +124,40 @@ Two parameters need to be passed to the script:
 python tools/test_hubserving.py http://127.0.0.1:8866/predict/clas_system ./deploy/hubserving/ILSVRC2012_val_00006666.JPEG 5
 ```
 
-## Returned result format
-The returned result is a list, including classification results(`clas`), and the `top_k`'s scores(`socres`). And `scores` is a list, consist of `score`.
+### Returned result format
+The returned result is a list, including the `top_k`'s classification results, corresponding scores and the time cost of prediction, details as follows.
+
+```
+list: The returned results
+└─ list: The result of first picture
+   └─ list: The top-k classification results, sorted in descending order of score
+   └─ list: The scores corresponding to the top-k classification results, sorted in descending order of score
+   └─ float: The time cost of predicting the picture, unit second
+```
 
 **Note:** If you need to add, delete or modify the returned fields, you can modify the file `module.py` of the corresponding module. For the complete process, refer to the user-defined modification service module in the next section.
 
 ## User defined service module modification
 If you need to modify the service logic, the following steps are generally required:
 
-- 1. Stop service
+1. Stop service
 ```shell
 hub serving stop --port/-p XXXX
 ```
-- 2. Modify the code in the corresponding files, like `module.py` and `params.py`, according to the actual needs.  
-For example, if you need to replace the model used by the deployed service, you need to modify model path parameters `cfg.model_file` and `cfg.params_file` in `params.py`. Of course, other related parameters may need to be modified at the same time. Please modify and debug according to the actual situation. It is suggested to run `module.py` directly for debugging after modification before starting the service test.  
-- 3. Uninstall old service module
+2. Modify the code in the corresponding files, like `module.py` and `params.py`, according to the actual needs.  
+For example, if you need to replace the model used by the deployed service, you need to modify model path parameters `cfg.model_file` and `cfg.params_file` in `params.py`. Of course, other related parameters may need to be modified at the same time. Please modify and debug according to the actual situation.
+
+    After modifying and installing (`hub install deploy/hubserving/clas/`) and before deploying, you can use `python deploy/hubserving/clas/test.py` to test the installed service module.
+
+1. Uninstall old service module
 ```shell
 hub uninstall clas_system
 ```
-- 4. Install modified service module
+4. Install modified service module
 ```shell
 hub install deploy/hubserving/clas/
 ```
-- 5. Restart service
+5. Restart service
 ```shell
 hub serving start -m clas_system
 ```
diff --git a/tools/test_hubserving.py b/tools/test_hubserving.py
index 561a7fd5d..6a130eec9 100644
--- a/tools/test_hubserving.py
+++ b/tools/test_hubserving.py
@@ -64,24 +64,21 @@ def main(url, image_path, top_k=1):
             continue
         data = {'images': [cv2_to_base64(img)], 'top_k': top_k}
 
-        starttime = time.time()
         try:
             r = requests.post(url=url, headers=headers, data=json.dumps(data))
             r.raise_for_status()
         except Exception as e:
             logger.error("File:{}, {}".format(file_str, e))
             continue
-        elapse = time.time() - starttime
-        total_time += elapse
         if r.json()['status'] != '000':
             logger.error(
                 "File:{}, The parameters returned by the server are: {}".
                 format(file_str, r.json()['msg']))
             continue
         res = r.json()["results"][0]
-        classes = res[0]
-        scores = res[1]
+        classes, scores, elapse = res
         all_acc += scores[0]
+        total_time += elapse
         cnt += 1
 
         scores = map(lambda x: round(x, 5), scores)