PaddleHub icon indicating copy to clipboard operation
PaddleHub copied to clipboard

hub Out of memory in a simple programm!!

Open LeeYongchao opened this issue 4 years ago • 56 comments

  • 版本、环境信息 1)hub.version'1.7.1' 2)paddle.version'1.7.2' 3)ubuntu16.04
  1. cuda10 5)paddle.fluid.install_check.run_check() Running Verify Paddle Program ... W0610 10:19:19.803442 8827 device_context.cc:237] Please NOTE: device: 0, CUDA Capability: 75, Driver API Version: 10.1, Runtime API Version: 9.0 W0610 10:19:19.805452 8827 device_context.cc:245] device: 0, cuDNN Version: 7.6. Your Paddle works well on SINGLE GPU or CPU. I0610 10:19:20.703788 8827 parallel_executor.cc:440] The Program will be executed on CUDA using ParallelExecutor, 1 cards are used, so 1 programs are executed in parallel. I0610 10:19:20.704022 8827 build_strategy.cc:365] SeqOnlyAllReduceOps:0, num_trainers:1 I0610 10:19:20.704203 8827 parallel_executor.cc:307] Inplace strategy is enabled, when build_strategy.enable_inplace = True I0610 10:19:20.704339 8827 parallel_executor.cc:375] Garbage collection strategy is enabled, when FLAGS_eager_delete_tensor_gb = 0 Your Paddle works well on MUTIPLE GPU or CPU. Your Paddle is installed successfully! Let's start deep Learning with Paddle now

  • 我的显存有6G,如果您的显存很大,请多放图片,会看到 显存一直增长 不回收
  • 代码很简单,如下: 首先 export CUDA_VISIBLE_DEVICES=0 import os import paddlehub as hub ocr = hub.Module(name="chinese_ocr_db_crnn_server") img_l=os.listdir('./static/images/') # 本目录有20张带文字的图片,如果您显存大,请多放 for img in img_l: _ = ocr.recognize_text(paths=['./static/images/'+img], use_gpu=True)

报错如下:

Error Message Summary:

ResourceExhaustedError:

Out of memory error on GPU 0. Cannot allocate 29.883057MB memory on GPU 0, available memory is only 22.750000MB.

Please check whether there is any other process using GPU 0.

  1. If yes, please stop them, or start PaddlePaddle on another GPU.
  2. If no, please decrease the batch size of your model.

at (/paddle/paddle/fluid/memory/allocation/cuda_allocator.cc:69)

LeeYongchao avatar Jun 10 '20 02:06 LeeYongchao

你好!建议直接将所有图片使用cv2读入之后,一次性传给预测接口recognize_text(使用参数images) 如:

import os

import cv2
import paddlehub as hub

test_images = 'Path/To/Images'
ocr = hub.Module(name="chinese_ocr_db_crnn_server")
imgs = [cv2.imread(image) for image in test_images]
ocr.recognize_text(images=[imgs], use_gpu=True)

Steffy-zxf avatar Jun 12 '20 02:06 Steffy-zxf

你好!建议直接将所有图片使用cv2读入之后,一次性传给预测接口recognize_text(使用参数images) 如:

import os

import cv2
import paddlehub as hub

test_images = 'Path/To/Images'
ocr = hub.Module(name="chinese_ocr_db_crnn_server")
imgs = [cv2.imread(image) for image in test_images]
ocr.recognize_text(images=[imgs], use_gpu=True)

这个方法 行不通,因为在实际中hub是这样用的:

第一步:hub serving start -m chinese_ocr_db_crnn_server

第二步:请求结果:

import requests import json import cv2 import base64 def cv2_to_base64(image): data = cv2.imencode('.jpg', image)[1] return base64.b64encode(data.tostring()).decode('utf8') 发送HTTP请求 data = {'images':[cv2_to_base64(cv2.imread("/PATH/TO/IMAGE"))]} headers = {"Content-type": "application/json"} url = "http://127.0.0.1:8866/predict/chinese_ocr_db_crnn_server" r = requests.post(url=url, headers=headers, data=json.dumps(data)) 打印预测结果 print(r.json()["results"])

第三步:如果有多个人 依次请求(注意不是并发),一定是不同的图片,不同的名称,才会发生,而且实际情况就是这样,那么次数一多,就会发生!!!

显存不回收!!!!!!!!

LeeYongchao avatar Jun 12 '20 02:06 LeeYongchao

我也有这个问题,麻烦尽快解决下

Bingjiajia avatar Jun 12 '20 02:06 Bingjiajia

你好!建议直接将所有图片使用cv2读入之后,一次性传给预测接口recognize_text(使用参数images) 如:

import os

import cv2
import paddlehub as hub

test_images = 'Path/To/Images'
ocr = hub.Module(name="chinese_ocr_db_crnn_server")
imgs = [cv2.imread(image) for image in test_images]
ocr.recognize_text(images=[imgs], use_gpu=True)

我部署在server上的文字识别模型,也是经常 挂掉,显存报错如下:


C++ Call Stacks (More useful to developers):

0 std::string paddle::platform::GetTraceBackStringstd::string(std::string&&, char const*, int) 1 paddle::memory::allocation::CUDAAllocator::AllocateImpl(unsigned long) 2 paddle::memory::allocation::AlignedAllocator::AllocateImpl(unsigned long) 3 paddle::memory::allocation::AutoGrowthBestFitAllocator::AllocateImpl(unsigned long) 4 paddle::memory::allocation::Allocator::Allocate(unsigned long) 5 paddle::memory::allocation::RetryAllocator::AllocateImpl(unsigned long) 6 paddle::memory::allocation::AllocatorFacade::Alloc(paddle::platform::Place const&, unsigned long) 7 paddle::memory::allocation::AllocatorFacade::AllocShared(paddle::platform::Place const&, unsigned long) 8 paddle::memory::AllocShared(paddle::platform::Place const&, unsigned long) 9 paddle::framework::Tensor::mutable_data(paddle::platform::Place const&, paddle::framework::proto::VarType_Type, unsigned long) 10 paddle::operators::BatchNormKernel<paddle::platform::CUDADeviceContext, float>::Compute(paddle::framework::ExecutionContext const&) const 11 std::_Function_handler<void (paddle::framework::ExecutionContext const&), paddle::framework::OpKernelRegistrarFunctor<paddle::platform::CUDAPlace, false, 0ul, paddle::operators::BatchNormKernel<paddle::platform::CUDADeviceContext, float>, paddle::operators::BatchNormKernel<paddle::platform::CUDADeviceContext, double>, paddle::operators::BatchNormKernel<paddle::platform::CUDADeviceContext, paddle::platform::float16> >::operator()(char const*, char const*, int) const::{lambda(paddle::framework::ExecutionContext const&)#1}>::_M_invoke(std::_Any_data const&, paddle::framework::ExecutionContext const&) 12 paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&, paddle::framework::RuntimeContext*) const 13 paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&) const 14 paddle::framework::OperatorBase::Run(paddle::framework::Scope const&, paddle::platform::Place const&) 15 paddle::framework::NaiveExecutor::Run() 16 paddle::AnalysisPredictor::ZeroCopyRun()


Error Message Summary:

ResourceExhaustedError:

Out of memory error on GPU 0. Cannot allocate 56.250244MB memory on GPU 0, available memory is only 54.750000MB.

Please check whether there is any other process using GPU 0.

  1. If yes, please stop them, or start PaddlePaddle on another GPU.
  2. If no, please decrease the batch size of your model.

at (/paddle/paddle/fluid/memory/allocation/cuda_allocator.cc:69)

2020-06-12 10:11:47,800-INFO: 127.0.0.1 - - [12/Jun/2020 10:11:47] "POST /predict/chinese_ocr_db_crnn_server HTTP/1.1" 200 -

moruifang0508 avatar Jun 12 '20 02:06 moruifang0508

@LeeYongchao @Bingjiajia @moruifang0508 感谢反馈!请问你们有试过不使用hub serving,本地调用ocr模型预测,是否会出现显存不足的情况呢?如果出现显存不足的情况,方便将待预测图片发下吗?

Steffy-zxf avatar Jun 12 '20 03:06 Steffy-zxf

您好,我使用paddleOCR项目中的代码去推理是没有问题的,但是我如果使用hub的话,采用如下代码: 首先导入环境变量:export CUDA_VISIBLE_DEVICES=0 然后运行如下代码: import os, time import paddlehub as hub ocr = hub.Module(name="chinese_ocr_db_crnn_server") img_l=os.listdir('./static/images/') # 本目录有20张带文字的图片,如果您显存大,请多放 for img in img_l: _ = ocr.recognize_text(paths=['./static/images/'+img], use_gpu=True) time.sleep(3)

这里使用循环,每次推理一张图片,就是为了测试他的显存是否回收,然后您观察后台的显存,会发现他一直增长,不降低; 具体来讲,如果在循环中,本张图片比上一张图片需要的显存小,他就不增长,如果本张图片比上一张大,那么肯定会增长,只要是增长了,就不会降下来了,这本身应该是不正常的 循环结束后,显存最终的大小就是您图片中最大的那一个。 如果您的显存很大,可能不会挂,但是他不回收。

可以看到,计算过去了很长时间了,显存一直被占用。 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 430.09 Driver Version: 430.09 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 166... Off | 00000000:01:00.0 Off | N/A | | N/A 42C P8 1W / N/A | 5939MiB / 5944MiB | 0% Default | +-------------------------------+----------------------+----------------------+

LeeYongchao avatar Jun 12 '20 05:06 LeeYongchao

@LeeYongchao 循环使用recognize_text接口预测,每次预测一张图片,发现显存在增长。这种情况是符合预期的,因为program在运行的时候会逐渐判断需要多少显存,逐渐分配显存。所以可以看到显存先逐渐增长,之后会稳定。只有当所有图片预测完毕,也就是说当加载的ocr module不再使用,垃圾回收后,此时显存会回收。

Steffy-zxf avatar Jun 12 '20 06:06 Steffy-zxf

@LeeYongchao 循环使用recognize_text接口预测,每次预测一张图片,发现显存在增长。这种情况是符合预期的,因为program在运行的时候会逐渐判断需要多少显存,逐渐分配显存。所以可以看到显存先逐渐增长,之后会稳定。只有当所有图片预测完毕,也就是说当加载的ocr module不再使用,垃圾回收后,此时显存会回收。

不好意思,刚才代码copy错误了。。。

请用下面的测试: 命令行:export CUDA_VISIBLE_DEVICES=0 命令行:hub serving start chinese_ocr_db_crnn_server

然后运行下面脚本:

import requests import json import cv2 import base64

def cv2_to_base64(image): data = cv2.imencode('.jpg', image)[1] return base64.b64encode(data.tostring()).decode('utf8') imgs_l=os.listdir('./static/images/') # 里面很多图片

for img in imgs_l: data = {'images': [cv2_to_base64(cv2.imread("./static/images/"+i))]} headers = {"Content-type": "application/json"} url = "http://127.0.0.1:8866/predict/chinese_ocr_db_crnn_server" r = requests.post(url=url, headers=headers, data=json.dumps(data)) print(r.json()["results"])

脚本运行后,显存还是那么大(5个G的样子),永远不下降。 只有把 hub serving start chinese_ocr_db_crnn_server 这个命令杀死后,显存才归零。

LeeYongchao avatar Jun 12 '20 08:06 LeeYongchao

@LeeYongchao 你使用serving部署module预测。当你的请求结束,只能说明客服端预测完成,但是服务端的进程还在运行,也就是说加载的ocr module没有消亡,自然还会继续占用显存。你可以试试hub stop --help命令 终止服务端进程,这样显存就会释放回收。

Steffy-zxf avatar Jun 12 '20 08:06 Steffy-zxf

@LeeYongchao 你使用serving部署module预测。当你的请求结束,只能说明客服端预测完成,但是服务端的进程还在运行,也就是说加载的ocr module没有消亡,自然还会继续占用显存。你可以试试hub stop --help命令 终止服务端进程,这样显存就会释放回收。

您好: 这个服务器端现在是无人职守的,不可能每次手动清理显存,他这样占显存,别的程序也用不了,造成了很大的浪费。不知道有没有什么办法可以清理显存呢?

hub stop --help 和 hub --help 的结果是一样的 没有清理显存这个内容,hub clear 也试过啦,也不是清理显存的命令。

百忙之中,请帮我问问相关人士,谢谢!!!

LeeYongchao avatar Jun 12 '20 11:06 LeeYongchao

@LeeYongchao 你使用serving部署module预测。当你的请求结束,只能说明客服端预测完成,但是服务端的进程还在运行,也就是说加载的ocr module没有消亡,自然还会继续占用显存。你可以试试hub stop --help命令 终止服务端进程,这样显存就会释放回收。

请问hub的后端是paddlepadlde吗?那么使用paddlepaddle的接口可以清理显存吗? 我好像也是这种情况哦~ 不过我的显存 很大,倒是不用担心~

moruifang0508 avatar Jun 12 '20 11:06 moruifang0508

我的也是,显存不大,碰到大点的直接就卡死了,提问了但是现在找不到提问的帖子了,只能来这里蹭热度了,请解决一下呗,不然这个放服务器上是不可能了,只能自己玩

y455471846b avatar Jun 15 '20 01:06 y455471846b

@LeeYongchao @y455471846b 你好!

你的数据量是多大呢? 我试了一张49KB的图片,chinese_ocr_db_crnn_server模型显存占用大概4000MB。你说的

脚本运行后,显存还是那么大(5个G的样子),永远不下降。

5G的显存占用,是否有别的进程也在使用同一张显卡呢?

另外如果你的显存不足够大,可以试试 轻量级ocr模型chinese_ocr_db_crnn_mobile

Steffy-zxf avatar Jun 15 '20 02:06 Steffy-zxf

@moruifang0508 你好!paddlehub 是 基于paddle开发的,底层深度学习常用的算子是使用paddle提供的API。清理显存使用,待程序完整使用结束后,会自动释放。

Steffy-zxf avatar Jun 15 '20 02:06 Steffy-zxf

@LeeYongchao @y455471846b 你好!

你的数据量是多大呢? 我试了一张49KB的图片,chinese_ocr_db_crnn_server模型显存占用大概4000MB。你说的

脚本运行后,显存还是那么大(5个G的样子),永远不下降。

5G的显存占用,是否有别的进程也在使用同一张显卡呢?

另外如果你的显存不足够大,可以试试 轻量级ocr模型chinese_ocr_db_crnn_mobile

您好,问题的关键 并不在显存大小,而是hub servering 起来以后,别人给他发送请求后,他的显存不会自己清理的。你必须 ctrl + C 结束这个东西 显存才释放。

如果放任不管,他一张图片推理占用4G ,然后返回请求的结果,然后显存就永远不会动了。 而正常情况 应该是 返回请求的结果后,显存应该下降才对。

LeeYongchao avatar Jun 16 '20 02:06 LeeYongchao

我的也是,显存不大,碰到大点的直接就卡死了,提问了但是现在找不到提问的帖子了,只能来这里蹭热度了,请解决一下呗,不然这个放服务器上是不可能了,只能自己玩

是的,大家都是这个问题!!! hub servering 起来,模型上显卡,占用大概500M 别人请求一下,显存占用4G,返回请求结果, 然后显存不下降。。。。。

LeeYongchao avatar Jun 16 '20 02:06 LeeYongchao

@LeeYongchao @y455471846b @moruifang0508 感谢反馈!目前预测模式是进程所有线程复用共享内存池,只有等待进程完整结束后显存和内存才会回收释放。输入图片预测完毕需要释放显存内存这个需求已经反馈!预计paddle下个版本会支持。敬请期待。

Steffy-zxf avatar Jun 16 '20 05:06 Steffy-zxf

@LeeYongchao @y455471846b @moruifang0508 感谢反馈!目前预测模式是进程所有线程复用共享内存池,只有等待进程完整结束后显存和内存才会回收释放。输入图片预测完毕需要释放显存内存这个需求已经反馈!预计paddle下个版本会支持。敬请期待。

您好,请问显存不回收这个问题在paddle 2.0.0b0这个版本解决了吗?我在版本更新日志中没看到关于这个问题的相关说明,麻烦您解答一下~

FD-Liekkas avatar Oct 14 '20 08:10 FD-Liekkas

目前还没有,预计在paddle 2.0正式版本中解决。

Steffy-zxf avatar Oct 15 '20 02:10 Steffy-zxf

请问paddle2.0.0rc解决这个问题了吗

w-Bro avatar Nov 03 '20 06:11 w-Bro

安卓移动版,也存在内存泄露的问题

milkliker avatar Nov 04 '20 02:11 milkliker

请问下现在解决了吗?是哪个版本的paddle解决了?

cuiyong127 avatar Dec 24 '20 07:12 cuiyong127

在 chinese_ocr_db_crnn_server 1.1.1 (paddlepaddle-gpu==2.0.0rc1.post110) 上测试还未解决。

liweigu avatar Jan 11 '21 11:01 liweigu

现在解决了吗?怎么解决的?

cuiyong127 avatar Feb 01 '21 11:02 cuiyong127

好像还没解决。 https://github.com/PaddlePaddle/PaddleHub/issues/1212

liweigu avatar Feb 02 '21 06:02 liweigu

怎么解决啊

YAwei666 avatar Feb 18 '21 03:02 YAwei666

@LeeYongchao @y455471846b @moruifang0508 感谢反馈!目前预测模式是进程所有线程复用共享内存池,只有等待进程完整结束后显存和内存才会回收释放。输入图片预测完毕需要释放显存内存这个需求已经反馈!预计paddle下个版本会支持。敬请期待。

@Steffy-zxf 请问paddlepaddle 2.0.0版本中增加这个功能了么?是哪个参数呢,非常感谢

BurrowsWang avatar Mar 10 '21 02:03 BurrowsWang

@LeeYongchao @y455471846b @moruifang0508 感谢反馈!目前预测模式是进程所有线程复用共享内存池,只有等待进程完整结束后显存和内存才会回收释放。输入图片预测完毕需要释放显存内存这个需求已经反馈!预计paddle下个版本会支持。敬请期待。

@Steffy-zxf 请问paddlepaddle 2.0.0版本中增加这个功能了么?是哪个参数呢,非常感谢

好像还没支持,我用的2.0版本,还是有这个问题。

shch1210 avatar Mar 10 '21 03:03 shch1210

我用的2.0版本的,还是这个问题,hub serving

zhuangyuyang avatar Mar 11 '21 08:03 zhuangyuyang

粗暴的解决方法就是,定时重启程序~~

cuiyuan605 avatar Mar 12 '21 03:03 cuiyuan605