有没有了解 paddleocr 的 V 友,我用 Flask 写了个简易 API,内存占用会越来越大, 4~6 个小时就把机器 64GB 内存占满了,只能用 cron 每小时重启,是内存泄露的问题吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
drymonfidelia
V2EX    Python

有没有了解 paddleocr 的 V 友,我用 Flask 写了个简易 API,内存占用会越来越大, 4~6 个小时就把机器 64GB 内存占满了,只能用 cron 每小时重启,是内存泄露的问题吗

  •  
  •   drymonfidelia 2024-04-06 21:38:15 +08:00 4886 次点击
    这是一个创建于 599 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是我的代码,因为我平时 python 写得少,不熟练,如果代码质量差请别喷

    import json, re import uuid from urllib.parse import quote, unquote import yaml import os, urllib.request import time from flask import Flask, config, render_template, request, redirect, make_response from paddleocr import PaddleOCR, draw_ocr ocr = PaddleOCR(use_angle_cls=True, lang='en') app = Flask(__name__) @app.route('/ocr', methods=['GET']) def do_ocr(): if request.method == 'GET': data = request.args if 'url' in data: url = unquote(data['url']) else: return "" tmp_path = f"/dev/shm/{uuid.uuid4()}" urllib.request.urlretrieve(url, tmp_path) result = ocr.ocr(tmp_path, cls=True) data = "" for recr in result: rec = recr[1][0].upper() data += rec + "," os.remove(tmp_path) return data.strip(",") if __name__ == '__main__': app.run() 

    ocrapi.py 是从别处复制来的猴子补丁(不然好像并发会有问题)

    from gevent import monkey, pywsgi monkey.patch_all() from app import app 

    用了 supervisor 启动:

    [program:ocrapi] command=gunicorn --workers 6 --worker-class=gevent --worker-cOnnections=50 -b 0.0.0.0:8080 ocrapi:app directory=/opt/ocrapi/ user=root autorestart=true redirect_stderr=true stdout_logfile=/var/log/ocrapi.log loglevel=info 

    服务启动时内存占用在 2GB 左右,随后越来越大

    另外想问下如果只是用于识别包装盒上的产品序列号(大写英文数字组成,位数固定,手机拍照的,白底黑字/黑底白字都有可能)有效果更好的方案吗?

    28 条回复    2024-07-19 11:01:33 +08:00
    ggvm
        1
    ggvm  
       2024-04-06 21:49:07 +08:00
    查一下具体的内存是被什么东西占用了?

    估计是模型被多次加载,但从来不释放?
    Puteulanus
        2
    Puteulanus  
       2024-04-06 21:51:07 +08:00
    ocr = PaddleOCR(use_angle_cls=True, lang='en')
    这个要是放 do_ocr 里面呢

    我之前看别人另一个识别的用的 https://cnocr.readthedocs.io/zh/latest/usage/
    drymonfidelia
        3
    drymonfidelia  
    OP
       2024-04-06 21:54:36 +08:00
    @Puteulanus 如果是这个要放进去的原因,为什么放外面反而会被多次加载?放外面不是更应该不会被多次加载么?
    Puteulanus
        4
    Puteulanus  
       2024-04-06 22:09:54 +08:00
    @drymonfidelia 我的意思是既然感觉 PaddleOCR 有问题,就别维持它的全局对象了,没有引用看垃圾回收能不能收了它
    est
        5
    est  
       2024-04-06 22:11:56 +08:00
    @drymonfidelia 可能是 ocr 对象维持了一些历史记录。你扫一次内存就占着不释放了。
    ClericPy
        6
    ClericPy  
       2024-04-06 22:20:48 +08:00
    如果对这个库不了解, 可以在子进程里初始化它, 子进程销毁的时候就清理了. 不过估计会慢... 优化的地方很多
    drymonfidelia
        7
    drymonfidelia &nbp;
    OP
       2024-04-06 22:25:14 +08:00
    @Puteulanus 但是每次 ocr 都加载一次模型感觉会很慢
    kaneg
        8
    kaneg  
       2024-04-06 22:37:36 +08:00 via iPhone
    /dev/shm/这个是在内存的,会不会文件没有删掉,滞留在内存了
    drymonfidelia
        9
    drymonfidelia  
    OP
       2024-04-06 22:39:56 +08:00
    @kaneg 我看 top 是 gunicorn 这个进程占的内存
    drymonfidelia
        10
    drymonfidelia  
    OP
       2024-04-06 22:41:53 +08:00
    @kaneg 不过你提醒我了 /dev/shm/ 确实堆了 10GB 的图没删掉,不知道为什么,不过影响不大
    GlobalNPC
        11
    GlobalNPC  
       2024-04-06 22:54:10 +08:00
    @drymonfidelia 怎么会影响不大。。。这里应该用 with 自动管理
    drymonfidelia
        12
    drymonfidelia  
    OP
       2024-04-06 22:55:19 +08:00
    @infun with 能实现代码块结束自动删除文件么
    kuanat
        13
    kuanat  
       2024-04-06 23:10:10 +08:00
    paddleocr 内存分配管理有问题是个很长时间的问题了。我印象官方 github 有几个 issues 就是讨论这个的,而且跨了多个版本,你可以去查一下。

    之前有说是因为框架缓存的原因,有人说不是。我之前遇到这个问题也是通过重启来解决,尝试读了一下 c++ 代码部分还是太复杂了,没有解决的精力和能力。
    GlobalNPC
        14
    GlobalNPC  
       2024-04-06 23:16:29 +08:00
    bringyou
        15
    bringyou  
       2024-04-06 23:18:12 +08:00
    如#13 所言,paddle OCR 的内存占用是个老问题,可以看 issue
    https://github.com/PaddlePaddle/PaddleOCR/discussions/6977
    bringyou
        16
    bringyou  
       2024-04-06 23:18:56 +08:00
    也可以手动调用 try_shrink_memory 来释放内存
    ON9
        17
    ON9  
       2024-04-06 23:48:58 +08:00 via Android
    一定要用猴子吗,用 fastapi 呢
    NoOneNoBody
        18
    NoOneNoBody  
       2024-04-07 01:19:46 +08:00
    python 多进程会将全局环境复制到每个子进程
    flask 我不清楚要怎么做,最好使用 cache 而不是全局变量,然后每个子进程调用时从 cache 懒加载读取
    Eished
        19
    Eished  
       2024-04-07 01:21:29 +08:00
    我也是 Flask+paddleocr ,用的 CPU 版本,1G 内存,都是小图片,大概半年才会内存满了重启一次
    founddev
        20
    founddev  
       2024-04-07 09:23:18 +08:00
    可以尝试 paddleocr 转 onnx 用 PyTorch ,TF 或者 tensorrt 这种比较成熟的框架,尽量不要使用受众很小的这种框架,有 bug 都不一样会改
    clemente
        21
    clemente  
       2024-04-07 22:52:55 +08:00
    不要用 paddle 百度都快放弃了
    CHchenkeyi
        22
    CHchenkeyi  
       2024-04-09 15:15:38 +08:00
    至少代码没看出来由啥问题
    CHchenkeyi
        23
    CHchenkeyi  
       2024-04-09 15:16:35 +08:00
    做了很多飞桨的,基本上有问题就是 版本问题,要么更新 paddle 版本,要么更新 ocr 版本。很玄学
    drymonfidelia
        24
    drymonfidelia  
    OP
       2024-07-18 17:41:05 +08:00 via iPhone
    @CHchenkeyi 更新了最新版更离谱了,运行半分钟 100%用完内存
    so1n
        25
    so1n  
       2024-07-18 19:48:47 +08:00
    遇到内存溢出问题,都是用 gunicorn 的 max_requests
    yinmin
        26
    yinmin  
       2024-07-18 23:51:29 +08:00
    @drymonfidelia 25 楼是正解。gunicorn 加参数 --max-requests 1000 试试
    (每个 worker 接收到 1000 次请求后就重启一个新的)

    你自己测试一下 max-requests 用 500 、1000 、5000 、10000 哪个更优化。
    mMartin
        27
    mMartin  
       2024-07-19 10:57:52 +08:00
    把 OCR 单独封装个单例试试 paddleOCR 我至少在十个生产环境用 还真没遇到内存泄露
    mMartin
        28
    mMartin  
       2024-07-19 11:01:33 +08:00
    要么就把 OCR 单独封装一个服务 RPC 调用 我检测分割分类和 OCR 经常一起用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3252 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 11:32 PVG 19:32 LAX 03:32 JFK 06:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86