8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如果使用 tf.lite.interpreter,循环中会发生内存泄漏

keithjgrant 2月前

37 0

我正在开发一个 FastAPI 项目,该项目接受带有模型名称和数据的请求。这些数据经过标准路径:(预处理、模型处理、后处理)。解释器...

我正在开发一个 FastAPI 项目,该项目接受带有模型名称和数据的请求。这些数据经过标准路径:(预处理、模型处理、后处理)。每个模型的解释器都存储在字典中,以便再次调用该模型。

由于这些型号数量较多(超过 500 种),占用的 RAM 量接近 3 GB。

我想尝试减少 RAM 消耗,并尝试删除 tf.lite.interpreter 保存,但这导致了内存泄漏。据我了解,这是因为 tf.lite.interpreter 每次创建实例时都会在内存中存储一​​些数据。

我想知道是否可以在处理后删除 tf.lite.interpreter 创建的所有数据。以减少 RAM 消耗。还是假设 tf.lite.interpreter 是为模型创建的,并在运行过程中不断存储?有没有办法在使用模型后释放内存?我的方法有意义吗?

提前感谢您的帮助。我刚刚开始使用 ML。

一开始我用memory_profiler分析了内存。它显示内存是在使用tf.lite.Interpreter()的行上分配的

之后我创建了一个小脚本用于测试。

from time import perf_counter, sleep
import tensorflow as tf
import psutil
import logging
from logging.handlers import RotatingFileHandler


PATH = ...


rotating_handler = RotatingFileHandler(
    filename='logs/memory_leak.log', 
    mode='a+', 
    maxBytes=int(20e6),
    backupCount=10, 
    encoding='utf-8'
)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
rotating_handler.setFormatter(formatter)
root_logger = logging.getLogger()
root_logger.setLevel(logging.WARNING)
root_logger.addHandler(rotating_handler)

def create_interpreter(path:str):
    with tf.device('/CPU:0'):
        timer_start: float = perf_counter()
        interpreter = tf.lite.Interpreter(model_path=path)
        interpreter.allocate_tensors()
        create_time = perf_counter() - timer_start
        print(f'ID interpreter: {id(interpreter)}')
        print(f'Time: {create_time}')
        process = psutil.Process()
        mem_info = process.memory_info()
        logging.warning(f'Memory usage: RSS={mem_info.rss / 1024 ** 2:.2f} MB, VMS={mem_info.vms / 1024 ** 2:.2f} MB')
        return interpreter

while True:
    some_interpreter = create_interpreter(path=PATH)
    some_interpreter.allocate_tensors()
    sleep(5)
    del some_interpreter

我知道del删除唯一的链接但是我认为之后python GC会清除内存。根据该脚本的日志,python进程消耗的内存正在慢慢增加。

帖子版权声明 1、本帖标题:如果使用 tf.lite.interpreter,循环中会发生内存泄漏
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由keithjgrant在本站《tensorflow》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 使用给定的平面列表:let list = [ { key: 1, parent: null, }, { key: 2, parent: 1, }, { key: 3, parent: null, }, { ...

    使用给定的平面 列表

    let list = [
        {
            key: 1,
            parent: null,
        },
        {
            key: 2,
            parent: 1,
        },
        {
            key: 3,
            parent: null,
        },
        {
            key: 4,
            parent: 1,
        },
        {
            key: 5,
            parent: 2,
        }
    ]
    

    如何创建像下面这样的嵌套对象?

    let nest = {
        children: [
            {
                key: 1,
                children: [
                    {
                        key: 2,
                        children: [
                            {
                                key: 5,
                                children: []
                            }
                        ]
                    },
                    {
                        key: 4,
                        children: []
                    }
                ]
            },
            {
                key: 3,
                children: []
            }
        ]
    }
    

    我不知道该如何解决这个问题。我想到的解决方案是必须反复遍历列表,以检查对象的父对象是否为空(在这种情况下,它将被分配为顶级对象),或者对象的父对象已经存在(在这种情况下,我们获取父对象的路径,并将子对象分配给该父对象)。

    PSI 认为这不是以下任何内容的重复

    • 将检查平面物体中是否存在键。
    • 并没有显示任何可以返回路径的内容。
返回
作者最近主题: