PaddleOCR 基于 PaddleHub Serving 的 OCR 服务化部署详解:从服务包安装到自定义模块扩展
【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR
本文围绕 PaddleOCR 仓库中deploy/hubserving目录的官方部署文档,系统讲解如何将文本检测、文本识别、版面分析、表格识别等 OCR 能力以 HTTP API 形式服务化:包括 9 种服务包的安装、CPU/GPU 两种启动方式、预测请求的发送与返回结果字段,以及如何结合module.py/params.py源码结构完成服务模块的自定义修改。读完本文,你可以独立完成一套可接入业务系统的 OCR 推理服务,并在需要时扩展其输入输出协议。
一、服务包总览与目录结构
PaddleOCR 将服务化部署代码组织在 deploy/hubserving/ 目录下,当前包含 9 种服务包,覆盖从单模块到多阶段串联的完整能力组合:
deploy/hubserving/ └─ ocr_cls 文本方向分类模块服务包 └─ ocr_det 文本检测模块服务包 └─ ocr_rec 文本识别模块服务包 └─ ocr_system 文本检测+文本方向分类+文本识别串联服务包 └─ structure_layout 版面分析服务包 └─ structure_table 表格识别服务包 └─ structure_system PP-Structure服务包 └─ kie_ser 关键信息抽取-SER服务包 └─ kie_ser_re 关键信息抽取-SER+RE服务包每个服务包下包含 4 个文件,以串联服务包为例,目录如下(见 deploy/hubserving/ocr_system/):
deploy/hubserving/ocr_system/ └─ __init__.py 空文件,必选 └─ config.json 配置文件,可选,使用配置文件启动服务时作为参数传入 └─ module.py 主模块,必选,包含服务的完整逻辑 └─ params.py 参数文件,必选,包含模型路径、前后处理参数等参数从源码结构看,这套目录约定与 PaddleHub 的模块注册机制严格对应。以 ocr_system/module.py 为例,模块类通过@moduleinfo装饰器声明服务名与版本,这是后续hub install、hub serving start -m能够按名称寻址服务的依据:
from paddlehub.module.module import moduleinfo, runnable, serving @moduleinfo( name="ocr_system", version="1.0.0", summary="ocr system service", author="paddle-dev", author_email="paddle-dev@baidu.com", type="cv/PP-OCR_system", ) class OCRSystem(hub.Module): ...各服务包的实际能力差异体现在两个地方:一是module.py中_initialize所实例化的预测引擎(串联服务用tools/infer/predict_system.py的TextSystem,PP-Structure 服务用ppstructure/predict_system.py的StructureSystem,KIE-SER 服务用ppstructure/kie/predict_kie_token_ser.py的SerPredictor);二是predict方法对不同引擎返回值的字段裁剪方式,这直接决定了 HTTP 接口的返回结构(第四节详述)。
二、启动前的准备工作
2.1 安装 PaddleHub
paddlehub 需要 Python > 3.6.2:
pip3 install paddlehub==2.1.0 --upgrade -i https://mirror.baidu.com/pypi/simple2.2 下载推理模型
安装服务模块前,需要准备推理模型并放到正确路径。默认使用的是 PP-OCRv3 模型,默认模型路径为:
| 模型 | 路径 | | ------- | - | | 检测模型 |./inference/PP-OCRv3_mobile_det_infer/| | 识别模型 |./inference/ch_PP-OCRv3_rec_infer/| | 方向分类器 |./inference/ch_ppocr_mobile_v2.0_cls_infer/| | 版面分析模型 |./inference/picodet_lcnet_x1_0_fgd_layout_infer/| | 表格结构识别模型 |./inference/ch_ppstructure_mobile_v2.0_SLANet_infer/| | 关键信息抽取SER模型 |./inference/ser_vi_layoutxlm_xfund_infer/| | 关键信息抽取RE模型 |./inference/re_vi_layoutxlm_xfund_infer/|
模型路径可在各服务包的params.py中查看和修改。例如串联服务包中 ocr_system/params.py 定义了:
cfg.det_algorithm = "DB" cfg.det_model_dir = "./inference/PP-OCRv3_mobile_det_infer/" cfg.rec_algorithm = "CRNN" cfg.rec_model_dir = "./inference/ch_PP-OCRv3_rec_infer/" cfg.rec_char_dict_path = "./ppocr/utils/ppocr_keys_v1.txt" cfg.use_angle_cls = True cfg.cls_model_dir = "./inference/ch_ppocr_mobile_v2.0_cls_infer/"注意这些路径是相对于服务进程工作目录的相对路径,params.py中还内置了det_model_url、rec_model_url、cls_model_url等模型下载地址。更多模型可以从 PaddleOCR 提供的模型库 PP-OCR 模型列表 和 PP-Structure 模型列表 下载,也可以替换成自己训练转换好的模型。
2.3 安装服务模块
在 Linux 环境(Windows 环境请将/替换为\)下,按需求选择服务包安装:
| 服务模块 | 命令 | | ------- | - | | 检测 |hub install deploy/hubserving/ocr_det| | 分类 |hub install deploy/hubserving/ocr_cls| | 识别 |hub install deploy/hubserving/ocr_rec| | 检测+识别串联 |hub install deploy/hubserving/ocr_system| | 表格识别 |hub install deploy/hubserving/structure_table| | PP-Structure |hub install deploy/hubserving/structure_system| | 版面分析 |hub install deploy/hubserving/structure_layout| | 关键信息抽取SER |hub install deploy/hubserving/kie_ser| | 关键信息抽取SER+RE |hub install deploy/hubserving/kie_ser_re|
三、启动服务:命令行与配置文件两种方式
3.1 命令行命令启动(仅支持CPU)
启动命令:
hub serving start --modules Module1==Version1, Module2==Version2, ... \ --port 8866 \ --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。
3.2 配置文件启动(支持CPU、GPU)
启动命令:
hub serving start -c config.jsonconfig.json格式如下(以 ocr_system/config.json 为例):
{ "modules_info": { "ocr_system": { "init_args": { "version": "1.0.0", "use_gpu": true }, "predict_args": { } } }, "port": 8868, "use_multiprocess": false, "workers": 2 }init_args中的可配参数与module.py中的_initialize函数接口一致。对照源码 ocr_system/module.py 的签名_initialize(self, use_gpu=False, enable_mkldnn=False),可知除use_gpu外还可传入enable_mkldnn以启用 MKL-DNN CPU 推理加速。predict_args中的可配参数与module.py中的predict函数接口一致。
当use_gpu为true时,表示使用 GPU 启动服务。从源码看,GPU 路径并不是简单地切换 device:_initialize会在开启 GPU 时强制校验CUDA_VISIBLE_DEVICES环境变量(见 ocr_system/module.py#L55-L65),若变量未设置会抛出RuntimeError,同时固定cfg.gpu_mem = 8000并置cfg.ir_optim = True开启 IR 优化。
注意事项:
使用配置文件启动服务时,其他命令行参数会被忽略。
如果使用 GPU 预测(即
use_gpu置为true),则需要在启动服务之前设置CUDA_VISIBLE_DEVICES环境变量,如:export CUDA_VISIBLE_DEVICES=0use_gpu不可与use_multiprocess同时为true。
如使用 GPU 3 号卡启动串联服务:
export CUDA_VISIBLE_DEVICES=3 hub serving start -c deploy/hubserving/ocr_system/config.json四、服务请求链路:请求如何进入模型
理解请求链路对排错很有帮助。test_hubserving.py 展示了标准客户端请求方式:以application/json为 Content-Type,将图像二进制内容 base64 编码后放入images字段发起 POST 请求,并从响应的results[0]取第一张图的结果:
img = open(image_file, "rb").read() data = {"images": [cv2_to_base64(img)]} r = requests.post(url=args.server_url, headers=headers, data=json.dumps(data)) res = r.json()["results"][0]服务端对应的入口是被@serving装饰器标记的serving_method(见 ocr_system/module.py#L147-L154):它先把 base64 字符串解码为 OpenCV 图像(base64_to_cv2),再调用predict。predict支持images(numpy.ndarray列表)与paths(文件路径列表)两种入参形态,二者只能提供其一,否则抛出TypeError——这就是为什么服务接口统一约定传 base64 图像数据。
以串联服务为例,单张图的预测结果在 ocr_system/module.py#L128-L144 中被组织为text/confidence/text_region三元组列表,其中text_region是检测框四点坐标的int32列表。而配置合并逻辑在merge_configs(ocr_system/module.py#L71-L85)中:先以默认参数parse_args()构造配置,再用params.py中read_params()返回的所有键值逐项覆盖,因此params.py是模型路径与前后处理参数的最终事实来源。
五、发送预测请求
配置好服务端后,使用仓库自带脚本发送预测请求:
python tools/test_hubserving.py --server_url=server_url --image_dir=image_path需要给脚本传递 2 个必选参数(见 test_hubserving.py#L148-L157 的参数定义):
server_url:服务地址,格式为http://[ip_address]:[port]/predict/[module_name]例如,如果使用配置文件启动分类、检测、识别、检测+分类+识别 3 阶段、表格识别和 PP-Structure 服务,并为每个服务修改了 port,那么发送请求的 url 将分别是:
http://127.0.0.1:8865/predict/ocr_det http://127.0.0.1:8866/predict/ocr_cls http://127.0.0.1:8867/predict/ocr_rec http://127.0.0.1:8868/predict/ocr_system http://127.0.0.1:8869/predict/structure_table http://127.0.0.1:8870/predict/structure_system http://127.0.0.1:8871/predict/structure_layout http://127.0.0.1:8872/predict/kie_ser http://127.0.0.1:8873/predict/kie_ser_reimage_dir:测试图像路径,可以是单张图片路径,也可以是图像集合目录路径
另有 2 个可选参数:
visualize:是否可视化结果,默认为False。可视化分支与 URL 中的模块名联动(见 test_hubserving.py#L122-L141):URL 含structure_table时把html导出为 xlsx;含structure_system时按区域类型分别保存表格 xlsx、图片裁剪与文本结果;否则按返回字段绘图——ocr_det只画文本框,ocr_system画框并标注文本(低分框按drop_score=0.5过滤)。output:可视化结果保存路径,默认为./hubserving_result。
访问示例:
python tools/test_hubserving.py --server_url=http://127.0.0.1:8868/predict/ocr_system --image_dir=./doc/imgs/ --visualize=false脚本每处理完一张图会打印该图耗时,全部结束后打印平均耗时,可作为简单的接口延迟观测手段。
六、返回结果格式说明
返回结果为列表(list),列表中的每一项为词典(dict),词典一共可能包含以下字段:
| 字段名称 | 数据类型 | 意义 |
|---|---|---|
| angle | str | 文本角度 |
| text | str | 文本内容 |
| confidence | float | 文本识别置信度或文本角度分类置信度 |
| text_region | list | 文本位置坐标 |
| html | str | 表格的 html 字符串 |
| regions | list | 版面分析+表格识别+OCR 的结果,每一项为一个 list,包含表示区域坐标的bbox、区域类型的type和区域结果的res三个字段 |
| layout | list | 版面分析的结果,每一项一个 dict,包含版面区域坐标的bbox、区域类型的label |
不同模块返回的字段不同。例如文本识别服务模块返回结果不含text_region字段(见 ocr_rec/module.py 中仅追加text、confidence两个键),文本方向分类服务返回angle、confidence,表格识别服务返回{"html": ...},版面分析服务返回{"layout": ...}(见 structure_layout/module.py#L128-L131),PP-Structure 服务返回{"regions": ...}(见 structure_system/module.py#L131-L137)。各模块字段矩阵如下:
| 字段名/模块名 | ocr_det | ocr_cls | ocr_rec | ocr_system | structure_table | structure_system | structure_layout | kie_ser | kie_re |
|---|---|---|---|---|---|---|---|---|---|
| angle | ✔ | ✔ | |||||||
| text | ✔ | ✔ | ✔ | ✔ | ✔ | ||||
| confidence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||
| text_region | ✔ | ✔ | ✔ | ✔ | ✔ | ||||
| html | ✔ | ✔ | |||||||
| regions | ✔ | ✔ | |||||||
| layout | ✔ | ||||||||
| ser_res | ✔ | ||||||||
| re_res | ✔ |
说明:如果需要增加、删除、修改返回字段,可在相应模块的module.py文件中修改predict方法的结果组装逻辑,完整流程参考下一节。
七、自定义修改服务模块
如果需要修改服务逻辑,一般需要操作以下步骤(以修改deploy/hubserving/ocr_system为例):
停止服务:
hub serving stop --port/-p XXXX到
deploy/hubserving/ocr_system下的module.py和params.py等文件中根据实际需求修改代码。例如,如果需要替换部署服务所用模型,则需要到 params.py 中修改模型路径参数
det_model_dir和rec_model_dir;如果需要关闭文本方向分类器,则将参数use_angle_cls置为False。当然,同时可能还需要修改其他相关参数(如识别模型输入形状rec_image_shape),请根据实际情况修改调试。强烈建议修改后先直接运行
module.py调试——每个module.py文件末尾都内置了if __name__ == "__main__":本地入口(构造实例、_initialize()后用./doc/imgs/下的示例图跑predict),能正确运行预测后再启动服务测试。注意:PP-OCRv3 识别模型使用的图片输入 shape 为
3,48,320,因此如果换成非 PP-OCRv3 的识别模型,需检查 params.py 中的cfg.rec_image_shape = "3, 48, 320"是否匹配;如果不使用 PP-OCRv3 识别模型,则无需修改该参数。(可选)如果想要重命名模块,需要更改
module.py文件中的以下两处:- from deploy.hubserving.ocr_system.params import read_params 中的
ocr_system - name="ocr_system", 中的
ocr_system
- from deploy.hubserving.ocr_system.params import read_params 中的
(可选)可能需要删除
__pycache__目录以强制刷新 CPython 缓存:find deploy/hubserving/ocr_system -name '__pycache__' -exec rm -r {} \;安装修改后的新服务包:
hub install deploy/hubserving/ocr_system重新启动服务:
hub serving start -m ocr_system
八、近期更新记录
以下为官方文档记录的服务能力演进时间线,可供判断各服务包的能力基线:
- 2022.10.09 新增关键信息抽取服务(
kie_ser、kie_ser_re) - 2022.08.23 新增版面分析服务(
structure_layout) - 2022.05.05 新增 PP-OCRv3 检测和识别模型
- 2022.03.30 新增 PP-Structure 和表格识别两种服务
九、小结:关键文件索引
| 内容 | 仓库路径 |
|---|---|
| 部署文档(本文蓝本) | deploy/hubserving/readme.md |
| 串联服务模块逻辑 | deploy/hubserving/ocr_system/module.py |
| 串联服务参数 | deploy/hubserving/ocr_system/params.py |
| GPU 启动配置样例 | deploy/hubserving/ocr_system/config.json |
| 检测服务参数(阈值差异示例) | deploy/hubserving/ocr_det/params.py |
| 请求测试脚本 | tools/test_hubserving.py |
| 识别字符字典 | ppocr/utils/ppocr_keys_v1.txt |
最后补充一个容易踩坑的细节:同一参数在不同服务包中的默认值并不相同。例如 DB 后处理参数在串联服务 ocr_system/params.py 中为det_db_box_thresh=0.5、det_db_unclip_ratio=1.6,而在独立检测服务 ocr_det/params.py 中为det_db_box_thresh=0.6、det_db_unclip_ratio=1.5。独立部署检测服务时若期望与串联服务行为完全一致,需要显式核对这些阈值,而不是默认它们全局统一。
【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考