精易论坛

标题: [开箱即用]部署地表最强免费通用文字识别 PaddleOCR [打印本页]

作者: 易函数    时间: 2021-8-11 20:02
标题: [开箱即用]部署地表最强免费通用文字识别 PaddleOCR
本帖最后由 易函数 于 2021-8-13 01:35 编辑

基于 Serverless 架构部署通用文字识别 PaddleOCR


github stars gitee stars


项目背景


PaddleOCR 旨在打造一套丰富、领先、且实用的OCR工具库,助力使用者训练出更好的模型,并应用落地。


PaddleOCR 项目地址: https://github.com/PaddlePaddle/PaddleOCR


在日常项目应用中,相信大家都希望自己项目中的Restful API服务,能够稳健的运行,并且最好拥有高并发,高可用的特性。云厂商提供的 Serverless 服务是最佳的选择。无需运维人员,无需自建 k8s,不需要担心服务崩溃不可用。


我们把 PaddleOCR 服务打包成一个镜像,以便在 Docker 或 k8s 环境里,快速发布上线使用。


本文将提供标准化的代码来实现这样的目标。


大家可以通过本项目提供的镜像,把 PaddleOCR 项目快速发布成可调用的Restful API服务。


开箱即用


这里提供了开箱即用的 docker 镜像,可直接将 PaddleOCR 部署到本地服务器,阿里云函数计算,腾讯云函数中提供通用文字识别 api 接口


PaddleOCR docker 镜像地址


部署 PaddleOCR 到本地


如果国外访问太慢可使用国内的仓库地址


# docker hub 仓库的地址 (国外地址较慢)
docker run -itd --name ppocr -p 9000:9000 duolabmeng666/paddlehub_ppocr:1.0 /bin/bash -c "sh /PaddleOCR/start.sh"

# 腾讯云的镜像仓库地址
docker run -itd --name ppocr -p 9000:9000 ccr.ccs.tencentyun.com/llapi/pphubocr:1.0 /bin/bash -c "sh /PaddleOCR/start.sh"

# 阿里云的镜像仓库地址
docker run -itd --name ppocr -p 9000:9000 registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0 /bin/bash -c "sh /PaddleOCR/start.sh"

调用 OCR



  1. 计算待识别图片的Base64编码

  2. 发送服务请求(发送参数,参考下面命令)


curl -H "Content-Type:application/json" -X POST --data "{\"images\": [\"iVBORw0KGgoAAAANSUhEUgAAAHkAAAAnCAYAAAArfufOAAAEvElEQVR4nO1bMWsbSRT+clyv4sAWGAS5wpUN8UGuSmlQEBHpsp0LgZy4cOkuwhHqrDKFkERcpMqWQZcgkRQurrJBNifjwo3BYEcSpNAv2Huzu5JWu7Pe2dWubDLzNV7P7r5987733rx5Yz8yCFD4pfHbfSugkDwUyRJAkSwBFMkSQJEsARTJEkCRLAEUyRJAkSwBFMkSQJEsAbwkn+nQdqo4PBN4W+jZATrlKrTydww5d4dfGyRDx7mgwg8Vsc+D2bbZE/tuwHO/x6WTL/o9/NsHVvPrWIoqg024fj2XGtnXeyg8mf7OjLPbGoWWs5rfQiW3LPSs8DfSG3i/vzljn/MTmm/3mhznAqWahjXee2QXS/4FOdc6/xmMSe5/R6l8ikvHjU69io7QVJzPplDY30Y27VC2xeRmUGKGsclyGzwQTzToNb+bLFN8xCG8hgpGxt+AHvRwuNPGVSj5wd84b1ZRufWOrxX3oNv2quw0PHY19WGOz3EQNyyS05uo1DatkTBEBD1LzqN3WRSJGtImrM+uvQ4jHZhzvyYbfwZWZm4wO7UpsMiBBBw7wXRNitQpisnTdn2dpYd/zHQzIm+twiJ2D++7LM0lp9kU1/Z3xbHquPam49FUHs279DS8Rn4pvlLm6cnR/6/n0IvrM0O+JIdJ11ycHVkRyYnEqewMCvkU0ErNpDSrQEthJfEoni9dL+W2oeesazPtdmflMcLCwinTg4jLnS/JYdK1B2yNd4671nyn7CiGeHjo4bjrd08gWyTszAmkaztNU9oooW0VFeM1P4YqOV7Ml64nOLuYZL1jiujjp84AiVZ4xYn40zXbMrFKl9aFYbMdXbOFIJ7qmm13VtMpXPavcXVLP+sNrFDRuBGvspERf7pmUbtvXfKaH8EY4PSECo/0n9H31YuEuYPI4Fl+hMtWBtq+BrDoLOtUb4QR5NxZ3I3AAHRtq5JvhojCs26H3fNGwfzpmvUBkN+iqP08GVsrbqHQPAJuwkheRpZ2Flnf+1MnCNOQYXg4JDv36gvDnOmaMplZURfJ4F+dN4iwomYVld2YCi97t5LNb+CqdYTznKjeNsm8vVm0jhe4+7RIsCP7cdju2AIxvB1Rxtk2je2/NMVReE27Wy9ymxje0DvNnrCdTZLv3JvdF/o/zdT9OFaZ7vbtKHS6RusjNLNRY3XkConv5b3drSW2HFDq1poQIvrOdG15mbs3OkevOP0HrWmzhZqfg7EoYVHwd5xRfC9LwjwYr8PMoZzZgK3fz3FDy4cI0dzzZOvYjAgGpV4OkRuUQvWXP7FLz2g7DXQEKkIT6WUzMjsnQUdodruTnGIRFTZzZt6R6Xjc75g0UZjHuHYw1Xg9/HUUahTRt+1ADh5N/xfKUcKHWVcnKZBzAsXLBKINEXsbgIhHgjxMq1KriOq4xof9AZbSnKrVpTNve2nVNSlPWzP0UaPjW8Lty8k7Poc6jOTBl7rx6s2B8eHUiI4f34y3JOPtl/5kqNc4MF69+2YM5hAbL/pG+92BOVennqFgz9M9L8uGn4xewJgbUxv9Z3xgct/UjfaPaKqNeXR/0xHJCr8q1N94SQBFsgRQJEsARbIEUCRLAEWyBFAkSwBFsgT4HxQ8/CE4B3ErAAAAAElFTkSuQmCC\"]}" http://127.0.0.1:9000/predict/ocr_system


  1. 返回结果(如果调用成功,会返回如下结果)


{"msg":"","results":[[{"confidence":0.9853195548057556,"text":"测试图像路径,可以是单张图片路径,也可以是图像集合目录路径","text_region":[[5,10],[466,10],[466,24],[5,24]]}]],"status":"000"}

调用 OCR 代码示例


查看调用代码示例


1


import requests
from pyefun import *
from pyefun.encoding.ebase64 import *

# 用 docker 部署 PaddleOCR 开箱即用 通用文字识别
# https://github.com/duolabmeng6/paddlehub_ppocr

def ocr(文件地址):
    image = base64编码(读入文件(文件地址))
    data = '{"images":["' + image + '"]}'
    txt = requests.post("http://127.0.0.1:9000/predict/ocr_system", data=data,
                        headers={'Content-Type': 'application/json'})
    return txt.content.decode("utf-8")

print(ocr("./test.png"))

部署到阿里云函数计算


在阿里云函数计算控制台中, 新建服务,创建函数,根据下面信息填写,创建函数后,绑定域名即可提供 api 识别接口。


容器镜像地址 registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0


启动命令 ["sh","/PaddleOCR/start.sh"]


需要绑定域名


识别地址就是 http://绑定域名/predict/ocr_system


2


3


部署到腾讯云函数


在腾讯云函数控制台中,需要将镜像推送至自己账户中的镜像仓库,随后创建云函数,即可提供 api 识别接口。



  1. 需要将镜像推送至腾讯云的镜像仓库

  2. 创建云函数


docker pull duolabmeng666/paddlehub_ppocr:1.2
docker tag duolabmeng666/paddlehub_ppocr:1.2 ccr.ccs.tencentyun.com/llapixxx/ppocr:1.2
docker push ccr.ccs.tencentyun.com/llapixxx/ppocr:1.2

推送镜像至腾讯云以后就可以创建云函数了


识别地址就是 https://创建云函数后可以看到.gz.apigw.tencentcs.com/release/predict/ocr_system


4 5


项目开发


使用 PaddleHub Serving 的服务部署 PaddleOCR


步骤如下:



  1. 构建飞浆的运行环境

  2. 用 PaddleHub Serving 的服务部署

  3. 将 PaddleOCR 项目下载回来,编写 Dockerfile 文件

  4. 在 Serverless 架构的中部署


docker 中构建飞浆的运行环境


1.构建 python3.7 运行环境


新建以下文件和目录


/test_ppocr
-- PaddleOCR (https://github.com/PaddlePaddle/PaddleOCR 项目的文件)
-- Dockerfile (docker 构建的文件)

# 创建 python 的基础的运行环境
docker run -itd --name testppocr -p 9000:9000 -v /test_ppocr:/test_ppocr python:3.7.10-slim /bin/bash #
# 进入容器内安装飞浆的运行环境
docker exec -it testppocr /bin/bash

2. 安装依赖


apt install g++
apt install libglib2.0-dev
apt install libgl1-mesa-glx
apt install libsm6
apt install libxrender1

# 离线下载 python 安装包 由于构建时经常重试所以下载离线包调试速度会加快
pip download -r requirements.txt -d ./pg
pip download paddlepaddle==2.0.2 -i https://mirror.baidu.com/pypi/simple -d ./pg
pip download paddlehub -d ./pg

# 安装 python 包
pip install -r requirements.txt --find-links ./pg
pip install paddlepaddle --find-links ./pg
pip install paddlehub -U --no-index --find-links ./pg

用 PaddleHub Serving 的服务部署


hub install deploy/hubserving/ocr_system/
hub install deploy/hubserving/ocr_cls/
hub install deploy/hubserving/ocr_det/
hub install deploy/hubserving/ocr_rec/

到这里 PaddleHub Serving 运行环境就安装好了 运行起来看一下效果


hub serving start --modules ocr_system ocr_cls ocr_det ocr_rec -p 9000

识别地址就是 http://127.0.0.1:9000/predict/ocr_system


测试没问题,到这里运行镜像就构建好了


最后将容器内无用文件删除,减小容器的体积


rm -rf /root/.cache/* \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /app/test/pg/*

保存并推送到对应厂商的容器镜像仓库


这里以阿里云容器镜像仓库作为例子


请自行修改参数推送,这里是我的账户命令


docker commit testppocr paddlehub_ppocr:1.0
docker tag paddlehub_ppocr:1.0 registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0
docker push registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0

编写 Dockerfile


上面的过程是构建飞浆的基础运行环境的 那么以后就可以用该基础镜像部署任意飞浆模型了


FROM registry.cn-hongkong.aliyuncs.com/llapi/pphub:base

COPY PaddleOCR /PaddleOCR

WORKDIR /PaddleOCR

RUN mkdir -p /PaddleOCR/inference/
ADD https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_det_infer.tar /PaddleOCR/inference/
RUN tar xf /PaddleOCR/inference/ch_ppocr_mobile_v2.0_det_infer.tar -C /PaddleOCR/inference/

ADD https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar /PaddleOCR/inference/
RUN tar xf /PaddleOCR/inference/ch_ppocr_mobile_v2.0_cls_infer.tar -C /PaddleOCR/inference/

ADD https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_rec_infer.tar /PaddleOCR/inference/
RUN tar xf /PaddleOCR/inference/ch_ppocr_mobile_v2.0_rec_infer.tar -C /PaddleOCR/inference/

RUN hub install deploy/hubserving/ocr_system/
RUN hub install deploy/hubserving/ocr_cls/
RUN hub install deploy/hubserving/ocr_det/
RUN hub install deploy/hubserving/ocr_rec/

EXPOSE 9000

CMD ["/bin/bash","-c","hub serving start --modules ocr_system ocr_cls ocr_det ocr_rec -p 9000"]

在 Serverless 架构的中部署


需要将docker镜像推送至对应平台的镜像仓库中


这里以阿里云容器镜像仓库作为例子


请自行修改参数推送,这里是我的账户命令


docker commit testppocr paddlehub_ppocr:1.0
docker tag paddlehub_ppocr:1.0 registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0
docker push registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0

部署到阿里云函数计算


在阿里云函数计算控制台中, 新建服务,创建函数,根据下面信息填写,创建函数后,绑定域名即可提供 api 识别接口。


容器镜像地址 registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0


启动命令 ["sh","/PaddleOCR/start.sh"]


需要绑定域名


识别地址就是 http://绑定域名/predict/ocr_system


2


3


部署到腾讯云函数


由于腾讯云云函数容器的文件的限制只允许 /tmp 可读可写,所以我们需要修改代码以支持云函数的部署。


这里我已经构建好了可以直接使用。


在腾讯云函数控制台中,需要将镜像推送至自己账户中的镜像仓库,随后创建云函数,即可提供 api 识别接口。



  1. 需要将镜像推送至腾讯云的镜像仓库

  2. 创建云函数


docker pull duolabmeng666/paddlehub_ppocr:1.2
docker tag duolabmeng666/paddlehub_ppocr:1.2 ccr.ccs.tencentyun.com/llapixxx/ppocr:1.2
docker push ccr.ccs.tencentyun.com/llapixxx/ppocr:1.2

推送镜像至腾讯云以后就可以创建云函数了


识别地址就是 https://创建云函数后可以看到.gz.apigw.tencentcs.com/release/predict/ocr_system


4 5


解决方案



分析 docker 中写出的文件


将我们前面部署好的镜像,在自己电脑上运行起来


docker run -itd --name ppocr -p 9000:9000 ccr.ccs.tencentyun.com/llapi/pphubocr:1.0

查看文件差异信息 发现运行了以后在非 /tmp 目录进行了写文件操作 所以导致在云函数中无法启动容器。 现在我们要做的事情就是将路径处理到 /tmp 中


docker diff ppocr
C /root
C /root/.paddlehub
C /root/.paddlehub/conf
A /root/.paddlehub/conf/serving_9000.json
C /root/.paddlehub/log
A /root/.paddlehub/log/HubServing-2021_08_12.log

通过查看源代码可以发现 /paddlehub/env.py 是控制这些文件写出目录的文件


将文件复制出来放置 ./tx/env.py 并在最后增加以下代码


CONF_HOME = "/tmp"
LOG_HOME = "/tmp"
TMP_HOME = "/tmp"

编写 Dockerfile


在项目目录中创建文件 Dockerfile_TX


FROM ccr.ccs.tencentyun.com/llapi/pphubocr:1.0

WORKDIR /PaddleOCR

COPY ./tx/env.py /usr/local/lib/python3.7/site-packages/paddlehub/env.py

CMD ["/bin/bash","-c","hub serving start --modules ocr_system ocr_cls ocr_det ocr_rec -p 9000"]

构建镜像测试


docker build -f ./Dockerfile_TX -t paddlehub_ppocr:1.0 .
docker rm -f ppocr
docker run -itd --name ppocr -p 9000:9000 paddlehub_ppocr:1.0
docker logs ppocr
docker diff ppocr

可以发现镜像在镜像中依然存在非 /tmp 文件的读写 但是这些文件在保存容器镜像以后 不会在读写 所以接下来只需要保存镜像推送即可


docker diff ppocr
C /usr
C /usr/local
C /usr/local/lib
C /usr/local/lib/python3.7
C /usr/local/lib/python3.7/site-packages
C /usr/local/lib/python3.7/site-packages/paddlehub
C /usr/local/lib/python3.7/site-packages/paddlehub/__pycache__
C /usr/local/lib/python3.7/site-packages/paddlehub/__pycache__/env.cpython-37.pyc
C /tmp
A /tmp/HubServing-2021_08_12.log
A /tmp/cache.yaml
A /tmp/config.yaml
A /tmp/serving_9000.json

打包镜像推送


# 保存镜像
docker commit ppocr ccr.ccs.tencentyun.com/llapi/pphubocr:1.2

# 测试一下这个镜像是否还存文件读写的情况 没有问题的话就可以推送了
docker rm -f ppocr
docker run -itd --name ppocr -p 9000:9000 ccr.ccs.tencentyun.com/llapi/pphubocr:1.2
docker logs ppocr
docker diff ppocr

# 经过前面的检查确定镜像没有问题,推送镜像
docker push ccr.ccs.tencentyun.com/llapi/pphubocr:1.2

在腾讯云函数中创建


选择镜像直接部署就可以拿到识别地址了


4 5


总结


在 Serverless 架构下部署深度学习模型变得非常简单且能提供无限的并发支持,我们可以将镜像部署到各个提供 Serverless 的服务商中,可提供稳定可靠弹性的推理服务。


在构建镜像方面,飞浆官方提供的 docker 镜像,动辄 4GB、8GB,在镜像如此大的情况下基本无缘 Serverless 。


本文所构建的的镜像仅 564MB ,在 Serverless 架构下部署 ,启动速度理想。


鸣谢


感谢各厂商大佬提供的技术支持



学习交流


pyefun 易函数 qq群:1017240979


项目相关


pyefun 易函数 https://github.com/duolabmeng6/pyefun


为python提供强大且易用的中文函数库,完整的封装了易语言核心支持库所有功能,以及易语言中简单易用的函数



作者: 1185384801    时间: 2021-8-11 20:44
火前留名
作者: xiaoshe    时间: 2021-8-11 21:18
那不错!
作者: xiaoshe    时间: 2021-8-11 21:23
1185384801 发表于 2021-8-11 20:44
火前留名

你是我见过精币最多的大佬  膜拜膜拜  赏我点吧!
作者: 784326742    时间: 2021-8-11 22:05
有没有蓝盘的  下载真慢按K跑。。。。猴年马月
作者: 风雪飞扬    时间: 2021-8-17 14:38
感谢大佬分享,大佬流弊威武
作者: 风雪飞扬    时间: 2021-8-17 15:21
@易函数 您好大佬,想咨询两个问题一下,
就是部署 PaddleOCR 到本地,执行docker run -itd --name ppocr -p 9000:9000 ccr.ccs.tencentyun.com/llapi/pphubocr:1.0 /bin/bash -c "sh /PaddleOCR/start.sh"下载镜像后无法运行,一直报错,请问是什么问题呢?希望大佬能指教一下,感激不尽。
WARNING: AVX is not support on your machine. Hence, no_avx core will be imported, It has much worse preformance than avx core.
Error: AVX is not support on your machine, but you have installed paddlepaddle with avx core, you should reinstall paddlepaddle by 'python -m pip install -U paddlepaddle-gpu[==version] -f https://paddlepaddle.org.cn/whl/stable_noavx.html'
Traceback (most recent call last):
  File "/usr/local/bin/hub", line 5, in <module>
    from paddlehub.commands.utils import execute
  File "/usr/local/lib/python3.7/site-packages/paddlehub/__init__.py", line 18, in <module>
    import paddle
  File "/usr/local/lib/python3.7/site-packages/paddle/__init__.py", line 29, in <module>
    from .fluid import monkey_patch_variable
  File "/usr/local/lib/python3.7/site-packages/paddle/fluid/__init__.py", line 35, in <module>
    from . import framework
  File "/usr/local/lib/python3.7/site-packages/paddle/fluid/framework.py", line 36, in <module>
    from . import core
  File "/usr/local/lib/python3.7/site-packages/paddle/fluid/core.py", line 349, in <module>
    raise e
  File "/usr/local/lib/python3.7/site-packages/paddle/fluid/core.py", line 308, in <module>
    from .core_noavx import *
ModuleNotFoundError: No module named 'paddle.fluid.core_noavx'
作者: 二毛2021    时间: 2021-8-17 15:31
这玩意冷启动那么慢,serverless估计不怎么好用吧,还是本地部署效率高
作者: 素颜じ灵魂hジ    时间: 2021-9-28 23:53
阿里云一直卡在把镜像推送到自己账户这一步,能出个详细教程吗
作者: ♂隐    时间: 2021-10-3 09:35
这个绝对牛逼啊!虽然我还看不懂额!
作者: flyhsx    时间: 2021-10-9 14:38
能离线部署到本地么

作者: pwind    时间: 2021-12-16 19:31
阿里云提示
{
    "request": {
        "url": "https://1828122772282890.cn-hangzhou.fc.aliyuncs.com/2016-08-15/services/ocr/functions",
        "method": "POST",
        "params": {
            "headers": {
                "x-fc-date": "Thu, 16 Dec 2021 11:31:31 GMT",
                "x-fc-account-id": "1828122772282890",
                "Content-Type": "application/json",
                "Authorization": "FC TMP.3KgTaTfzDjYZLK1TLj37HfzwYBRcRw7gKH1S4bBmw516xraKXitQVj9eFrEeEYQYgSfezDbxAzPoV73UGxMSYEtP7LrPKF:iFBmx+QPNqVKhj7FyvMaf+9v8d4SMUX7NQwzc38c3FE="
            },
            "method": "POST",
            "body": "{\"functionName\":\"ocr\",\"handler\":\"index.handler\",\"regionId\":\"cn-hangzhou\",\"runtime\":\"custom-container\",\"serviceName\":\"ocr\",\"initializer\":\"\",\"environmentVariables\":{},\"initializationTimeout\":3,\"instanceType\":\"e1\",\"memorySize\":3072,\"timeout\":60,\"customContainerConfig\":{\"args\":\"\",\"command\":\"[\\\"sh\\\",\\\"/PaddleOCR/start.sh\\\"]\",\"image\":\"registry.cn-hongkong.aliyuncs.com/llapi/ppocr:1.0\",\"accelerationType\":\"Default\"},\"caPort\":9000}",
            "credentials": "same-origin",
            "url": "https://1828122772282890.cn-hangzhou.fc.aliyuncs.com/2016-08-15/services/ocr/functions",
            "\"\"": "undefined"
        }
    },
    "response": {
        "ErrorCode": "InvalidArgument",
        "ErrorMessage": "Image and function must be in the same region when runtime is custom-container"
    }
}
作者: nowxname    时间: 2021-12-18 12:01
大佬牛逼了,
作者: 907811175    时间: 2022-1-8 22:00
这个吃配置的,除非你服务器配置一个好,不然识别效率跟蜗牛一样
作者: 海洋之心365    时间: 2022-4-12 19:47
学习 学习
作者: wnt24    时间: 2022-5-3 13:47
有点看不明白呀!
作者: qq73s5456    时间: 2022-9-1 17:21
说话话, 这种依懒一堆环境的东西, 实际应用不强, 小项目一般一个DLL 就OK, 大项目还不如直接对接大厂API 。
作者: aosheng    时间: 2022-9-18 06:35
6666666666666666666666
作者: yangli    时间: 2022-9-26 08:22
1111111111111111111111111111111
作者: zkwt0012    时间: 2024-11-5 18:12
牛牛牛牛牛
作者: zkwt0012    时间: 2024-11-5 18:12
火前留名
作者: 不过人心    时间: 2025-4-15 10:40
“{"msg":"OpenCV(4.2.0) /io/opencv/modules/imgcodecs/src/loadsave.cpp:730: error: (-215:Assertion failed) !buf.empty() in function 'imdecode_'\n","results":"","status":"101"}

搞好了出现这个,难受啊




欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4