如何从内存中删除FastAI模型列表?内存释放失效问题求助
如何彻底释放FastAI模型占用的内存
我正在开发一个测试模块,用于测试内存崩溃前可加载的FastAI模型数量。目前遇到内存占满后无法移除模型的问题,执行remove_all_models后RAM占比没有下降。
原模型加载与释放代码:
import gc from fastai.vision.all import load_learner class ClassificationInference: def __init__(self): self.model_list = [] def load_model(self, model_name: str) -> None: model_file = os.path.join("trained_model", "saved_model", f"{model_name}.pkl") model = load_learner(model_file) self.model_list.append(model) def remove_all_models(self) -> None: for i in range(len(self.model_list)): if i >= len(self.model_list): break del self.model_list[i] del self.model_list self.model_list = None torch.cuda.empty_cache() gc.collect() self.model_list = []
内存测量代码:
max_gpu = torch.cuda.get_device_properties(None).total_memory max_ram = psutil.virtual_memory().total current_gpu = torch.cuda.memory_allocated(None) current_ram = psutil.virtual_memory().used percentage_gpu = (current_gpu / max_gpu) * 100 percentage_ram = (current_ram / max_ram) * 100 print(f"Percentage before start: (RAM: {percentage_ram}, " f"GPU: {percentage_gpu})")
问题根源
- 循环删除逻辑错误:通过索引循环删除列表元素时,删除操作会导致列表长度缩短,后续索引会跳过部分元素,导致部分模型对象未被正确删除。
- 未处理GPU张量引用:FastAI的
Learner加载后默认占用GPU内存,仅删除模型对象无法彻底释放GPU上的张量资源。 - 未清除模型内部引用:
Learner包含数据加载器、优化器等内部组件,这些组件会持有额外内存引用,未清理会导致内存无法释放。
修正后的代码
import gc import torch import os from fastai.vision.all import load_learner import psutil class ClassificationInference: def __init__(self): self.model_list = [] def load_model(self, model_name: str) -> None: model_file = os.path.join("trained_model", "saved_model", f"{model_name}.pkl") model = load_learner(model_file) self.model_list.append(model) def remove_all_models(self) -> None: # 逐个处理每个模型,清除所有关联引用 for model in self.model_list: # 将模型移回CPU,释放GPU张量 if model.dls.device.type == 'cuda': model.to('cpu') # 删除模型参数的GPU引用 for param in model.parameters(): del param # 清除Learner内部组件的引用 del model.dls del model.opt del model.loss_func # 删除模型对象本身 del model # 清空列表并释放列表引用 self.model_list.clear() del self.model_list self.model_list = [] # 强制释放GPU缓存并触发垃圾回收 torch.cuda.empty_cache() # 多次调用gc确保彻底回收未引用对象 gc.collect() gc.collect()
关键步骤说明
- 逐个清理模型:遍历列表中的每个模型,先将其移回CPU,再删除参数、数据加载器等内部组件,确保所有关联内存引用被切断。
- 正确清空列表:使用
clear()清空列表后删除列表对象,避免残留引用。 - 多次垃圾回收:
gc.collect()需要调用多次,确保Python解释器彻底回收所有未引用的对象。 - GPU缓存释放:
torch.cuda.empty_cache()用于释放PyTorch占用的闲置GPU内存。
内存测量优化
psutil.virtual_memory().used包含系统缓存和缓冲区内存,若要查看应用实际占用的RAM,建议改用psutil.virtual_memory().active,该指标更准确反映当前进程的实际内存消耗。
内容的提问来源于stack exchange,提问作者Francisco Ferraz
相关产品推荐
相关产品推荐

