PaddlePaddle / FastDeploy

⚡️An Easy-to-use and Fast Deep Learning Model Deployment Toolkit for ☁️Cloud 📱Mobile and 📹Edge. Including Image, Video, Text and Audio 20+ main stream scenarios and 150+ SOTA models with end-to-end optimization, multi-platform and multi-framework support.
https://www.paddlepaddle.org.cn/fastdeploy
Apache License 2.0
2.81k stars 441 forks source link

python 调用fastdeploy返回的result内存无法释放? del result也不行? #2065

Open moyans opened 1 year ago

moyans commented 1 year ago

For deployment of GPU/TensorRT, please refer to examples/vision/detection/paddledetection/python

import cv2 import fastdeploy.vision as vision

im = cv2.imread("000000014439.jpg") model = vision.detection.PPYOLOE("ppyoloe_crn_l_300e_coco/model.pdmodel", "ppyoloe_crn_l_300e_coco/model.pdiparams", "ppyoloe_crn_l_300e_coco/infer_cfg.yml")

result = model.predict(im) print(result)

vis_im = vision.vis_detection(im, result, score_threshold=0.5) cv2.imwrite("vis_image.jpg", vis_im)

ChaoII commented 1 year ago

py 不是应该自动gc的吗?还需要手动释放吗

moyans commented 1 year ago

py 不是应该自动gc的吗?还需要手动释放吗

result的对象是c创建的, py释放不了, 手动也释放不了,,,

ChaoII commented 1 year ago
 .def("predict",
           [](vision::detection::PPDetBase& self, pybind11::array& data) {
             auto mat = PyArrayToCvMat(data);
             vision::DetectionResult res;
             self.Predict(&mat, &res);
             return res;
           })

这样写的也需要手动释放嘛?

moyans commented 1 year ago

环境

import os
import cv2
import fastdeploy as fd
from memory_profiler import profile

class PPOCRv3:
    def __init__(
            self,
            det_model_dir,
            cls_model_dir,
            rec_model_dir,
            rec_label_file,
            cpu_thread_num=9,
            backend="default"
        ) -> None:
        runtime_option = fd.RuntimeOption()
        runtime_option.set_cpu_thread_num(cpu_thread_num)
        cls_batch_size = 1
        rec_batch_size = 6
        det_model_file = os.path.join(det_model_dir, "inference.pdmodel")
        det_params_file = os.path.join(det_model_dir, "inference.pdiparams")
        cls_model_file = os.path.join(cls_model_dir, "inference.pdmodel")
        cls_params_file = os.path.join(cls_model_dir, "inference.pdiparams")
        rec_model_file = os.path.join(rec_model_dir, "inference.pdmodel")
        rec_params_file = os.path.join(rec_model_dir, "inference.pdiparams")
        det_option = runtime_option
        det_option.set_trt_input_shape("x", [1, 3, 64, 64], [1, 3, 640, 640], [1, 3, 960, 960])
        self.det_model = fd.vision.ocr.DBDetector(det_model_file, det_params_file, runtime_option=det_option)
        self.det_model.det_db_unclip_ratio = 2.0

        cls_option = runtime_option
        cls_option.set_trt_input_shape("x", [1, 3, 48, 10], [cls_batch_size, 3, 48, 320], [cls_batch_size, 3, 48, 1024])
        self.cls_model = fd.vision.ocr.Classifier(cls_model_file, cls_params_file, runtime_option=cls_option)

        rec_option = runtime_option
        rec_option.set_trt_input_shape("x", [1, 3, 48, 10], [rec_batch_size, 3, 48, 320], [rec_batch_size, 3, 48, 1024])
        self.rec_model = fd.vision.ocr.Recognizer(rec_model_file, rec_params_file, rec_label_file, runtime_option=rec_option)

        self.ppocr_v3 = fd.vision.ocr.PPOCRv3(det_model=self.det_model, cls_model=self.cls_model, rec_model=self.rec_model)
        self.ppocr_v3.cls_batch_size = cls_batch_size
        self.ppocr_v3.rec_batch_size = rec_batch_size

    @profile
    def run(self, im):
        return self.ppocr_v3.predict(im)

测试代码:

model = PPOCRv3(det_model_dir, cls_model_dir, rec_model_dir, rec_label_file)

    img_dir = r"E:\DataSet\XFUND\images"
    img_list = os.listdir(img_dir)
    for ind, names in enumerate(img_list):
        print(f"loading images %s" % names)
        img_path = os.path.join(img_dir, names)
        assert os.path.exists(img_path), f"{img_path} not found!"
        im = cv2.imread(img_path)
        results = model.run(im)

log日志:

loading images zh_train_0.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53    271.0 MiB    271.0 MiB           1       @profile
    54                                             def run(self, im):
    55   1796.0 MiB   1524.9 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_1.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   1796.0 MiB   1796.0 MiB           1       @profile
    54                                             def run(self, im):
    55   1893.7 MiB     97.8 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_10.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   1893.8 MiB   1893.8 MiB           1       @profile
    54                                             def run(self, im):
    55   1939.6 MiB     45.9 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_100.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   1939.7 MiB   1939.7 MiB           1       @profile
    54                                             def run(self, im):
    55   2020.8 MiB     81.2 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_101.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   2020.8 MiB   2020.8 MiB           1       @profile
    54                                             def run(self, im):
    55   2048.1 MiB     27.3 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_102.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   2048.2 MiB   2048.2 MiB           1       @profile
    54                                             def run(self, im):
    55   2082.3 MiB     34.1 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_103.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   2082.3 MiB   2082.3 MiB           1       @profile
    54                                             def run(self, im):
    55   2115.9 MiB     33.7 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_104.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   2115.9 MiB   2115.9 MiB           1       @profile
    54                                             def run(self, im):
    55   2183.4 MiB     67.5 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_105.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   2183.4 MiB   2183.4 MiB           1       @profile
    54                                             def run(self, im):
    55   2244.3 MiB     60.9 MiB           1           return self.ppocr_v3.predict(im)

loading images zh_train_106.jpg
Filename: D:\Code\test\ppocr.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    53   2244.3 MiB   2244.3 MiB           1       @profile
    54                                             def run(self, im):
    55   2283.3 MiB     38.9 MiB           1           return self.ppocr_v3.predict(im)

result的类型:

type(results)
<class 'fastdeploy.libs.fastdeploy_main.vision.OCRResult'>
jiangjiajun commented 1 year ago

是怎么确认内存的上涨是由result导致的呢? 如果改成如下代码执行测试呢

model = PPOCRv3(det_model_dir, cls_model_dir, rec_model_dir, rec_label_file)
im = cv2.imread("test.jpg")
for i in range(1000):
     results = model.run(im)
moyans commented 1 year ago

是怎么确认内存的上涨是由result导致的呢? 如果改成如下代码执行测试呢

model = PPOCRv3(det_model_dir, cls_model_dir, rec_model_dir, rec_label_file)
im = cv2.imread("test.jpg")
for i in range(1000):
     results = model.run(im)

结果是一样的

代码

    import psutil

    cls_batch_size = 1
    rec_batch_size = 6

    det_model_dir = r"E:\models\PaddleOCR\ch_PP-OCRv3_xx_16.2M\inference_model\ch_PP-OCRv3_det_infer"
    cls_model_dir = r"E:\models\PaddleOCR\ch_PP-OCRv3_xx_16.2M\inference_model\ch_ppocr_mobile_v2.0_cls_infer"
    rec_model_dir = r"E:\models\PaddleOCR\ch_PP-OCRv3_xx_16.2M\inference_model\ch_PP-OCRv3_rec_infer"
    rec_label_file = r"E:\models\PaddleOCR\ch_PP-OCRv3_xx_16.2M\ppocr_keys_v1.txt"

    runtime_option = fd.RuntimeOption()
    runtime_option.set_cpu_thread_num(4)
    det_model_file = os.path.join(det_model_dir, "inference.pdmodel")
    det_params_file = os.path.join(det_model_dir, "inference.pdiparams")
    cls_model_file = os.path.join(cls_model_dir, "inference.pdmodel")
    cls_params_file = os.path.join(cls_model_dir, "inference.pdiparams")
    rec_model_file = os.path.join(rec_model_dir, "inference.pdmodel")
    rec_params_file = os.path.join(rec_model_dir, "inference.pdiparams")

    det_option = runtime_option
    det_option.set_trt_input_shape("x", [1, 3, 64, 64], [1, 3, 640, 640], [1, 3, 960, 960])
    det_model = fd.vision.ocr.DBDetector(det_model_file, det_params_file, runtime_option=det_option)
    det_model.det_db_unclip_ratio = 2.0

    cls_option = runtime_option
    cls_option.set_trt_input_shape("x", [1, 3, 48, 10], [cls_batch_size, 3, 48, 320], [cls_batch_size, 3, 48, 1024])
    cls_model = fd.vision.ocr.Classifier(cls_model_file, cls_params_file, runtime_option=cls_option)

    rec_option = runtime_option
    rec_option.set_trt_input_shape("x", [1, 3, 48, 10], [rec_batch_size, 3, 48, 320], [rec_batch_size, 3, 48, 1024])
    rec_model = fd.vision.ocr.Recognizer(rec_model_file, rec_params_file, rec_label_file, runtime_option=rec_option)

    ppocr_v3 = fd.vision.ocr.PPOCRv3(det_model=det_model, cls_model=cls_model, rec_model=rec_model)
    ppocr_v3.cls_batch_size = cls_batch_size
    ppocr_v3.rec_batch_size = rec_batch_size

    img_dir = r"E:\DataSet\XFUND\images"
    img_list = os.listdir(img_dir)

    for ind, names in enumerate(img_list):
        print(f"loading images %s" % names)
        img_path = os.path.join(img_dir, names)
        assert os.path.exists(img_path), f"{img_path} not found!"
        im = cv2.imread(img_path)
        results = ppocr_v3.predict(im)
        # print(results)
        print(u'当前进程的内存使用:%.4f GB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024 / 1024) )

日志

loading images zh_train_0.jpg
当前进程的内存使用:1.7453 GB
loading images zh_train_1.jpg
当前进程的内存使用:1.8372 GB
loading images zh_train_10.jpg
当前进程的内存使用:1.8802 GB
loading images zh_train_100.jpg
当前进程的内存使用:1.9576 GB
loading images zh_train_101.jpg
当前进程的内存使用:1.9855 GB
loading images zh_train_102.jpg
当前进程的内存使用:2.0161 GB
loading images zh_train_103.jpg
当前进程的内存使用:2.0458 GB
loading images zh_train_104.jpg
当前进程的内存使用:2.1100 GB
loading images zh_train_105.jpg
当前进程的内存使用:2.1664 GB
loading images zh_train_106.jpg
当前进程的内存使用:2.2009 GB
loading images zh_train_107.jpg
当前进程的内存使用:2.2732 GB
loading images zh_train_108.jpg
当前进程的内存使用:2.3153 GB
loading images zh_train_109.jpg
当前进程的内存使用:2.3864 GB
loading images zh_train_11.jpg
当前进程的内存使用:2.4560 GB
loading images zh_train_110.jpg
当前进程的内存使用:2.4539 GB
loading images zh_train_111.jpg
当前进程的内存使用:2.4811 GB
loading images zh_train_112.jpg
当前进程的内存使用:2.5140 GB
loading images zh_train_113.jpg
当前进程的内存使用:2.5694 GB
loading images zh_train_114.jpg
当前进程的内存使用:2.6923 GB
loading images zh_train_115.jpg
当前进程的内存使用:2.7444 GB
loading images zh_train_116.jpg
当前进程的内存使用:2.8663 GB
loading images zh_train_117.jpg
当前进程的内存使用:2.9299 GB
loading images zh_train_118.jpg
当前进程的内存使用:2.9469 GB
loading images zh_train_119.jpg
当前进程的内存使用:3.0413 GB
loading images zh_train_12.jpg
当前进程的内存使用:3.2168 GB
loading images zh_train_120.jpg
当前进程的内存使用:3.2664 GB
loading images zh_train_121.jpg
当前进程的内存使用:3.3288 GB
loading images zh_train_122.jpg
当前进程的内存使用:3.3982 GB
loading images zh_train_123.jpg
当前进程的内存使用:3.3892 GB
loading images zh_train_124.jpg
当前进程的内存使用:3.4554 GB
loading images zh_train_125.jpg
fastislow commented 9 months ago

遇到了同样问题,是否 img 在 predict 内部发生了内存泄漏 @jiangjiajun

youzeFix commented 3 months ago

我这里也是,内存释放不了,一直OOM