Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重复刷新模型造成的内存泄露问题 #2511

Open
Algabeno opened this issue Aug 26, 2024 · 4 comments
Open

重复刷新模型造成的内存泄露问题 #2511

Algabeno opened this issue Aug 26, 2024 · 4 comments
Assignees

Comments

@Algabeno
Copy link


温馨提示:根据社区不完全统计,按照模板提问,可以加快回复和解决问题的速度


环境

【FastDeploy版本】: deploy自己编译
【编译命令】export ENABLE_ORT_BACKEND = OFF
export ENABLE_PADDLE_BACKEND = OFF
export ENABLE_OPENVINO_BACKEND = OFF
export ENABLE_VISION = ON
export ENABLE_TEXT = OFF
export ENABLE_TRT_BACKEND = OFF
export WITH_GPU = OFF
【系统平台】: Windows 11
【硬件】: 笔记本 intel i7-1260p
【编译语言】:C++

问题日志及出现问题的操作流程

由于工程要求,每次刷新相机之后都需要重新刷新一次AI模型。经过测试发现,如果重复调用多次模型初始化函数,会造成内存泄漏,每隔10s~20s会泄露0.3M。下面是我的初始化函数
bool OcrModel::InitModel(OcrModelConfig& config) {
// 将 GBK 路径转换为 UTF-8 路径
std::string model_dir = config.strNetPath;

// 构建模型文件的路径
std::filesystem::path model_path = std::filesystem::path(model_dir) / "inference.pdmodel";
std::filesystem::path params_path = std::filesystem::path(model_dir) / "inference.pdiparams";
std::filesystem::path config_path = std::filesystem::path(model_dir) / "inference.yaml";

std::string& strError = config.strError;

// 检查文件是否存在
if (!fs::exists(model_path) || !fs::exists(params_path)) {
    config.strError = "Model or parameter file does not exist.";
    return false;
}

// 初始化模型
option.UseCpu();  // 使用 CPU
try {
    model = fastdeploy::vision::ocr::DBDetector(model_path.string(), params_path.string(), option);
}
catch (const std::exception& e) {
    strError = "Failed to create the OCR model: " + std::string(e.what());
    return false;
}

if (!model.Initialized()) {
    strError = "Failed to initialize the OCR model.";
    return false;
}

try {
    model.GetPostprocessor().SetDetDBThresh(config.det_db_thresh);
    model.GetPostprocessor().SetDetDBBoxThresh(config.det_db_box_thresh);
    model.GetPostprocessor().SetDetDBUnclipRatio(config.det_db_unclip_ratio);
}
catch (const std::exception& e) {
    strError = "Failed to set post-processing parameters: " + std::string(e.what());
    return false;
}
return true;

}

@Jiang-Jia-Jun
Copy link
Collaborator

如果你是每一次都要加载模型,建议把加载模型的操作放在子进程里,这样进程结束,占用资源会自动释放

@Algabeno
Copy link
Author

如果你是每一次都要加载模型,建议把加载模型的操作放在子进程里,这样进程结束,占用资源会自动释放

FastDeploy是一个很棒的框架,我在尝试将这个框架应用到真实的生产环境中。如果把加载模型的操作放在子进程会造成不必要的开销和加深算法的复杂度,能否实现在同进程主动释放内存

@github-staff github-staff deleted a comment from Algabeno Aug 27, 2024
@Jiang-Jia-Jun
Copy link
Collaborator

在你的代码里,是会循环调用这一行是吗model = fastdeploy::vision::ocr::DBDetector(model_path.string(), params_path.string(), option);

也许你可以试一下将model的声明也放在一个作用域内,例如

{
  Model model = fastdeploy::xxxxx;
  model = fastdeploy::vision::ocr::DBDetector....
}

测试看下是否可以在出作用域后自动释放

@Algabeno
Copy link
Author

在你的代码里,是会循环调用这一行是吗model = fastdeploy::vision::ocr::DBDetector(model_path.string(), params_path.string(), option);

也许你可以试一下将model的声明也放在一个作用域内,例如

{
  Model model = fastdeploy::xxxxx;
  model = fastdeploy::vision::ocr::DBDetector....
}

测试看下是否可以在出作用域后自动释放

十分感谢您的解答,我的代码会在特定情况下重复调用多次model = fastdeploy::vision::ocr::DBDetector(model_path.string(), params_path.string(), option);。我尝试了将model的声明放在一个作用域内,无法解决内存泄漏的问题。作用域只能释放掉栈对象。而初始化模型的代码似乎存在着一些堆对象没有显式释放,导致在刷新模型时会有些许内存泄漏,这并不利于一个软件的长期运行。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@Algabeno @Jiang-Jia-Jun and others