paddleocr 2.8.1 paddlepaddle-gpu 2.6.1 占用大量显存并且只增不减,很快cuda oom
🔎 Search before asking
- [X] I have searched the PaddleOCR Docs and found no similar bug report.
- [X] I have searched the PaddleOCR Issues and found no similar bug report.
- [X] I have searched the PaddleOCR Discussions and found no similar bug report.
🐛 Bug (问题描述)
你好,我们原本是使用paddleocr==2.7.0.3 paddlepaddle-gpu==2.5.2.post117,一切都正常,最近我们升级到paddleocr 2.8.1 paddlepaddle-gpu 2.6.1 (cuda 11.8),但是现在很快cuda OOM。看log是推理占用大量显存并且只增不减从不释放。(我们已经用了paddle.device.cuda.empty_cache() - 非常奇怪,相同的batchsize设置,以前基本上模型只需要占用2-3G的显存,现在很快就16-24G,甚至放到显存更大的机器直接上到40+G。
请问可能是什么有问题?除了退回原先版本之外还有别的释放显存方法吗?
🏃♂️ Environment (运行环境)
当前
OS: linux ubuntu 22.04
paddleocr 2.8.1
paddlepaddle-gpu 2.6.1
cuda 11.8
cudnn 8.9.6
python 3.12
之前运行正常时候
OS: linux ubuntu 20.04
paddleocr: 2.7.0.3
paddlepaddle-gpu 2.5.2.post117
cuda 11.7
cudnn 8.5.0
python 3.10
🌰 Minimal Reproducible Example (最小可复现问题的Demo)
目前很难提供,但是只有我们遇到了这样的问题吗?
换paddle3.0 beta 1试试
CUDNN版本问题。有的CUDNN版本有内存泄漏漏洞。cuda 11.8 建议cudnn版本使用-8.9.7.29。 本人商业库封装库长达半年稳定运行。
奇怪,似乎是2.8.1的问题,我退到paddleocr 2.7.3就没有这个显存泄漏的问题了
奇怪,似乎是2.8.1的问题,我退到paddleocr 2.7.3就没有这个显存泄漏的问题了
!!!感恩!!!好像是这样,我也尝试降级了下,这个问题好像确实解决了。
2.7.3在仅检测的方法实现上,有个语法BUG,我看2.8.1解决了,就升了个版本。因为自己正好上了不少新Feature,我还以为OOM是负载变大暴露出来的问题。(要不是看到你的评论,我都忘了还有这个变量)QAQ
补充下现象,方便排查:
- 不是每次预测都会导致显存分配量增加(大概是每次收到比之前更大的图像时,会触发一次新的显存分配,这仅是我的观察)
- 泄露发生在,新的显存分配后,此前分配的显存并没有释放。(empty_cache对此情况没有作用)
我这用2.8.1的,内存也是只增不减,一直崩溃
目前测下来发现两个点:
- 2.7.3的rec_batch_size参数不生效,改成多少实际上都是1,在本地测试样本上占用显存1.7G
- 2.8.x~2.9.0的rec_batch_size 是生效的,默认配置是6,在同样的样本上测试,显存占用7G,rec_batch_size 改成1后,显存占用2.6G
比较直观的能感受出,在不调整rec_batch_size 的情况下,仅从2.7.3切换到2.8+的版本,显存占用涨了4倍以上,实际上修改rec_batch_size 为1后,显存占用上涨50%左右,虽然单batch的情况显存占用涨的不是特别多,但是对小显存设备十分不友好,还是希望能够查清楚原因
我解决了,之前安装的是paddle 2.6.0-post 117 后面换成了最新的paddle 3.0.0 b2 cu118版本的(我的显卡驱动最高支持到12.1 paddle官方还有个cu123的 那个没试过) 然后之前的现象是 我解析一批pdf shape 各不相同 最大长边应该在2000左右 ,然后我的检测最长边设置的是min 736 ,但是理论上说2000左右的最长边 最大显存开销应该不大,但是很奇怪 ,在推理了好几个不同的pdf后 显存涨到了15个 g左右, 然后我换了paddle3.0.0 b2版本后 先保持min 736不变 然后讲一张4000×4000的图拿进去推理 经过det与rec 观测到显存来到4g左右 ,接下来我根据2.6.0版本paddle 的预测过程一样,推理了相同的几个pdf ,这个时候显存再也没有超过4个g左右了(因为他们的分辨率都比4000×4000低)。 最后我还做了个实验,当你的ocr是服务的时候(就像我一样 用fastapi 进行算法部署),最好设置最大长边resize 参数为max 具体值根据你显存决定,因为你不知道用户上传的图片分辨率有多大,设置个上限保证显存不会因为图片太大而oom,我测试下来 max设置为2048 在批量推理很多图与pdf后,显存始终在2320左右,再也不会增加或变化了,希望对你有帮助
还有你们说的 rec batch的问题 我似乎没遇到 paddle3.0.0 b2 cu118
这个貌似是paddle的问题,我试了的2.9.1,也是显存在不停的涨直到oom,paddle 升级到3.0.0,就没有了
奇怪,似乎是2.8.1的问题,我退到paddleocr 2.7.3就没有这个显存泄漏的问题了
!!!感恩!!!好像是这样,我也尝试降级了下,这个问题好像确实解决了。
2.7.3在仅检测的方法实现上,有个语法BUG,我看2.8.1解决了,就升了个版本。因为自己正好上了不少新Feature,我还以为OOM是负载变大暴露出来的问题。(要不是看到你的评论,我都忘了还有这个变量)QAQ
老哥能说下2.7.3仅检测的语法bug是什么吗,我现在因为显存占用的原因只能用2.7.3版本,而且也需要用到仅检测的功能
奇怪,似乎是2.8.1的问题,我退到paddleocr 2.7.3就没有这个显存泄漏的问题了
!!!感恩!!!好像是这样,我也尝试降级了下,这个问题好像确实解决了。 2.7.3在仅检测的方法实现上,有个语法BUG,我看2.8.1解决了,就升了个版本。因为自己正好上了不少新Feature,我还以为OOM是负载变大暴露出来的问题。(要不是看到你的评论,我都忘了还有这个变量)QAQ
老哥能说下2.7.3仅检测的语法bug是什么吗,我现在因为显存占用的原因只能用2.7.3版本,而且也需要用到仅检测的功能
才看到(;′⌒`)
dt_boxes是numpy.ndarray对象时候不能用not语法
if not dt_boxes => if dt_boxes is None
https://github.com/PaddlePaddle/PaddleOCR/blob/5e22578a96d2e7dae091375e3385b073a6fece62/paddleocr.py#L692-L693
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我解决了,之前安装的是paddle 2.6.0-post 117 后面换成了最新的paddle 3.0.0 b2 cu118版本的(我的显卡驱动最高支持到12.1 paddle官方还有个cu123的 那个没试过) 然后之前的现象是 我解析一批pdf shape 各不相同 最大长边应该在2000左右 ,然后我的检测最长边设置的是min 736 ,但是理论上说2000左右的最长边 最大显存开销应该不大,但是很奇怪 ,在推理了好几个不同的pdf后 显存涨到了15个 g左右, 然后我换了paddle3.0.0 b2版本后 先保持min 736不变 然后讲一张4000×4000的图拿进去推理 经过det与rec 观测到显存来到4g左右 ,接下来我根据2.6.0版本paddle 的预测过程一样,推理了相同的几个pdf ,这个时候显存再也没有超过4个g左右了(因为他们的分辨率都比4000×4000低)。 最后我还做了个实验,当你的ocr是服务的时候(就像我一样 用fastapi 进行算法部署),最好设置最大长边resize 参数为max 具体值根据你显存决定,因为你不知道用户上传的图片分辨率有多大,设置个上限保证显存不会因为图片太大而oom,我测试下来 max设置为2048 在批量推理很多图与pdf后,显存始终在2320左右,再也不会增加或变化了,希望对你有帮助
还有你们说的 rec batch的问题 我似乎没遇到 paddle3.0.0 b2 cu118
哥,你的paddleocr是什么版本?解决问题后,稳定运行了多久啊?
(1)paddleocr=2.8.1、paddlepaddle-gpu=2.6.1,显存一直增长。 (2)paddleocr=2.7.3、paddlepaddle-gpu=2.6.1,显存一直增长。 (3)paddleocr=2.8.1、paddlepaddle-gpu=3.0.0b2,显存一直增长,但是增长幅度较小,每次增长0.1~0.14G左右,已经跑了2天,显存增长了2.5G左右,还在继续观察。另外,我开了一个服务,里面把ocr部分关掉,显存稳定了,不会增长,已经运行半天,还在继续观察。 (4)接下来尝试一下,paddleocr=2.7.3、paddlepaddle-gpu=3.0.0b2,希望能解决问题吧。。。。
我这用2.8.1的,内存也是只增不减,一直崩溃
现在解决了吗?
@ShawnALiu 你的ocr检测设置里,图片的大小上线设置的是多少,目前我的paddle版本是3.0.0b2,有部分显存增长是正常的,理论上跟paddleocr版本是无关的,跟paddlepaddle核心有关,给你举个例子再说下 paddleocr默认的是max 960 也就是说超过960分辨率的图片会resize到960进行推理 (当然如果你设置的是min,那么随着推理图片大小的变化,显存肯定是会慢慢往上涨的,并且输入足够大的图后会直接oom,并且oom后这部分显存不会释放出来),我设置的是2048(为了适应某些输入分辨率较大的图片,如果默认是960,本来原图就大,resize后目标就更小了,所以设置的是2048),当我输入图片一开始是1000分辨率左右的时候显存会增加(显存会初始化一部分,然后第一次推理进来会增加,这个时候输入一部分低于1000分辨率的图显存不变),然后我输入超过2048分辨率的图片后,显存也会增加(因为图片超过了1000分辨率,超过的部分显存会继续cache增加),当我继续输入图片并且图片分辨率超过2048后显存不会再增加了(因为设置了max,无论多大都会resize到2048,并且输入低于2048分辨率的图也不会造成显存增加了),目前是比较稳定的,这也跟深度学习的推理原理是吻合的,只要设置了上限,不管你图片有多大有多小,显存应该都是稳定不变的了,只要你输入有一次超过了你设置max上限后, 显存就会cache这部分的size,理论上不会再增加了,你可以再多测测。
@ShawnALiu 你的ocr检测设置里,图片的大小上线设置的是多少,目前我的paddle版本是3.0.0b2,有部分显存增长是正常的,理论上跟paddleocr版本是无关的,跟paddlepaddle核心有关,给你举个例子再说下 paddleocr默认的是max 960 也就是说超过960分辨率的图片会resize到960进行推理 (当然如果你设置的是min,那么随着推理图片大小的变化,显存肯定是会慢慢往上涨的,并且输入足够大的图后会直接oom,并且oom后这部分显存不会释放出来),我设置的是2048(为了适应某些输入分辨率较大的图片,如果默认是960,本来原图就大,resize后目标就更小了,所以设置的是2048),当我输入图片一开始是1000分辨率左右的时候显存会增加(显存会初始化一部分,然后第一次推理进来会增加,这个时候输入一部分低于1000分辨率的图显存不变),然后我输入超过2048分辨率的图片后,显存也会增加(因为图片超过了1000分辨率,超过的部分显存会继续cache增加),当我继续输入图片并且图片分辨率超过2048后显存不会再增加了(因为设置了max,无论多大都会resize到2048,并且输入低于2048分辨率的图也不会造成显存增加了),目前是比较稳定的,这也跟深度学习的推理原理是吻合的,只要设置了上限,不管你图片有多大有多小,显存应该都是稳定不变的了,只要你输入有一次超过了你设置max上限后, 显存就会cache这部分的size,理论上不会再增加了,你可以再多测测。
谢谢你举得例子,是符合认知的,我的使用场景比较复杂,我开了n个进程,每个进程里初始化了1个paddleocr。
以下是我的初始化方式:
PAD_OCR = PaddleOCR(det_model_dir=det_model_dir,
rec_model_dir=rec_model_dir,
cls_model_dir=cls_model_dir,
det_limit_side_len=det_limit_side_len,
show_log=False,
use_gpu=True)
其中 det_limit_side_len当前设置为960,可以作为配置项,自行调整。由于参考文档里det_limit_type默认为max,因此我并没有在初始化时设置。
以下是我的使用方式: lines = pad_ocr.ocr(img_rgb, det=True, rec=True, cls=False)
目前运行2天,每过几个小时,显存会有0.1~0.15左右的增长,还不知道会不会增长到一定程度就稳定,现在已经9小时没有增长可,算是好消息吧。
奇怪,似乎是2.8.1的问题,我退到paddleocr 2.7.3就没有这个显存泄漏的问题了
!!!感恩!!!好像是这样,我也尝试降级了下,这个问题好像确实解决了。 2.7.3在仅检测的方法实现上,有个语法BUG,我看2.8.1解决了,就升了个版本。因为自己正好上了不少新Feature,我还以为OOM是负载变大暴露出来的问题。(要不是看到你的评论,我都忘了还有这个变量)QAQ
老哥能说下2.7.3仅检测的语法bug是什么吗,我现在因为显存占用的原因只能用2.7.3版本,而且也需要用到仅检测的功能
才看到(;′⌒`)
dt_boxes是numpy.ndarray对象时候不能用not语法if not dt_boxes=>if dt_boxes is Nonehttps://github.com/PaddlePaddle/PaddleOCR/blob/5e22578a96d2e7dae091375e3385b073a6fece62/paddleocr.py#L692-L693
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我这边用的时候继承了ocr方法,这个地方我已经改成 if dt_boxes is None了,今天看官方的main分支,好像又改成了if dt_boxes.size == 0了,这个有必要同步成这种形式吗?
@ShawnALiu 不知道你的多进程是如何实现的,我是用的gunicorn 搭配uvicorn实现的多进程,原生的uvicorn对于进程管理方式有点问题,会导致paddle导入的时候初始化出现问题,用gunicorn就不会有这个问题,你的增长有可能是每个进程处理图片不一样导致的呢,应该是当每个进程都接收了超过max 960的图片后 所有的总显存是不会再变化才对,因为这个确实不太好debug,只能长时间监控,对了,为了适配更多的国产化设备,我们已经考虑还是用pytorch来进行推理,具体的paddle的代码还得重构为torch,paddle的兼容性还是不太好,torch好多了,不管是进程管理,显存分配,推理线程安全性等等问题。
你的增长有可能是每个进程处理图片不一样导致的呢,应该是当每个进程都接收了超过max 960的图片后 所有的总显存是不会再变化才对
是的,为了验证这个,我重新起了1个服务,只开1个进程,去处理图片,看看最终显存变化。
我也遇到了此类的情况,请问目前除了更改版本外有其他的解决方式吗
我也遇到了此类的情况,请问目前除了更改版本外有其他的解决方式吗
我的还是会爆显存,没有解决问题
大佬们,我的问题是在训练det server模型时eval的过程中显存OOM,我用Tesla T4(16GB) eval到第1张就oom了,用Tesla A10 (24GB) eval到大概10几张图的时候就OOM了。 不知道大家有没有遇到过? 我用的是paddlepaddle 2.6/3.0.0b1, paddleocr 2.7 (源码), cuda 11.8, cudnn 8.9.7.29, windows 10, python 3.11
我基于Paddle2.6.1自己编译的推理库,PaddleOCR基于2.4版本改编版本,GPU运行稳定。无内存泄漏。基于3000张图片连续测试,内存稳定在2.8G。显存稳定在1.8~2.0G。https://gitee.com/raoyutian/PaddleOCRSharp 基于C++版本自行改编优化,速度快,稳定运行。
我基于Paddle2.6.1自己编译的推理库,PaddleOCR基于2.4版本改编版本,GPU运行稳定。无内存泄漏。基于3000张图片连续测试,内存稳定在2.8G。显存稳定在1.8~2.0G。https://gitee.com/raoyutian/PaddleOCRSharp 基于C++版本自行改编优化,速度快,稳定运行。
注意看README.md,多数是付费版,看好再花时间去调试
我基于Paddle2.6.1自己编译的推理库,PaddleOCR基于2.4版本改编版本,GPU运行稳定。无内存泄漏。基于3000张图片连续测试,内存稳定在2.8G。显存稳定在1.8~2.0G。https://gitee.com/raoyutian/PaddleOCRSharp 基于C++版本自行改编优化,速度快,稳定运行。
注意看README.md,多数是付费版,看好再花时间去调试 我话本意是,我都能优化显存泄漏问题,飞桨官方也能优化,说明显存泄漏是可以解决的。我的库能长达一年左右的在客户中稳定运行,说明显存泄漏问题是根本上解决了的。
我这边升级使用了最新的paddlepaddle/paddle:3.0.0-gpu-cuda11.8-cudnn8.9-trt8.6 还是会OOM