diff --git a/deploy/hubserving/.ipynb_checkpoints/serving-checkpoint.md b/deploy/hubserving/.ipynb_checkpoints/serving-checkpoint.md new file mode 100644 index 0000000000000000000000000000000000000000..da043921388ad59a5b6b9e60ebd6f1200454ff25 --- /dev/null +++ b/deploy/hubserving/.ipynb_checkpoints/serving-checkpoint.md @@ -0,0 +1,109 @@ +# 服务部署 + +PaddleOCR提供2种服务部署方式: +- 基于HubServing的部署:已集成到PaddleOCR中([code](https://github.com/PaddlePaddle/PaddleOCR/tree/develop/deploy/ocr_hubserving)),按照本教程使用; +- 基于PaddleServing的部署:详见PaddleServing官网[demo](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/ocr),后续也将集成到PaddleOCR。 + +服务部署目录下包括检测、识别、2阶段串联三种服务包,根据需求选择相应的服务包进行安装和启动。目录如下: +``` +deploy/hubserving/ + └─ ocr_det 检测模块服务包 + └─ ocr_rec 识别模块服务包 + └─ ocr_system 检测+识别串联服务包 +``` + +每个服务包下包含3个文件。以2阶段串联服务包为例,目录如下: +``` +deploy/hubserving/ocr_system/ + └─ __init__.py 空文件 + └─ config.json 配置文件,启动服务时作为参数传入 + └─ module.py 主模块,包含服务的完整逻辑 +``` + +## 启动服务 +以下步骤以检测+识别2阶段串联服务为例,如果只需要检测服务或识别服务,替换相应文件路径即可。 +### 1. 安装paddlehub +```pip3 install paddlehub --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple``` + +### 2. 安装服务模块 +PaddleOCR提供3种服务模块,根据需要安装所需模块。如: + +安装检测服务模块: +```hub install deploy/hubserving/ocr_det/``` + +或,安装识别服务模块: +```hub install deploy/hubserving/ocr_rec/``` + +或,安装检测+识别串联服务模块: +```hub install deploy/hubserving/ocr_system/``` + +### 3. 修改配置文件 +在config.json中指定模型路径、是否使用GPU、是否对结果做可视化等参数,如,串联服务ocr_system的配置: +```python +{ + "modules_info": { + "ocr_system": { + "init_args": { + "version": "1.0.0", + "det_model_dir": "./inference/det/", + "rec_model_dir": "./inference/rec/", + "use_gpu": true + }, + "predict_args": { + "visualization": false + } + } + } +} +``` +其中,模型路径对应的模型为```inference模型```。 + +### 4. 运行启动命令 +```hub serving start -m ocr_system --config hubserving/ocr_det/config.json``` + +这样就完成了一个服务化API的部署,默认端口号为8866。 + +**NOTE:** 如使用GPU预测(即,config中use_gpu置为true),则需要在启动服务之前,设置CUDA_VISIBLE_DEVICES环境变量,如:```export CUDA_VISIBLE_DEVICES=0```,否则不用设置。 + +## 发送预测请求 +配置好服务端,以下数行代码即可实现发送预测请求,获取预测结果: + +```python +import requests +import json +import cv2 +import base64 + +def cv2_to_base64(image): + return base64.b64encode(image).decode('utf8') + +# 发送HTTP请求 +data = {'images':[cv2_to_base64(open("./doc/imgs/11.jpg", 'rb').read())]} +headers = {"Content-type": "application/json"} +# url = "http://127.0.0.1:8866/predict/ocr_det" +# url = "http://127.0.0.1:8866/predict/ocr_rec" +url = "http://127.0.0.1:8866/predict/ocr_system" +r = requests.post(url=url, headers=headers, data=json.dumps(data)) + +# 打印预测结果 +print(r.json()["results"]) +``` + +你可能需要根据实际情况修改```url```字符串中的端口号和服务模块名称。 + +上面所示代码都已写入测试脚本,可直接运行命令:```python tools/test_hubserving.py``` + +## 自定义修改服务模块 +如果需要修改服务逻辑,你一般需要操作以下步骤: + +1、 停止服务 +```hub serving stop -m ocr_system``` + +2、 到相应的module.py文件中根据实际需求修改代码 + +3、 卸载旧服务包 +```hub uninstall ocr_system``` + +4、 安装修改后的新服务包 +```hub install deploy/hubserving/ocr_system/``` + diff --git a/deploy/hubserving/ocr_det/.ipynb_checkpoints/params-checkpoint.py b/deploy/hubserving/ocr_det/.ipynb_checkpoints/params-checkpoint.py new file mode 100644 index 0000000000000000000000000000000000000000..0d32c1f51b23d72379361fb504b33558c52d783c --- /dev/null +++ b/deploy/hubserving/ocr_det/.ipynb_checkpoints/params-checkpoint.py @@ -0,0 +1,41 @@ +# -*- coding:utf-8 -*- +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +class Config(object): + pass + + +def read_params(): + cfg = Config() + + #params for text detector + cfg.det_algorithm = "DB" + # cfg.det_model_dir = "./inference/ch_det_mv3_db/" + cfg.det_model_dir = "./inference/det/" + cfg.det_max_side_len = 960 + + #DB parmas + cfg.det_db_thresh =0.3 + cfg.det_db_box_thresh =0.5 + cfg.det_db_unclip_ratio =2.0 + + # #EAST parmas + # cfg.det_east_score_thresh = 0.8 + # cfg.det_east_cover_thresh = 0.1 + # cfg.det_east_nms_thresh = 0.2 + + # #params for text recognizer + # cfg.rec_algorithm = "CRNN" + # # cfg.rec_model_dir = "./inference/ch_det_mv3_crnn/" + # cfg.rec_model_dir = "./inference/rec/" + + # cfg.rec_image_shape = "3, 32, 320" + # cfg.rec_char_type = 'ch' + # cfg.rec_batch_num = 30 + # cfg.rec_char_dict_path = "./ppocr/utils/ppocr_keys_v1.txt" + # cfg.use_space_char = True + + return cfg \ No newline at end of file diff --git a/deploy/ocr_hubserving/ocr_det/__init__.py b/deploy/hubserving/ocr_det/__init__.py similarity index 100% rename from deploy/ocr_hubserving/ocr_det/__init__.py rename to deploy/hubserving/ocr_det/__init__.py diff --git a/deploy/ocr_hubserving/ocr_det/config.json b/deploy/hubserving/ocr_det/config.json similarity index 76% rename from deploy/ocr_hubserving/ocr_det/config.json rename to deploy/hubserving/ocr_det/config.json index f995d0ed2bd4da3aaf39e654a5c7ab51e377e367..9f6fd50f1d4c75da176d77b882a4c4262c9da434 100644 --- a/deploy/ocr_hubserving/ocr_det/config.json +++ b/deploy/hubserving/ocr_det/config.json @@ -3,12 +3,14 @@ "ocr_det": { "init_args": { "version": "1.0.0", - "det_model_dir": "./inference/ch_det_mv3_db/", "use_gpu": true }, "predict_args": { "visualization": false } } - } + }, + "port": 8866, + "use_multiprocess": false, + "workers": 2 } diff --git a/deploy/ocr_hubserving/ocr_det/module.py b/deploy/hubserving/ocr_det/module.py similarity index 75% rename from deploy/ocr_hubserving/ocr_det/module.py rename to deploy/hubserving/ocr_det/module.py index 0ee32d38e5b6b4502592b62a3f129a0e11a8cd7a..6b7bafb83ebb9cca112659f95b6556797972efc1 100644 --- a/deploy/ocr_hubserving/ocr_det/module.py +++ b/deploy/hubserving/ocr_det/module.py @@ -22,8 +22,6 @@ import paddlehub as hub from tools.infer.utility import draw_boxes, base64_to_cv2 from tools.infer.predict_det import TextDetector -class Config(object): - pass @moduleinfo( name="ocr_det", @@ -33,43 +31,28 @@ class Config(object): author_email="paddle-dev@baidu.com", type="cv/text_recognition") class OCRDet(hub.Module): - def _initialize(self, - det_model_dir="", - det_algorithm="DB", - use_gpu=False - ): + def _initialize(self, use_gpu=False): """ initialize with the necessary elements """ - self.config = Config() - self.config.use_gpu = use_gpu + from ocr_det.params import read_params + cfg = read_params() + + cfg.use_gpu = use_gpu if use_gpu: try: _places = os.environ["CUDA_VISIBLE_DEVICES"] int(_places[0]) print("use gpu: ", use_gpu) print("CUDA_VISIBLE_DEVICES: ", _places) + cfg.gpu_mem = 8000 except: raise RuntimeError( "Environment Variable CUDA_VISIBLE_DEVICES is not set correctly. If you wanna use gpu, please set CUDA_VISIBLE_DEVICES via export CUDA_VISIBLE_DEVICES=cuda_device_id." ) - self.config.ir_optim = True - self.config.gpu_mem = 8000 - - #params for text detector - self.config.det_algorithm = det_algorithm - self.config.det_model_dir = det_model_dir - # self.config.det_model_dir = "./inference/det/" - - #DB parmas - self.config.det_db_thresh =0.3 - self.config.det_db_box_thresh =0.5 - self.config.det_db_unclip_ratio =2.0 + cfg.ir_optim = True - #EAST parmas - self.config.det_east_score_thresh = 0.8 - self.config.det_east_cover_thresh = 0.1 - self.config.det_east_nms_thresh = 0.2 + self.text_detector = TextDetector(cfg) def read_images(self, paths=[]): images = [] @@ -83,10 +66,9 @@ class OCRDet(hub.Module): images.append(img) return images - def det_text(self, + def predict(self, images=[], paths=[], - det_max_side_len=960, draw_img_save='ocr_det_result', visualization=False): """ @@ -94,10 +76,8 @@ class OCRDet(hub.Module): Args: images (list(numpy.ndarray)): images data, shape of each is [H, W, C]. If images not paths paths (list[str]): The paths of images. If paths not images - use_gpu (bool): Whether to use gpu. Default false. - output_dir (str): The directory to store output images. + draw_img_save (str): The directory to store output images. visualization (bool): Whether to save image or not. - box_thresh(float): the threshold of the detected text box's confidence Returns: res (list): The result of text detection box and save path of images. """ @@ -111,8 +91,6 @@ class OCRDet(hub.Module): assert predicted_data != [], "There is not any image to be predicted. Please check the input data." - self.config.det_max_side_len = det_max_side_len - text_detector = TextDetector(self.config) all_results = [] for img in predicted_data: result = {'save_path': ''} @@ -121,7 +99,7 @@ class OCRDet(hub.Module): result['data'] = [] all_results.append(result) continue - dt_boxes, elapse = text_detector(img) + dt_boxes, elapse = self.text_detector(img) print("Predict time : ", elapse) result['data'] = dt_boxes.astype(np.int).tolist() @@ -146,7 +124,7 @@ class OCRDet(hub.Module): Run as a service. """ images_decode = [base64_to_cv2(image) for image in images] - results = self.det_text(images_decode, **kwargs) + results = self.predict(images_decode, **kwargs) return results @@ -156,5 +134,5 @@ if __name__ == '__main__': './doc/imgs/11.jpg', './doc/imgs/12.jpg', ] - res = ocr.det_text(paths=image_path, visualization=True) + res = ocr.predict(paths=image_path, visualization=True) print(res) \ No newline at end of file diff --git a/deploy/hubserving/ocr_det/params.py b/deploy/hubserving/ocr_det/params.py new file mode 100644 index 0000000000000000000000000000000000000000..0b950114f82d88f20d2ce521628ea9dda7740ab4 --- /dev/null +++ b/deploy/hubserving/ocr_det/params.py @@ -0,0 +1,39 @@ +# -*- coding:utf-8 -*- +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +class Config(object): + pass + + +def read_params(): + cfg = Config() + + #params for text detector + cfg.det_algorithm = "DB" + cfg.det_model_dir = "./inference/ch_det_mv3_db/" + cfg.det_max_side_len = 960 + + #DB parmas + cfg.det_db_thresh =0.3 + cfg.det_db_box_thresh =0.5 + cfg.det_db_unclip_ratio =2.0 + + # #EAST parmas + # cfg.det_east_score_thresh = 0.8 + # cfg.det_east_cover_thresh = 0.1 + # cfg.det_east_nms_thresh = 0.2 + + # #params for text recognizer + # cfg.rec_algorithm = "CRNN" + # cfg.rec_model_dir = "./inference/ch_det_mv3_crnn/" + + # cfg.rec_image_shape = "3, 32, 320" + # cfg.rec_char_type = 'ch' + # cfg.rec_batch_num = 30 + # cfg.rec_char_dict_path = "./ppocr/utils/ppocr_keys_v1.txt" + # cfg.use_space_char = True + + return cfg \ No newline at end of file diff --git a/deploy/ocr_hubserving/ocr_rec/__init__.py b/deploy/hubserving/ocr_rec/__init__.py similarity index 100% rename from deploy/ocr_hubserving/ocr_rec/__init__.py rename to deploy/hubserving/ocr_rec/__init__.py diff --git a/deploy/ocr_hubserving/ocr_rec/config.json b/deploy/hubserving/ocr_rec/config.json similarity index 74% rename from deploy/ocr_hubserving/ocr_rec/config.json rename to deploy/hubserving/ocr_rec/config.json index 2cfbc0b558d49d54c341506f0e8789578e1b42cd..59d54e6c7545f300f134c9c2efaf546308b9c360 100644 --- a/deploy/ocr_hubserving/ocr_rec/config.json +++ b/deploy/hubserving/ocr_rec/config.json @@ -3,11 +3,13 @@ "ocr_rec": { "init_args": { "version": "1.0.0", - "det_model_dir": "./inference/ch_rec_mv3_crnn/", "use_gpu": true }, "predict_args": { } } - } + }, + "port": 8867, + "use_multiprocess": false, + "workers": 2 } diff --git a/deploy/ocr_hubserving/ocr_rec/module.py b/deploy/hubserving/ocr_rec/module.py similarity index 74% rename from deploy/ocr_hubserving/ocr_rec/module.py rename to deploy/hubserving/ocr_rec/module.py index b50016a37fc44291b5aa01bdf2b55bdab11c8fe5..77a907d6d29912dc0293c2f313215b40b7469ff3 100644 --- a/deploy/ocr_hubserving/ocr_rec/module.py +++ b/deploy/hubserving/ocr_rec/module.py @@ -22,8 +22,6 @@ import paddlehub as hub from tools.infer.utility import base64_to_cv2 from tools.infer.predict_rec import TextRecognizer -class Config(object): - pass @moduleinfo( name="ocr_rec", @@ -33,41 +31,28 @@ class Config(object): author_email="paddle-dev@baidu.com", type="cv/text_recognition") class OCRRec(hub.Module): - def _initialize(self, - rec_model_dir="", - rec_algorithm="CRNN", - rec_char_dict_path="./ppocr/utils/ppocr_keys_v1.txt", - rec_batch_num=30, - use_gpu=False - ): + def _initialize(self, use_gpu=False): """ initialize with the necessary elements """ - self.config = Config() - self.config.use_gpu = use_gpu + from ocr_rec.params import read_params + cfg = read_params() + + cfg.use_gpu = use_gpu if use_gpu: try: _places = os.environ["CUDA_VISIBLE_DEVICES"] int(_places[0]) print("use gpu: ", use_gpu) print("CUDA_VISIBLE_DEVICES: ", _places) + cfg.gpu_mem = 8000 except: raise RuntimeError( "Environment Variable CUDA_VISIBLE_DEVICES is not set correctly. If you wanna use gpu, please set CUDA_VISIBLE_DEVICES via export CUDA_VISIBLE_DEVICES=cuda_device_id." ) - self.config.ir_optim = True - self.config.gpu_mem = 8000 + cfg.ir_optim = True - #params for text recognizer - self.config.rec_algorithm = rec_algorithm - self.config.rec_model_dir = rec_model_dir - # self.config.rec_model_dir = "./inference/rec/" - - self.config.rec_image_shape = "3, 32, 320" - self.config.rec_char_type = 'ch' - self.config.rec_batch_num = rec_batch_num - self.config.rec_char_dict_path = rec_char_dict_path - self.config.use_space_char = True + self.text_recognizer = TextRecognizer(cfg) def read_images(self, paths=[]): images = [] @@ -81,7 +66,7 @@ class OCRRec(hub.Module): images.append(img) return images - def rec_text(self, + def predict(self, images=[], paths=[]): """ @@ -102,14 +87,13 @@ class OCRRec(hub.Module): assert predicted_data != [], "There is not any image to be predicted. Please check the input data." - text_recognizer = TextRecognizer(self.config) img_list = [] for img in predicted_data: if img is None: continue img_list.append(img) try: - rec_res, predict_time = text_recognizer(img_list) + rec_res, predict_time = self.text_recognizer(img_list) except Exception as e: print(e) return [] @@ -121,7 +105,7 @@ class OCRRec(hub.Module): Run as a service. """ images_decode = [base64_to_cv2(image) for image in images] - results = self.det_text(images_decode, **kwargs) + results = self.predict(images_decode, **kwargs) return results @@ -132,5 +116,5 @@ if __name__ == '__main__': './doc/imgs_words/ch/word_2.jpg', './doc/imgs_words/ch/word_3.jpg', ] - res = ocr.rec_text(paths=image_path) + res = ocr.predict(paths=image_path) print(res) \ No newline at end of file diff --git a/deploy/hubserving/ocr_rec/params.py b/deploy/hubserving/ocr_rec/params.py new file mode 100644 index 0000000000000000000000000000000000000000..fe93fc0870a1bb1d050285ca858de4cddb6b3a61 --- /dev/null +++ b/deploy/hubserving/ocr_rec/params.py @@ -0,0 +1,39 @@ +# -*- coding:utf-8 -*- +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +class Config(object): + pass + + +def read_params(): + cfg = Config() + + # #params for text detector + # cfg.det_algorithm = "DB" + # cfg.det_model_dir = "./inference/ch_det_mv3_db/" + # cfg.det_max_side_len = 960 + + # #DB parmas + # cfg.det_db_thresh =0.3 + # cfg.det_db_box_thresh =0.5 + # cfg.det_db_unclip_ratio =2.0 + + # #EAST parmas + # cfg.det_east_score_thresh = 0.8 + # cfg.det_east_cover_thresh = 0.1 + # cfg.det_east_nms_thresh = 0.2 + + #params for text recognizer + cfg.rec_algorithm = "CRNN" + cfg.rec_model_dir = "./inference/ch_rec_mv3_crnn/" + + cfg.rec_image_shape = "3, 32, 320" + cfg.rec_char_type = 'ch' + cfg.rec_batch_num = 30 + cfg.rec_char_dict_path = "./ppocr/utils/ppocr_keys_v1.txt" + cfg.use_space_char = True + + return cfg \ No newline at end of file diff --git a/deploy/ocr_hubserving/ocr_system/__init__.py b/deploy/hubserving/ocr_system/__init__.py similarity index 100% rename from deploy/ocr_hubserving/ocr_system/__init__.py rename to deploy/hubserving/ocr_system/__init__.py diff --git a/deploy/ocr_hubserving/ocr_system/config.json b/deploy/hubserving/ocr_system/config.json similarity index 65% rename from deploy/ocr_hubserving/ocr_system/config.json rename to deploy/hubserving/ocr_system/config.json index 364c7426a44a6b67576508c89cd993368624726f..21c701c60ec93828497892160bcf52f4dc558f04 100644 --- a/deploy/ocr_hubserving/ocr_system/config.json +++ b/deploy/hubserving/ocr_system/config.json @@ -3,14 +3,15 @@ "ocr_system": { "init_args": { "version": "1.0.0", - "det_model_dir": "./inference/ch_det_mv3_db/", - "rec_model_dir": "./inference/ch_rec_mv3_crnn/", "use_gpu": true }, "predict_args": { "visualization": false } } - } + }, + "port": 8868, + "use_multiprocess": false, + "workers": 2 } diff --git a/deploy/ocr_hubserving/ocr_system/module.py b/deploy/hubserving/ocr_system/module.py similarity index 72% rename from deploy/ocr_hubserving/ocr_system/module.py rename to deploy/hubserving/ocr_system/module.py index dc5ab211b937c114cb87e9bcc058af583f606d6b..a70697f46fa64bf2922a3308986e4417a9b9037c 100644 --- a/deploy/ocr_hubserving/ocr_system/module.py +++ b/deploy/hubserving/ocr_system/module.py @@ -23,9 +23,6 @@ from tools.infer.utility import draw_ocr, base64_to_cv2 from tools.infer.predict_system import TextSystem -class Config(object): - pass - @moduleinfo( name="ocr_system", version="1.0.0", @@ -34,58 +31,28 @@ class Config(object): author_email="paddle-dev@baidu.com", type="cv/text_recognition") class OCRSystem(hub.Module): - def _initialize(self, - det_model_dir="", - det_algorithm="DB", - rec_model_dir="", - rec_algorithm="CRNN", - rec_char_dict_path="./ppocr/utils/ppocr_keys_v1.txt", - rec_batch_num=30, - use_gpu=False - ): + def _initialize(self, use_gpu=False): """ initialize with the necessary elements """ - self.config = Config() - self.config.use_gpu = use_gpu + from ocr_system.params import read_params + cfg = read_params() + + cfg.use_gpu = use_gpu if use_gpu: try: _places = os.environ["CUDA_VISIBLE_DEVICES"] int(_places[0]) print("use gpu: ", use_gpu) print("CUDA_VISIBLE_DEVICES: ", _places) + cfg.gpu_mem = 8000 except: raise RuntimeError( "Environment Variable CUDA_VISIBLE_DEVICES is not set correctly. If you wanna use gpu, please set CUDA_VISIBLE_DEVICES via export CUDA_VISIBLE_DEVICES=cuda_device_id." ) - self.config.ir_optim = True - self.config.gpu_mem = 8000 - - #params for text detector - self.config.det_algorithm = det_algorithm - self.config.det_model_dir = det_model_dir - # self.config.det_model_dir = "./inference/det/" - - #DB parmas - self.config.det_db_thresh =0.3 - self.config.det_db_box_thresh =0.5 - self.config.det_db_unclip_ratio =2.0 - - #EAST parmas - self.config.det_east_score_thresh = 0.8 - self.config.det_east_cover_thresh = 0.1 - self.config.det_east_nms_thresh = 0.2 - - #params for text recognizer - self.config.rec_algorithm = rec_algorithm - self.config.rec_model_dir = rec_model_dir - # self.config.rec_model_dir = "./inference/rec/" - - self.config.rec_image_shape = "3, 32, 320" - self.config.rec_char_type = 'ch' - self.config.rec_batch_num = rec_batch_num - self.config.rec_char_dict_path = rec_char_dict_path - self.config.use_space_char = True + cfg.ir_optim = True + + self.text_sys = TextSystem(cfg) def read_images(self, paths=[]): images = [] @@ -99,10 +66,9 @@ class OCRSystem(hub.Module): images.append(img) return images - def recognize_text(self, + def predict(self, images=[], paths=[], - det_max_side_len=960, draw_img_save='ocr_result', visualization=False, text_thresh=0.5): @@ -111,11 +77,8 @@ class OCRSystem(hub.Module): Args: images (list(numpy.ndarray)): images data, shape of each is [H, W, C]. If images not paths paths (list[str]): The paths of images. If paths not images - use_gpu (bool): Whether to use gpu. - batch_size(int): the program deals once with one - output_dir (str): The directory to store output images. + draw_img_save (str): The directory to store output images. visualization (bool): Whether to save image or not. - box_thresh(float): the threshold of the detected text box's confidence text_thresh(float): the threshold of the recognize chinese texts' confidence Returns: res (list): The result of chinese texts and save path of images. @@ -130,8 +93,6 @@ class OCRSystem(hub.Module): assert predicted_data != [], "There is not any image to be predicted. Please check the input data." - self.config.det_max_side_len = det_max_side_len - text_sys = TextSystem(self.config) cnt = 0 all_results = [] for img in predicted_data: @@ -142,7 +103,7 @@ class OCRSystem(hub.Module): all_results.append(result) continue starttime = time.time() - dt_boxes, rec_res = text_sys(img) + dt_boxes, rec_res = self.text_sys(img) elapse = time.time() - starttime cnt += 1 print("Predict time of image %d: %.3fs" % (cnt, elapse)) @@ -187,7 +148,7 @@ class OCRSystem(hub.Module): Run as a service. """ images_decode = [base64_to_cv2(image) for image in images] - results = self.recognize_text(images_decode, **kwargs) + results = self.predict(images_decode, **kwargs) return results @@ -197,5 +158,5 @@ if __name__ == '__main__': './doc/imgs/11.jpg', './doc/imgs/12.jpg', ] - res = ocr.recognize_text(paths=image_path, visualization=True) + res = ocr.predict(paths=image_path, visualization=False) print(res) \ No newline at end of file diff --git a/deploy/hubserving/ocr_system/params.py b/deploy/hubserving/ocr_system/params.py new file mode 100644 index 0000000000000000000000000000000000000000..5b3bb1ea44b6cd262283797807c2c77646202fe8 --- /dev/null +++ b/deploy/hubserving/ocr_system/params.py @@ -0,0 +1,39 @@ +# -*- coding:utf-8 -*- +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +class Config(object): + pass + + +def read_params(): + cfg = Config() + + #params for text detector + cfg.det_algorithm = "DB" + cfg.det_model_dir = "./inference/ch_det_mv3_db/" + cfg.det_max_side_len = 960 + + #DB parmas + cfg.det_db_thresh =0.3 + cfg.det_db_box_thresh =0.5 + cfg.det_db_unclip_ratio =2.0 + + #EAST parmas + cfg.det_east_score_thresh = 0.8 + cfg.det_east_cover_thresh = 0.1 + cfg.det_east_nms_thresh = 0.2 + + #params for text recognizer + cfg.rec_algorithm = "CRNN" + cfg.rec_model_dir = "./inference/ch_rec_mv3_crnn/" + + cfg.rec_image_shape = "3, 32, 320" + cfg.rec_char_type = 'ch' + cfg.rec_batch_num = 30 + cfg.rec_char_dict_path = "./ppocr/utils/ppocr_keys_v1.txt" + cfg.use_space_char = True + + return cfg \ No newline at end of file diff --git a/doc/doc_ch/serving.md b/doc/doc_ch/serving.md index da043921388ad59a5b6b9e60ebd6f1200454ff25..69860e6783041ff37a89e951af8db3fcc61c43cb 100644 --- a/doc/doc_ch/serving.md +++ b/doc/doc_ch/serving.md @@ -1,7 +1,7 @@ # 服务部署 PaddleOCR提供2种服务部署方式: -- 基于HubServing的部署:已集成到PaddleOCR中([code](https://github.com/PaddlePaddle/PaddleOCR/tree/develop/deploy/ocr_hubserving)),按照本教程使用; +- 基于HubServing的部署:已集成到PaddleOCR中([code](https://github.com/PaddlePaddle/PaddleOCR/tree/develop/deploy/hubserving)),按照本教程使用; - 基于PaddleServing的部署:详见PaddleServing官网[demo](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/ocr),后续也将集成到PaddleOCR。 服务部署目录下包括检测、识别、2阶段串联三种服务包,根据需求选择相应的服务包进行安装和启动。目录如下: @@ -15,12 +15,13 @@ deploy/hubserving/ 每个服务包下包含3个文件。以2阶段串联服务包为例,目录如下: ``` deploy/hubserving/ocr_system/ - └─ __init__.py 空文件 - └─ config.json 配置文件,启动服务时作为参数传入 - └─ module.py 主模块,包含服务的完整逻辑 + └─ __init__.py 空文件,必选 + └─ config.json 配置文件,可选,使用配置启动服务时作为参数传入 + └─ module.py 主模块,必选,包含服务的完整逻辑 + └─ params.py 参数文件,必选,包含模型路径、前后处理参数等参数 ``` -## 启动服务 +## 快速启动服务 以下步骤以检测+识别2阶段串联服务为例,如果只需要检测服务或识别服务,替换相应文件路径即可。 ### 1. 安装paddlehub ```pip3 install paddlehub --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple``` @@ -31,39 +32,71 @@ PaddleOCR提供3种服务模块,根据需要安装所需模块。如: 安装检测服务模块: ```hub install deploy/hubserving/ocr_det/``` -或,安装识别服务模块: +或,安装识别服务模块: ```hub install deploy/hubserving/ocr_rec/``` 或,安装检测+识别串联服务模块: ```hub install deploy/hubserving/ocr_system/``` -### 3. 修改配置文件 -在config.json中指定模型路径、是否使用GPU、是否对结果做可视化等参数,如,串联服务ocr_system的配置: +### 3. 启动服务 +#### 方式1. 命令行命令启动(仅支持CPU) +**启动命令:** +```shell +$ hub serving start --modules [Module1==Version1, Module2==Version2, ...] \ + --port XXXX \ + --use_multiprocess \ + --workers \ +``` + +**参数:** + +|参数|用途| +|-|-| +|--modules/-m|PaddleHub Serving预安装模型,以多个Module==Version键值对的形式列出
*`当不指定Version时,默认选择最新版本`*| +|--port/-p|服务端口,默认为8866| +|--use_multiprocess|是否启用并发方式,默认为单进程方式,推荐多核CPU机器使用此方式
*`Windows操作系统只支持单进程方式`*| +|--workers|在并发方式下指定的并发任务数,默认为`2*cpu_count-1`,其中`cpu_count`为CPU核数| + +如启动串联服务: ```hub serving start -m ocr_system``` + +这样就完成了一个服务化API的部署,使用默认端口号8866。 + +#### 方式2. 配置文件启动(支持CPU、GPU) +**启动命令:** +```hub serving start --config/-c config.json``` + +其中,`config.json`格式如下: ```python { "modules_info": { "ocr_system": { "init_args": { "version": "1.0.0", - "det_model_dir": "./inference/det/", - "rec_model_dir": "./inference/rec/", "use_gpu": true }, "predict_args": { "visualization": false } } - } + }, + "port": 8868, + "use_multiprocess": false, + "workers": 2 } ``` -其中,模型路径对应的模型为```inference模型```。 -### 4. 运行启动命令 -```hub serving start -m ocr_system --config hubserving/ocr_det/config.json``` +- `init_args`中的可配参数与`module.py`中的`_initialize`函数接口一致。其中,**当`use_gpu`为`true`时,表示使用GPU启动服务**。 +- `predict_args`中的可配参数与`module.py`中的`predict`函数接口一致。 -这样就完成了一个服务化API的部署,默认端口号为8866。 +**注意:** +- 使用配置文件启动服务时,其他参数会被忽略。 +- 如果使用GPU预测(即,`use_gpu`置为`true`),则需要在启动服务之前,设置CUDA_VISIBLE_DEVICES环境变量,如:```export CUDA_VISIBLE_DEVICES=0```,否则不用设置。 -**NOTE:** 如使用GPU预测(即,config中use_gpu置为true),则需要在启动服务之前,设置CUDA_VISIBLE_DEVICES环境变量,如:```export CUDA_VISIBLE_DEVICES=0```,否则不用设置。 +如,使用GPU 3号卡启动串联服务: +```shell +export CUDA_VISIBLE_DEVICES=3 +hub serving start -c deploy/hubserving/ocr_system/config.json +``` ## 发送预测请求 配置好服务端,以下数行代码即可实现发送预测请求,获取预测结果: @@ -89,21 +122,25 @@ r = requests.post(url=url, headers=headers, data=json.dumps(data)) print(r.json()["results"]) ``` -你可能需要根据实际情况修改```url```字符串中的端口号和服务模块名称。 +你可能需要根据实际情况修改`url`字符串中的端口号和服务模块名称。 上面所示代码都已写入测试脚本,可直接运行命令:```python tools/test_hubserving.py``` ## 自定义修改服务模块 -如果需要修改服务逻辑,你一般需要操作以下步骤: +如果需要修改服务逻辑,你一般需要操作以下步骤(以修改`ocr_system`为例): -1、 停止服务 -```hub serving stop -m ocr_system``` +- 1、 停止服务 +```hub serving stop --port/-p XXXX``` -2、 到相应的module.py文件中根据实际需求修改代码 +- 2、 到相应的`module.py`和`params.py`等文件中根据实际需求修改代码。 +例如,如果需要替换部署服务所用模型,则需要到`params.py`中修改模型路径参数`det_model_dir`和`rec_model_dir`,当然,同时可能还需要修改其他相关参数,请根据实际情况修改调试。 建议修改后先直接运行`module.py`调试,能正确运行预测后再启动服务测试。 -3、 卸载旧服务包 +- 3、 卸载旧服务包 ```hub uninstall ocr_system``` -4、 安装修改后的新服务包 +- 4、 安装修改后的新服务包 ```hub install deploy/hubserving/ocr_system/``` +- 5、重新启动服务 +```hub serving start -m ocr_system``` +