diff --git a/src/MaaCore/Config/Miscellaneous/OcrPack.cpp b/src/MaaCore/Config/Miscellaneous/OcrPack.cpp index 25352c2698..e6cf727e76 100644 --- a/src/MaaCore/Config/Miscellaneous/OcrPack.cpp +++ b/src/MaaCore/Config/Miscellaneous/OcrPack.cpp @@ -34,41 +34,50 @@ bool asst::OcrPack::load(const std::filesystem::path& path) auto& paddle_dir = path; - fastdeploy::RuntimeOption option; - option.UseOrtBackend(); + fastdeploy::RuntimeOption det_option; + det_option.UseOrtBackend(); + bool build_det = false; + + fastdeploy::RuntimeOption rec_option; + rec_option.UseOrtBackend(); + std::string rec_label; + bool build_rec = false; do { using namespace asst::utils::path_literals; const auto det_dir = paddle_dir / "det"_p; - const auto dst_model_file = det_dir / "inference.onnx"_p; - // const auto dst_params_file = det_dir / "inference.pdiparams"_p; + const auto det_model_file = det_dir / "inference.onnx"_p; const auto rec_dir = paddle_dir / "rec"_p; const auto rec_model_file = rec_dir / "inference.onnx"_p; - // const auto rec_params_file = rec_dir / "inference.pdiparams"_p; const auto rec_label_file = rec_dir / "keys.txt"_p; - if (std::filesystem::exists(dst_model_file)) { - auto det_model = asst::utils::read_file(dst_model_file); - option.SetModelBuffer(det_model.data(), det_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX); - m_det = std::make_unique("dummy.onnx", std::string(), option, - fastdeploy::ModelFormat::ONNX); + // fastdeploy 同时加载两个实例有可能会炸,不知道为啥,加个锁 + static std::mutex load_mutex; + + if (std::filesystem::exists(det_model_file)) { + auto det_model = asst::utils::read_file(det_model_file); + det_option.SetModelBuffer(det_model.data(), det_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX); + build_det = true; } - else if (!m_det) { - break; - } - // else 沿用原来的模型 if (std::filesystem::exists(rec_model_file) && std::filesystem::exists(rec_label_file)) { auto rec_model = asst::utils::read_file(rec_model_file); - auto label = asst::utils::read_file(rec_label_file); - option.SetModelBuffer(rec_model.data(), rec_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX); - m_rec = std::make_unique("dummy.onnx", std::string(), label, option, + rec_label = asst::utils::read_file(rec_label_file); + rec_option.SetModelBuffer(rec_model.data(), rec_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX); + build_rec = true; + } + + if (build_det) { + std::unique_lock lock(load_mutex); + m_det = std::make_unique("dummy.onnx", std::string(), det_option, fastdeploy::ModelFormat::ONNX); } - else if (!m_rec) { - break; + + if (build_rec) { + std::unique_lock lock(load_mutex); + m_rec = std::make_unique("dummy.onnx", std::string(), rec_label, + rec_option, fastdeploy::ModelFormat::ONNX); } - // else 沿用原来的模型 if (m_det && m_rec) { m_ocr = std::make_unique(m_det.get(), m_rec.get()); diff --git a/src/MaaCore/Config/ResourceLoader.cpp b/src/MaaCore/Config/ResourceLoader.cpp index 399b07a6c9..457f9acfcf 100644 --- a/src/MaaCore/Config/ResourceLoader.cpp +++ b/src/MaaCore/Config/ResourceLoader.cpp @@ -57,34 +57,34 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) LogTraceFunction; using namespace asst::utils::path_literals; - auto config_future = std::async(std::launch::async, [&]() -> bool { - /* load resource with json files*/ - LoadResourceAndCheckRet(GeneralConfig, "config.json"_p); - LoadResourceAndCheckRet(RecruitConfig, "recruitment.json"_p); - LoadResourceAndCheckRet(StageDropsConfig, "stages.json"_p); - LoadResourceAndCheckRet(RoguelikeCopilotConfig, "roguelike"_p / "copilot.json"_p); - LoadResourceAndCheckRet(RoguelikeRecruitConfig, "roguelike"_p / "recruitment.json"_p); - LoadResourceAndCheckRet(RoguelikeShoppingConfig, "roguelike"_p / "shopping.json"_p); - LoadResourceAndCheckRet(BattleDataConfig, "battle_data.json"_p); - LoadResourceAndCheckRet(OcrConfig, "ocr_config.json"_p); - - /* load resource with json and template files*/ - LoadResourceWithTemplAndCheckRet(TaskData, "tasks.json"_p, "template"_p); - LoadResourceWithTemplAndCheckRet(InfrastConfig, "infrast.json"_p, "template"_p / "infrast"_p); - LoadResourceWithTemplAndCheckRet(ItemConfig, "item_index.json"_p, "template"_p / "items"_p); - /* load cache */ - LoadCacheWithoutRet(AvatarCacheManager, "avatars"_p); - + auto word_ocr_future = std::async(std::launch::async, [&]() -> bool { + LoadResourceAndCheckRet(WordOcr, "PaddleOCR"_p); return true; }); - auto ocr_future = std::async(std::launch::async, [&]() -> bool { - // fastdeploy 不知道有啥问题,没法异步加载两个模型,改成同步算了 - LoadResourceAndCheckRet(WordOcr, "PaddleOCR"_p); + auto char_ocr_future = std::async(std::launch::async, [&]() -> bool { LoadResourceAndCheckRet(CharOcr, "PaddleCharOCR"_p); return true; }); + /* load resource with json files*/ + LoadResourceAndCheckRet(GeneralConfig, "config.json"_p); + LoadResourceAndCheckRet(RecruitConfig, "recruitment.json"_p); + LoadResourceAndCheckRet(StageDropsConfig, "stages.json"_p); + LoadResourceAndCheckRet(RoguelikeCopilotConfig, "roguelike"_p / "copilot.json"_p); + LoadResourceAndCheckRet(RoguelikeRecruitConfig, "roguelike"_p / "recruitment.json"_p); + LoadResourceAndCheckRet(RoguelikeShoppingConfig, "roguelike"_p / "shopping.json"_p); + LoadResourceAndCheckRet(BattleDataConfig, "battle_data.json"_p); + LoadResourceAndCheckRet(OcrConfig, "ocr_config.json"_p); + + /* load resource with json and template files*/ + LoadResourceWithTemplAndCheckRet(TaskData, "tasks.json"_p, "template"_p); + LoadResourceWithTemplAndCheckRet(InfrastConfig, "infrast.json"_p, "template"_p / "infrast"_p); + LoadResourceWithTemplAndCheckRet(ItemConfig, "item_index.json"_p, "template"_p / "items"_p); + + /* load cache */ + LoadCacheWithoutRet(AvatarCacheManager, "avatars"_p); + /*** lazy loading ***/ // 战斗中技能识别,二分类模型 LoadResourceAndCheckRet(OnnxSessions, "onnx"_p / "skill_ready_cls.onnx"_p); @@ -92,6 +92,7 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) LoadResourceAndCheckRet(OnnxSessions, "onnx"_p / "deploy_direction_cls.onnx"_p); // 战斗中干员(血条)检测,yolov8 检测模型 LoadResourceAndCheckRet(OnnxSessions, "onnx"_p / "operators_det.onnx"_p); + /* tiles info */ LoadResourceAndCheckRet(TilePack, "Arknights-Tile-Pos"_p); @@ -100,8 +101,8 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) #undef LoadCacheWithoutRet m_loaded = true; - m_loaded &= config_future.get(); - m_loaded &= ocr_future.get(); + m_loaded &= word_ocr_future.get(); + m_loaded &= char_ocr_future.get(); return m_loaded; }