我正在开发一个 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进程消耗的内存正在慢慢增加。
使用给定的平面列表: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 认为这不是以下任何内容的重复