背景
在落地RAG知识库过程中,遇到了图文识别、图片表格内容识别的需求。但那时(2024年4月)各开源RAG项目还没有集成成熟的解决方案,经调研我选择了百度开源的PaddleOCR。支持国产!
概念梳理
PaddleOCR
百度飞桨的OCR框架,结合对应模型实现OCR能力。可通过命令行操作,项目中可集成该SDK实现OCR能力。主要包含了如下组件:
- ocr_system:可识别图片中的文字;
- structure_table:可识别图片中的表格,默认返回html格式。集成时按需解析成目标格式,如markdown。
- structure_layout:识别如火车票、发票等版面。
PaddleHub
将PaddleOCR的能力封装成http服务,项目集成时可直接通过API调用完成。
我的RAG使用的也是开源项目,更新频繁。为降低影响,我选择了PaddleHub方式集成。
在集成时,考虑到便利性,使用Docker部署方式。由于是首次制作该Docker镜像,过程分为3步进行:
- paddleOCR基础镜像
- paddlehub基础镜像
- paddlehub运行镜像
当制作过程成熟后可直接使用Dockerfile制作即可。在后续的文章中我会提供完整版的Dockerfile文件。
1 制作paddleOCR基础镜像
基础环境
- ubuntu 22.04
- gcc/g++ 11.04
- Python 3.10
- paddleocr 2.7.5
- paddpaddle 2.5.2
- paddlehub 2.4.0
- opencv-python 4.6.0.66
拉取Ubuntu
docker pull ubuntu:22.04# 启动容器
docker run -it --name=myUbuntu -d ubuntu:22.04# 进入容器
docker exec -it myUbuntu /bin/bash
📌 以下操作需要在容器内进行。
依赖包安装
依次执行如下操作:
# 设置时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \echo "Asia/Shanghai" > /etc/timezone# 安装依赖
apt-get update && apt-get install -y --no-install-recommends \python3.10 \python3-pip \git \wget \unzip \&& apt-get clean all && \rm -rf /var/lib/apt/lists/*# 安装vi
apt-get update && apt-get install -y --no-install-recommends \vim \&& apt-get clean all && \rm -rf /var/lib/apt/lists/*# 安装gcc 和 g++ 11.4.0
apt-get update && apt-get install -y --no-install-recommends \gcc-11 \g++-11 \&& apt-get clean all && \rm -rf /var/lib/apt/lists/*# 为 gcc-11 和 g++-11 建立软连接
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100 && \update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100# 安装paddlehub
pip3.10 install --upgrade pip -i https://mirror.baidu.com/pypi/simple && \
pip3.10 install paddlehub --upgrade -i https://mirror.baidu.com/pypi/simple# 下载PaddleOCR
wget https://github.com/PaddlePaddle/PaddleOCR/archive/refs/tags/v2.7.5.tar.gz && \tar -zxvf v2.7.5.tar.gz && \mv PaddleOCR-2.7.5 PaddleOCR \&& rm -rf v2.7.5.tar.gz \&& cd PaddleOCR \&& pip3.10 install -r requirements.txt -i https://mirror.baidu.com/pypi/simple \&& mkdir -p /PaddleOCR/inference/ \&& wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_det_infer.tar && \tar xf ch_ppocr_mobile_v2.0_det_infer.tar -C /PaddleOCR/inference/ && \wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar && \tar xf ch_ppocr_mobile_v2.0_cls_infer.tar -C /PaddleOCR/inference/ && \wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_rec_infer.tar && \tar xf ch_ppocr_mobile_v2.0_rec_infer.tar -C /PaddleOCR/inference/ \&& rm -rf ch_ppocr_mobile_v2.0_det_infer.tar \&& rm -rf ch_ppocr_mobile_v2.0_cls_infer.tar \&& rm -rf ch_ppocr_mobile_v2.0_rec_infer.tar# 安装paddleocr 2.7.5
pip3.10 install -i https://mirror.baidu.com/pypi/simple paddleocr==2.7.5# 安装paddlepaddle 2.5.2
pip3.10 install -i https://mirror.baidu.com/pypi/simple paddlepaddle==2.5.2# 安装paddleclas
pip3.10 install -i https://mirror.baidu.com/pypi/simple paddleclas==2.5.2# 安装 opencv-python
pip3.10 install -i https://mirror.baidu.com/pypi/simple opencv-python==4.6.0.66
安装完上述依赖后,可以测试一下paddleocr是否可用。如执行表格识别:
paddleocr --image_dir=ppstructure/docs/table/table.jpg --type=structure --layout=false
可以正常输出的话,说明paddleocr安装成功了。
镜像提交
安装完所有依赖后,提交镜像,以生成基础镜像:
docker commit myUbuntu paddleocr:base
查看生成的基础镜像:
root@os1:/home/parallels# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
paddleocr base d48f60f25c7e 19 minutes ago 3.53GB
ubuntu 22.04 437ec753bef3 10 days ago 77.9MB
可能的问题
在依赖包安装过程中,可能会出现如下问题:
📌 问题:
…………
class PaddleOCR(predict_system.TextSystem):
NameError: name 'predict_system' is not defined
原因: 通过pip安装的2.7.5这个版本有个小bug,需要手动修改一下 paddleocr.py:
vi /usr/local/lib/python3.10/dist-packages/paddleocr/paddleocr.py
路径需要按照你的实际路径修改。然后引入包 predict_system:
from tools.infer import predict_system
2 制作paddlehub基础镜像
参考文档:基于HubServing的服务部署
# 启动容器
docker run -it --name=ocr -d paddleocr:base /bin/bash#进入容器
docker exec -it ocr /bin/bash
📌 以下操作需要在容器内进行。
安装表格识别模型
修改配置
cd /PaddleOCR
vi deploy/hubserving/structure_table/params.py
将模型和字典修改为我们下载好的内容,中文版的:
安装模块
# 切换路径
cd /PaddleOCR#PP-Structure
hub install deploy/hubserving/structure_system#表格识别
hub install deploy/hubserving/structure_table#表格版面分析
hub install deploy/hubserving/structure_layout
可能的问题
❓ 问题:
File "/usr/local/lib/python3.10/dist-packages/google/protobuf/descriptor.py", line 914, in __new__
_message.Message._CheckCalledFromGeneratedFile()
TypeError: Descriptors cannot be created directly.
If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.
If you cannot immediately regenerate your protos, some other possible workarounds are:
1. Downgrade the protobuf package to 3.20.x or lower.
2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and will be much slower).
原因:
我们默认安装的protobuf为5.26.1:
root@443924942e80:/PaddleOCR# pip show protobuf
Name: protobuf
Version: 5.26.1
Summary:
Home-page: https://developers.google.com/protocol-buffers/
Author: protobuf@googlegroups.com
Author-email: protobuf@googlegroups.com
License: 3-Clause BSD License
Location: /usr/local/lib/python3.10/dist-packages
Requires:
Required-by: onnx, onnxruntime, paddlenlp, paddlepaddle, visualdl
而paddlepaddle是基于3.19版本生成的proto。
解决方案:
降级protobuf至3.20.2,不能再低了!
pip3.10 install -i https://mirror.baidu.com/pypi/simple protobuf==3.20.2
启动服务
执行下面的指令启动服务:
hub serving start -m structure_table \--port 8866 \--use_multiprocess \--workers
显示结果参考如下:
验证
在容器中的PaddleOCR目录中执行下面的指令进行测试:
cd /PaddleOCRpython3.10 tools/test_hubserving.py --server_url=http://127.0.0.1:8866/predict/structure_table --image_dir=./pic_3.png
响应信息参考:
root@443924942e80:/PaddleOCR# python3.10 tools/test_hubserving.py --server_url=http://127.0.0.1:8866/predict/structure_table --image_dir=./pic_3.png
[2024/04/29 07:13:14] ppocr INFO: Predict time of ./pic_3.png: 14.628s
[2024/04/29 07:13:14] ppocr INFO: {'html': '<html><body><table><tbody><tr><td colspan="8">中国***视频 ***报价表</td></tr><tr><td>序号</td><td>产品型号</td><td>配置描述</td><td></td><td>购买账号数 报价单位</td><td>用户价(每个)</td><td>备注</td></tr><tr><td rowspan="3">1</td>…………………………………………</td></tr></tbody></table></body></html>'}
[2024/04/29 07:13:14] ppocr INFO: avg time cost: 14.628179788589478
安装文字识别模型
ocr_system
修改模型配置文件
vi deploy/hubserving/ocr_system/params.py
将检测模型替换为模型替换为 OCRv4 版本:
🔔 注意:
此处替换成 ch_PP-OCRv4_rec_server_infer 后(100M的高精度模型),当机器资源有限时,客户端调用会超时!(我的虚拟机配置是4c8g)
安装模块
cd /PaddleOCR
hub install deploy/hubserving/ocr_system
安装成功显示如下:
root@443924942e80:/PaddleOCR# hub install deploy/hubserving/ocr_system
[2024-04-29 07:28:38,423] [INFO] - Successfully installed ocr_system-1.0.0
启动服务
root@443924942e80:/PaddleOCR# hub serving start -m ocr_system \--port 8866 \--use_multiprocess \--workers
[2024-04-29 07:30:17,132] [ WARNING] - The _initialize method in HubModule will soon be deprecated, you can use the __init__() to handle the initialization of the object
[2024-04-29 07:30:18 +0000] [419] [INFO] Starting gunicorn 22.0.0
[2024-04-29 07:30:18 +0000] [419] [INFO] Listening at: http://0.0.0.0:8866 (419)
[2024-04-29 07:30:18 +0000] [419] [INFO] Using worker: sync
[2024-04-29 07:30:18 +0000] [436] [INFO] Booting worker with pid: 436
验证
root@443924942e80:/PaddleOCR# python3.10 tools/test_hubserving.py --server_url=http://127.0.0.1:8866/predict/ocr_system --image_dir=./pic_3.png
[2024/04/29 07:58:47] ppocr INFO: Predict time of ./pic_3.png: 23.598s
[2024/04/29 07:58:47] ppocr INFO: [{'confidence': 0.9993818998336792, 'text': '中国***视频', 'text_region': [[387, 17], [514, 17], [514, 34], [387, 34]]}, {'confidence': 0.9982057213783264, 'text': '报价表', 'text_region': [[519, 17], [656, 17], [656, 35], [519, 35]]}, {'confidence': 0.9998618364334106, 'text': '序号', 'text_region': [[13, 55], [41, 55], [41, 75], [13, 75]]}, {'confidence': 0.9999333620071411, 'text': '产品**', 'text_region': [[120, 56], [170, 56], [170, 74], [120, 74]]}, {'confidence': 0.9986265897750854, 'text': '配置描述', 'text_region': [[372, 56], [423, 56], [423, 74], [372, 74]]}, {'confidence': 0.9993833303451538, 'text': '购买**数', 'text_region': [[562, 53], [623, 56], [622, 74], [561, 72]]}, {'confidence': 0.9999394416809082, 'text': '报价单位', 'text_region': [[637, 56], [687, 56], [687, 74], [637, 74]]}, ………………………………………… {'confidence': 0.9988632202148438, 'text': '每增加*T存储,增加****元', 'text_region': [[776, 699], [918, 699], [918, 716], [776, 716]]}]
[2024/04/29 07:58:47] ppocr INFO: avg time cost: 23.59811234474182
安装版面识别模型
structure_layout
修改模型配置文件
vi deploy/hubserving/structure_layout/params.py
修改配置,将模型和字典替换成最新的:
相关配置:
cfg.layout_model_dir = './inference/picodet_lcnet_x1_0_fgd_layout_cdla_infer/'
cfg.layout_dict_path = './ppocr/utils/dict/layout_dict/layout_cdla_dict.txt'
安装模块
cd /PaddleOCR
hub install deploy/hubserving/structure_layout
启动服务
hub serving start --modules structure_layout --port 8871 --use_multiprocess --workers
镜像提交
退出容器,提交镜像。
root@os1:/home/parallels# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
443924942e80 paddleocr:base "/bin/bash" 16 hours ago Up 16 hours ocr
root@os1:/home/parallels# docker commit ocr paddlehub:base
sha256:3d7e5b5fe54b84f3c02df4c059156e5bd9c3d7337a31127ac1735e6491f453a4
root@os1:/home/parallels# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
paddlehub base 3d7e5b5fe54b 3 seconds ago 3.68GB
paddleocr base d48f60f25c7e 17 hours ago 3.53GB
ubuntu 22.04 437ec753bef3 11 days ago 77.9MB
3 制作paddlehub运行镜像
Dockerfile
FROM paddlehub:baseWORKDIR /PaddleOCR# 暴露8866 端口
EXPOSE 8866#启动模型
/bin/bash", "-c", "hub serving start --modules structure_table ocr_system structure_layout --port 8866 --use_multiprocess --workers
生成镜像
docker build -t paddle-server:1.0 .
启动容器
docker run -p 8866:8866 --name=paddle-server -d paddle-server:1.0
验证
在宿主机上PaddleOCR目录下,执行客户端请求进行验证。
导出镜像
docker save paddle-server:1.0 -o paddle-server.tar
导入镜像
导入到目标环境中。
docker load -i paddle-server.tar
优化
CPU环境下启用多核
以structure_table
为例:修改文件/root/.paddlehub/modules/structure_table/module.py
,将 enable_mkldnn=False
修改成为True
,如下:
def _initialize(self, use_gpu=False, enable_mkldnn=True):
然后 docker restart
重启容器。
写在最后
本文介绍了百度飞浆旗下的PaddleOCR和PaddleHub的用途以及Docker镜像的制作方法,并提供了一种“无侵入”式集成OCR能力的简易方案,给您的项目提供参考。