Skip to content

Commit a75d849

Browse files
rasapaladkalinowskimichalkulakowskidtrawins
authored
Adding graph from model_config (#3094)
* Schema and test Co-authored-by: Damian Kalinowski <damian.kalinowski@intel.com> Co-authored-by: michalkulakowski <Michal.Kulakowski@intel.com> Co-authored-by: Trawinski, Dariusz <dariusz.trawinski@intel.com>
1 parent 35a663b commit a75d849

10 files changed

+307
-76
lines changed

docs/mediapipe.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,30 @@ Here is example of the `subconfig.json`:
157157
### Starting OpenVINO Model Server with Mediapipe servables
158158
MediaPipe servables configuration is to be placed in the same json file like the
159159
[models config file](starting_server.md).
160-
While models are defined in section `model_config_list`, graphs are configured in
161-
the `mediapipe_config_list` section.
160+
Graphs parameters can be defined in section `model_config_list` just like classic models (recommended) or in the section `mediapipe_config_list` which is deprecated now.
162161

163-
When the MediaPipe graphs artifacts are packaged like presented above, configuring the OpenVINO Model Server is very easy. Just a `config.json` needs to be prepared with a list of all the graphs to be deployed:
162+
Here is an example `config.json` file that defines two MediaPipe graphs. One with custom `graph_path` and one default:
163+
```json
164+
{
165+
"model_config_list": [
166+
{
167+
"config": {
168+
"name": "mediapipe_graph_name",
169+
}
170+
},
171+
{
172+
"config": {
173+
"name": "mediapipe_graph_name_for_default_name",
174+
"base_path":"mediapipe_graph_name ",
175+
"graph_path": " graph.pbtxt"
176+
}
177+
}
178+
]
179+
}
180+
```
181+
In case the `mediapipe_graph_name_for_default_name` above, ovms will search for the default graph name `graph.pbtxt` in the `mediapipe_graph_name` directory relative to the `config.json` location.
182+
183+
Graphs can also be configured in the `mediapipe_config_list` section.
164184
```json
165185
{
166186
"model_config_list": [],

src/modelconfig.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,12 @@ Status ModelConfig::parseModelMapping() {
470470
Status ModelConfig::parseNode(const rapidjson::Value& v) {
471471
this->setName(v["name"].GetString());
472472
try {
473-
this->setBasePath(v["base_path"].GetString());
473+
// Check for optional parameters
474+
if (v.HasMember("base_path")) {
475+
this->setBasePath(v["base_path"].GetString());
476+
} else {
477+
this->setBasePath("");
478+
}
474479
} catch (std::logic_error& e) {
475480
SPDLOG_DEBUG("Relative path error: {}", e.what());
476481
return StatusCode::INTERNAL_ERROR;

src/modelmanager.cpp

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -429,25 +429,26 @@ Status ModelManager::processMediapipeConfig(const MediapipeGraphConfig& config,
429429
#if (MEDIAPIPE_DISABLE == 0)
430430
static Status parseMediapipeConfig(rapidjson::Document& configJson, std::string& rootDirectoryPath, std::vector<MediapipeGraphConfig>& mediapipesInConfigFile) {
431431
const auto itrp = configJson.FindMember("mediapipe_config_list");
432-
if (itrp == configJson.MemberEnd() || !itrp->value.IsArray()) {
433-
return StatusCode::OK;
434-
}
435-
try {
436-
for (const auto& mediapipeGraphConfig : itrp->value.GetArray()) {
437-
MediapipeGraphConfig config;
438-
config.setRootDirectoryPath(rootDirectoryPath);
439-
auto status = config.parseNode(mediapipeGraphConfig);
440-
if (status != StatusCode::OK) {
441-
SPDLOG_LOGGER_ERROR(modelmanager_logger, "Parsing graph config failed");
442-
return status;
432+
// Legacy mediapipe_config_list parsing
433+
if (itrp != configJson.MemberEnd() && itrp->value.IsArray()) {
434+
try {
435+
for (const auto& mediapipeGraphConfig : itrp->value.GetArray()) {
436+
MediapipeGraphConfig config;
437+
config.setRootDirectoryPath(rootDirectoryPath);
438+
auto status = config.parseNode(mediapipeGraphConfig);
439+
if (status != StatusCode::OK) {
440+
SPDLOG_LOGGER_ERROR(modelmanager_logger, "Parsing graph config failed");
441+
return status;
442+
}
443+
mediapipesInConfigFile.push_back(config);
443444
}
444-
mediapipesInConfigFile.push_back(config);
445+
} catch (const std::exception& e) {
446+
SPDLOG_ERROR("Failed to process mediapipe graph config:{}", e.what());
447+
} catch (...) {
448+
SPDLOG_ERROR("Failed to process mediapipe graph config.");
445449
}
446-
} catch (const std::exception& e) {
447-
SPDLOG_ERROR("Failed to process mediapipe graph config:{}", e.what());
448-
} catch (...) {
449-
SPDLOG_ERROR("Failed to process mediapipe graph config.");
450450
}
451+
451452
return StatusCode::OK;
452453
}
453454
#endif
@@ -736,10 +737,35 @@ Status ModelManager::loadMetricsConfig(rapidjson::Document& configJson) {
736737
}
737738
}
738739

739-
Status ModelManager::loadModels(const rapidjson::Value::MemberIterator& modelsConfigList, std::vector<ModelConfig>& gatedModelConfigs, std::set<std::string>& modelsInConfigFile, std::set<std::string>& modelsWithInvalidConfig, std::unordered_map<std::string, ModelConfig>& newModelConfigs, const std::string& rootDirectoryPath) {
740+
#if (MEDIAPIPE_DISABLE == 1)
741+
Status ModelManager::loadModels(const rapidjson::Value::MemberIterator& modelsConfigList, std::vector<ModelConfig>& gatedModelConfigs, std::set<std::string>& modelsInConfigFile,
742+
std::set<std::string>& modelsWithInvalidConfig, std::unordered_map<std::string, ModelConfig>& newModelConfigs, const std::string& rootDirectoryPath) {
743+
#else
744+
Status ModelManager::loadModels(const rapidjson::Value::MemberIterator& modelsConfigList, std::vector<ModelConfig>& gatedModelConfigs, std::set<std::string>& modelsInConfigFile,
745+
std::set<std::string>& modelsWithInvalidConfig, std::unordered_map<std::string, ModelConfig>& newModelConfigs, const std::string& rootDirectoryPath,
746+
std::vector<MediapipeGraphConfig>& mediapipesInConfigFile) {
747+
#endif
740748
Status firstErrorStatus = StatusCode::OK;
741749

742750
for (const auto& configs : modelsConfigList->value.GetArray()) {
751+
#if (MEDIAPIPE_DISABLE == 0)
752+
// Check if config is present for mediapipe graph
753+
MediapipeGraphConfig mpConfig;
754+
mpConfig.setRootDirectoryPath(rootDirectoryPath);
755+
auto mpStatus = mpConfig.parseNode(configs["config"]);
756+
if (!mpStatus.ok()) {
757+
SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Parsing : {} config as mediapipe graph failed due to error: {}", mpConfig.getGraphName(), mpStatus.string());
758+
} else {
759+
std::ifstream ifs(mpConfig.getGraphPath());
760+
if (ifs.is_open()) {
761+
SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Adding mediapipe graph config for {}, {}", mpConfig.getGraphName(), mpConfig.getGraphPath());
762+
mediapipesInConfigFile.push_back(mpConfig);
763+
continue;
764+
} else {
765+
SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Graph.pbtxt not found for config {}, {}", mpConfig.getGraphName(), mpConfig.getGraphPath());
766+
}
767+
}
768+
#endif
743769
ModelConfig modelConfig;
744770
modelConfig.setRootDirectoryPath(rootDirectoryPath);
745771
auto status = modelConfig.parseNode(configs["config"]);
@@ -815,13 +841,18 @@ Status ModelManager::loadModelsConfig(rapidjson::Document& configJson, std::vect
815841
std::set<std::string> modelsInConfigFile;
816842
std::set<std::string> modelsWithInvalidConfig;
817843
std::unordered_map<std::string, ModelConfig> newModelConfigs;
844+
#if (MEDIAPIPE_DISABLE == 0)
845+
auto status = loadModels(itr, gatedModelConfigs, modelsInConfigFile, modelsWithInvalidConfig, newModelConfigs, this->rootDirectoryPath, mediapipesInConfigFile);
846+
#else
818847
auto status = loadModels(itr, gatedModelConfigs, modelsInConfigFile, modelsWithInvalidConfig, newModelConfigs, this->rootDirectoryPath);
848+
#endif
819849
if (!status.ok()) {
820850
SPDLOG_LOGGER_ERROR(modelmanager_logger, "Loading main OVMS config models failed.");
821851
IF_ERROR_NOT_OCCURRED_EARLIER_THEN_SET_FIRST_ERROR(status);
822852
}
823853

824854
#if (MEDIAPIPE_DISABLE == 0)
855+
std::vector<MediapipeGraphConfig> subdirectoryMediapipesInConfigFile;
825856
for (auto& mediapipeConfig : mediapipesInConfigFile) {
826857
std::string subconfigPath = mediapipeConfig.getSubconfigPath();
827858
rapidjson::Document mediapipeConfigJson;
@@ -851,7 +882,7 @@ Status ModelManager::loadModelsConfig(rapidjson::Document& configJson, std::vect
851882
}
852883
std::string subconfigRootDirectoryPath;
853884
FileSystem::setRootDirectoryPath(subconfigRootDirectoryPath, subconfigPath);
854-
status = loadModels(mediapipeItr, gatedModelConfigs, modelsInConfigFile, modelsWithInvalidConfig, newModelConfigs, subconfigRootDirectoryPath);
885+
status = loadModels(mediapipeItr, gatedModelConfigs, modelsInConfigFile, modelsWithInvalidConfig, newModelConfigs, subconfigRootDirectoryPath, subdirectoryMediapipesInConfigFile);
855886
if (!status.ok()) {
856887
IF_ERROR_NOT_OCCURRED_EARLIER_THEN_SET_FIRST_ERROR(status);
857888
SPDLOG_LOGGER_ERROR(modelmanager_logger, "Loading Mediapipe {} models from subconfig {} failed.", mediapipeConfig.getGraphName(), subconfigPath);

src/modelmanager.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,14 @@ class ModelManager {
103103
Status cleanupModelTmpFiles(ModelConfig& config);
104104
Status reloadModelVersions(std::shared_ptr<ovms::Model>& model, std::shared_ptr<FileSystem>& fs, ModelConfig& config, std::shared_ptr<model_versions_t>& versionsToReload, std::shared_ptr<model_versions_t>& versionsFailed);
105105
Status addModelVersions(std::shared_ptr<ovms::Model>& model, std::shared_ptr<FileSystem>& fs, ModelConfig& config, std::shared_ptr<model_versions_t>& versionsToStart, std::shared_ptr<model_versions_t>& versionsFailed);
106-
Status loadModels(const rapidjson::Value::MemberIterator& modelsConfigList, std::vector<ModelConfig>& gatedModelConfigs, std::set<std::string>& modelsInConfigFile, std::set<std::string>& modelsWithInvalidConfig, std::unordered_map<std::string, ModelConfig>& newModelConfigs, const std::string& rootDirectoryPath);
106+
107107
#if (MEDIAPIPE_DISABLE == 0)
108+
Status loadModels(const rapidjson::Value::MemberIterator& modelsConfigList, std::vector<ModelConfig>& gatedModelConfigs, std::set<std::string>& modelsInConfigFile, std::set<std::string>& modelsWithInvalidConfig, std::unordered_map<std::string, ModelConfig>& newModelConfigs, const std::string& rootDirectoryPath, std::vector<ovms::MediapipeGraphConfig>& mediapipesInConfigFile);
108109
Status processMediapipeConfig(const MediapipeGraphConfig& config, std::set<std::string>& mediapipesInConfigFile, MediapipeFactory& factory);
109110
Status loadMediapipeGraphsConfig(std::vector<MediapipeGraphConfig>& mediapipesInConfigFile);
110111
Status loadModelsConfig(rapidjson::Document& configJson, std::vector<ModelConfig>& gatedModelConfigs, std::vector<ovms::MediapipeGraphConfig>& mediapipesInConfigFile);
111112
#else
113+
Status loadModels(const rapidjson::Value::MemberIterator& modelsConfigList, std::vector<ModelConfig>& gatedModelConfigs, std::set<std::string>& modelsInConfigFile, std::set<std::string>& modelsWithInvalidConfig, std::unordered_map<std::string, ModelConfig>& newModelConfigs, const std::string& rootDirectoryPath);
112114
Status loadModelsConfig(rapidjson::Document& configJson, std::vector<ModelConfig>& gatedModelConfigs);
113115
#endif
114116
Status tryReloadGatedModelConfigs(std::vector<ModelConfig>& gatedModelConfigs);

src/schema.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ const std::string MODEL_CONFIG_DEFINITION = R"(
181181
"properties": {
182182
"config": {
183183
"type": "object",
184-
"required": ["name", "base_path"],
184+
"required": ["name"],
185185
"properties": {
186186
"name": {
187187
"type": "string"
@@ -193,6 +193,12 @@ const std::string MODEL_CONFIG_DEFINITION = R"(
193193
"type": ["integer", "string"],
194194
"minimum": 0
195195
},
196+
"graph_path": {
197+
"type": "string"
198+
},
199+
"subconfig": {
200+
"type": "string"
201+
},
196202
"model_version_policy": {
197203
"$ref": "#/definitions/model_version_policy"
198204
},
@@ -383,14 +389,14 @@ const std::string MODELS_CONFIG_SCHEMA = R"({
383389
"items": {
384390
"$ref": "#/definitions/pipeline_config"
385391
}
386-
},)" +
392+
},)" +
387393
#if (MEDIAPIPE_DISABLE == 0)
388394
R"("mediapipe_config_list": {
389-
"type": "array",
390-
"items": {
391-
"$ref": "#/definitions/mediapipe_config"
392-
}
393-
},)" +
395+
"type": "array",
396+
"items": {
397+
"$ref": "#/definitions/mediapipe_config"
398+
}
399+
},)" +
394400
#endif
395401
R"("custom_node_library_config_list": {
396402
"type": "array",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"model_config_list": [{"config": {
3+
"name":"graphdummy",
4+
"base_path":"/ovms/src/test/mediapipe/relative_paths/graph_only_name/graphdummy"
5+
}
6+
}]
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"model_config_list": [{"config": {
3+
"name":"graphdummy"
4+
}
5+
}]
6+
}

0 commit comments

Comments
 (0)