RapidAI / RapidOCR

📄 Awesome OCR multiple programing languages toolkits based on ONNXRuntime, OpenVINO and PaddlePaddle.
https://rapidai.github.io/RapidOCRDocs
Apache License 2.0
3.11k stars 370 forks source link

docker安装rapidocr_api有bug #223

Closed nzm001 closed 3 weeks ago

nzm001 commented 2 months ago

问题描述 / Problem Description

  1. python-multipart依赖没有加
  2. fix bugs: Error loading ASGI app. Could not import module "api".
  3. 内存爆炸

运行环境 / Runtime Environment

  1. ubuntu22.04
  2. docker环境python:3.10-slim

复现代码 / Reproduction Code

# 启动python:3.10-slim(docker run ... /bin/bash)
sed -i '.......'  /etc/apt/sources.list.d/debian.sources # 修改apt源,没影响
apt-get update
apt-get install -f -y g++ gcc python3-opencv
apt-get clean
rm -rf /var/lib/apt/lists/*
pip install --no-cache-dir --upgrade pip -i https://mirrors.aliyun.com/pypi/simple
pip install --no-cache-dir rapidocr_api -i https://mirrors.aliyun.com/pypi/simple
rapidocr_api -ip 0.0.0.0 -p 9003 # error1:没装python-multipart
pip install --no-cache-dir python-multipart -i https://mirrors.aliyun.com/pypi/simple
rapidocr_api -ip 0.0.0.0 -p 9003 # error2:Error loading ASGI app. Could not import module "api".
#修改api.py
rapidocr_api -ip 0.0.0.0 -p 9003 # 没有报错
# error3:每秒内存占用提高0.3-0.5MB的样子,直到boom

可能解决方案 / Possible solutions

  1. 添加python-multipart依赖。另外opencv有四个包,只要装一个,是否可以先检测,都没有再装opencv-python。
  2. stackoverflow,api改为src.api。
  3. 我不会。猜测开发的时候,直接在自己的工程目录下跑没问题。但是用pip安装,环境目录不一样导致2和3的问题。
  4. 请问rapidocr_api可以指定det、rec模型吗?谢谢。使用的时候发现小图片(来源是手机截图,但是我知道文字一定会在某个300x10的矩形中出现)先用随便啥模型超分辨率重建一次,det和rec结果要好很多,不知道有没有普适性。
SWHL commented 2 months ago

感谢你的指出,请问是否愿意提PR来帮助修复这些问题呢

nzm001 commented 2 months ago

第二点,修改api.py,"api:app"改为"rapidocr_api.api:app",但是这么改只是不报错,内存问题没有解决。只会改这么一处。

SWHL commented 2 months ago

好的,等我有空,我来具体看看

SWHL commented 1 month ago

rapidocr_api==0.0.9

内存一直增长的问题,暂时不知道为啥,因为rapidocr_api依赖rapidocr_onnxruntime, 而rapidocr_onnxruntime是没有这个问题的。

nzm001 commented 1 month ago

刚刚重新试了一下,以下是Dockerfile

FROM python:3.10-slim

ENV DEBIAN_FRONTEND=noninteractive

RUN set -eux; \
    pip install --no-cache-dir rapidocr_api -i https://mirrors.aliyun.com/pypi/simple; \
    pip uninstall -y opencv-python; \
    pip install --no-cache-dir opencv-python-headless -i https://mirrors.aliyun.com/pypi/simple

EXPOSE 9003

CMD ["bash", "-c", "rapidocr_api -ip 0.0.0.0 -p 9003"]

直接docker run会导致一个cpu核心跑满(空载,未识别图片),内存一直增加。如果用docker run -it xx /bin/bash进去,

cd /usr/local/lib/python3.10/site-packages/rapidocr_api/
rapidocr_api -ip 0.0.0.0 -p 9003

这样cpu基本没有负载(<0.5%),内存不会不停增加。也就是说必须要在rapidocr_api的安装目录运行,不知道这样是否有助于找到bug。

nzm001 commented 1 month ago

另外用了这段时间发现对于手机电脑截屏、漫画、电影内嵌字幕这类图片中较小的文字时,使用upscale再识别准确率有提升(可以先裁剪再upscale)。不过这个自己去整合应用就行了,有兴趣提高准确率的人可以去试试看。例如实际应用漫画翻译manga-image-translator中的参数--upscaler {waifu2x,esrgan,4xultrasharp}。

210 电影字幕就是这种情况。

SWHL commented 1 month ago

刚刚重新试了一下,以下是Dockerfile

FROM python:3.10-slim

ENV DEBIAN_FRONTEND=noninteractive

RUN set -eux; \
    pip install --no-cache-dir rapidocr_api -i https://mirrors.aliyun.com/pypi/simple; \
    pip uninstall -y opencv-python; \
    pip install --no-cache-dir opencv-python-headless -i https://mirrors.aliyun.com/pypi/simple

EXPOSE 9003

CMD ["bash", "-c", "rapidocr_api -ip 0.0.0.0 -p 9003"]

直接docker run会导致一个cpu核心跑满(空载,未识别图片),内存一直增加。如果用docker run -it xx /bin/bash进去,

cd /usr/local/lib/python3.10/site-packages/rapidocr_api/
rapidocr_api -ip 0.0.0.0 -p 9003

这样cpu基本没有负载(<0.5%),内存不会不停增加。也就是说必须要在rapidocr_api的安装目录运行,不知道这样是否有助于找到bug。

收到,感谢,我排查排查

SWHL commented 1 month ago

另外用了这段时间发现对于手机电脑截屏、漫画、电影内嵌字幕这类图片中较小的文字时,使用upscale再识别准确率有提升(可以先裁剪再upscale)。不过这个自己去整合应用就行了,有兴趣提高准确率的人可以去试试看。例如实际应用漫画翻译manga-image-translator中的参数--upscaler {waifu2x,esrgan,4xultrasharp}。 #210 电影字幕就是这种情况。

感谢,我后期看看能不能整合进来

SWHL commented 1 month ago

关于docker启动报OOM的问题,猜测可能是我用错了async函数,麻烦你那里安装rapidocr_api之后,在源码中去掉async字段,实验一下是否仍在存在该问题: https://github.com/RapidAI/RapidOCR/blob/b2fd006ee602b49a723914dab8b3ac69030b27cd/api/rapidocr_api/main.py#L52

nzm001 commented 1 month ago
FROM python:3.10-slim

ENV DEBIAN_FRONTEND=noninteractive

RUN set -eux; \
    pip install --no-cache-dir rapidocr_api -i https://mirrors.aliyun.com/pypi/simple; \
    pip uninstall -y opencv-python; \
    pip install --no-cache-dir opencv-python-headless -i https://mirrors.aliyun.com/pypi/simple; \
    sed -i 's/async def ocr(/def ocr(/' /usr/local/lib/python3.10/site-packages/rapidocr_api/main.py

EXPOSE 9003

CMD ["bash", "-c", "rapidocr_api -ip 0.0.0.0 -p 9003"]

确认过了,bug没有变化,在rapidocr_api的安装目录运行正常。docker run -it进入

cat /usr/local/lib/python3.10/site-packages/rapidocr_api/main.py # 确认已经删除async
cd /usr/local/lib/python3.10/site-packages/rapidocr_api/
rapidocr_api -ip 0.0.0.0 -p 9003 # 在rapidocr_api的安装目录运行正常
# Ctrl + C 退出
cd /
rapidocr_api -ip 0.0.0.0 -p 9003 # 根目录运行还是一样的问题
SWHL commented 1 month ago

收到,请尝试将执行代码rapidocr_api -ip 0.0.0.0 -p 9003写到一个shell(例如1.sh)文件里,通过bash 1.sh来启动试试呢。

nzm001 commented 1 month ago

docker run -it xx /bin/bash

# cd /
# echo 'rapidocr_api -ip 0.0.0.0 -p 9003' > 1.sh
# bash 1.sh # bug没变化,单核占满,内存增长
INFO:     Will watch for changes in these directories: ['/']
INFO:     Uvicorn running on http://0.0.0.0:9003 (Press CTRL+C to quit)
INFO:     Started reloader process [132] using WatchFiles
INFO:     Started server process [162]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

# cd /usr/local/lib/python3.10/site-packages/rapidocr_api/
# bash /1.sh # 运行正常
INFO:     Will watch for changes in these directories: ['/usr/local/lib/python3.10/site-packages/rapidocr_api']
INFO:     Uvicorn running on http://0.0.0.0:9003 (Press CTRL+C to quit)
INFO:     Started reloader process [70] using WatchFiles
INFO:     Started server process [100]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
SWHL commented 1 month ago

好吧,这。。。。 暂时不知道哪里出了问题了

xmxoxo commented 1 month ago

有可能是那个“reload=True“造成的,我改了代码,加了参数,可以传是否使用模型等功能,我改完PR一下

xmxoxo commented 1 month ago

另外在Docker里 启动方式用这样:

CMD ["rapidocr_api"]

SWHL commented 1 month ago

@xmxoxo 感谢,期待你的PR

xmxoxo commented 1 month ago

已经提交PR

SWHL commented 1 month ago

@xmxoxo 已经合并进去了,感谢,最新版本为rapidocr_api==0.1.1 @nzm001 请安装最新的版本,尝试是否仍然有问题

SWHL commented 3 weeks ago

@TwT-L 麻烦说一下运行具体环境、代码和详细报错信息

xmxoxo commented 3 weeks ago

这里有个做好的镜像 大家可以测试下: registry.cn-shenzhen.aliyuncs.com/my_worker/rapidocr_api:0.1.1

使用方法:

拉取镜像:
docker pull registry.cn-shenzhen.aliyuncs.com/my_worker/rapidocr_api:0.1.1

启动容器:
docker run -p 9003:9003 --name rapidocr_api_1 --restart always -d rapidocr_api:0.1.1
SWHL commented 3 weeks ago

@xmxoxo 哇哦,想问一下这个镜像已经解决了上面的问题了吗?如果是的,我想给写到官方文档里呢,一直缺少个docker镜像来着。

xmxoxo commented 3 weeks ago

@SWHL 你可以测试一下这个镜像,我这里用是没啥问题

nzm001 commented 3 weeks ago

有可能是那个“reload=True“造成的,我改了代码,加了参数,可以传是否使用模型等功能,我改完PR一下

@xmxoxo 这怎么能找得出来??6啊。那个dockerfile里,uninstall需要和前面的install写在一个RUN里,否则镜像不会缩小。

api/README.md里设置环境变量expert改为export。

FROM python:3.10-slim

ENV DEBIAN_FRONTEND=noninteractive

RUN set -eux; \
    pip install --no-cache-dir rapidocr_web rapidocr_api -i https://mirrors.aliyun.com/pypi/simple; \
    pip uninstall -y opencv-python; \
    pip install --no-cache-dir opencv-python-headless -i https://mirrors.aliyun.com/pypi/simple

EXPOSE 9003
EXPOSE 9004

CMD ["bash", "-c", "rapidocr_web -ip 0.0.0.0 -p 9003 & rapidocr_api -ip 0.0.0.0 -p 9004"]

运行

sudo docker run -d \
    --name rapidocr \
    --restart always \
    --cap-drop=ALL \
    --security-opt=no-new-privileges \
    --cpus=".9" \
    --memory=4g --memory-swap=4g \
    -p 9003:9003 -p 9004:9004 \
    -e det_model_path=/models/ch_PP-OCRv3_det_infer.onnx \
    -e rec_model_path=/models/ch_PP-OCRv3_rec_infer.onnx \
    -v /path/to/models:/models \
    rapidocr

@SWHL Debian 12测试没问题。不会编程,具体代码就不献丑了,下面是用的时候发现的一些想法:

  1. Dockerfile里api和web可以任意选择删除,也可以放一起用(这俩默认端口一样,所以改了一个)。
  2. docker run参数限制了cpu和内存,参数你看看要不要删改。-e det_model_path-e rec_model_path只对api生效,对web无效,两者并不统一。
  3. 设置了rec_model_pathrec_keys_path是否也需要改,还是说通过那个在线转换paddleocr后,onnx自带字典。
SWHL commented 3 weeks ago

@nzm001 回答 想法2: web端,我考虑做一些适配,统一一下 想法3: 通过在线paddleocr转换后,onnx中是自带字典的。需要注意的是如果自己是通过paddle2onnx工具,是不带字典的哈

nzm001 commented 3 weeks ago

怪不得,用PaddlePaddle/Paddle2ONNX和RapidAI/PaddleOCRModelConvert这两个转换的sha256一样,用网页转的就是和前两者不同。

SWHL commented 3 weeks ago

@nzm001 RapidAI/PaddleOCRModelConvert和 用网页转的是同一个工具呀,网页的只不过是用streamlite包装了一下,没做什么,估计后面对应的依赖包,像paddle2onnx,版本不同。

TwT-L commented 2 weeks ago

为什么我的docker启动的rapidocr_api会提示

INFO:     172.30.0.2:56468 - "POST /ocr HTTP/1.1" 500 Internal Server Error
rapidocr-1  | ERROR:    Exception in ASGI application
rapidocr-1  | Traceback (most recent call last):
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
rapidocr-1  |     result = await app(  # type: ignore[func-returns-value]
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
rapidocr-1  |     return await self.app(scope, receive, send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 1054, in __call__
rapidocr-1  |     await super().__call__(scope, receive, send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 113, in __call__
rapidocr-1  |     await self.middleware_stack(scope, receive, send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 187, in __call__
rapidocr-1  |     raise exc
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 165, in __call__
rapidocr-1  |     await self.app(scope, receive, _send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
rapidocr-1  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
rapidocr-1  |     raise exc
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
rapidocr-1  |     await app(scope, receive, sender)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 715, in __call__
rapidocr-1  |     await self.middleware_stack(scope, receive, send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 735, in app
rapidocr-1  |     await route.handle(scope, receive, send)
rapidocr-1  |   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 288, in handle
rapidocr-1  |     await self.app(scope, receive,