@@ -82,6 +82,14 @@ std::string GraphExport::getDraftModelDirectoryPath(const std::string& directory
8282 std::string fullPath = FileSystem::joinPath ({directoryPath, GraphExport::getDraftModelDirectoryName (draftModel)});
8383 return fullPath;
8484}
85+ #define GET_PLUGIN_CONFIG_OPT_OR_FAIL_AND_RETURN (PLUGIN_SETTINGS_IMPL, EXPORT_SETTINGS ) \
86+ auto pluginConfigOrStatus = GraphExport::createPluginString(PLUGIN_SETTINGS_IMPL, EXPORT_SETTINGS); \
87+ if (std::holds_alternative<Status>(pluginConfigOrStatus)) { \
88+ auto status = std::get<Status>(pluginConfigOrStatus); \
89+ SPDLOG_ERROR (" Failed to create plugin config: {}" , status.string ()); \
90+ return status; \
91+ } \
92+ auto pluginConfigOpt = std::get<std::optional<std::string>>(pluginConfigOrStatus)
8593
8694static Status createTextGenerationGraphTemplate (const std::string& directoryPath, const HFSettingsImpl& hfSettings) {
8795 if (!std::holds_alternative<TextGenGraphSettingsImpl>(hfSettings.graphSettings )) {
@@ -96,12 +104,7 @@ static Status createTextGenerationGraphTemplate(const std::string& directoryPath
96104 oss << OVMS_VERSION_GRAPH_LINE;
97105 std::string modelsPath = constructModelsPath (graphSettings.modelPath , ggufFilename);
98106 SPDLOG_TRACE (" modelsPath: {}, directoryPath: {}, ggufFilename: {}" , modelsPath, directoryPath, ggufFilename.value_or (" std::nullopt" ));
99- auto pluginConfigOrStatus = GraphExport::createPluginString (graphSettings.pluginConfig , exportSettings);
100- if (std::holds_alternative<Status>(pluginConfigOrStatus)) {
101- auto status = std::get<Status>(pluginConfigOrStatus);
102- SPDLOG_ERROR (" Failed to create plugin config: {}" , status.string ());
103- return status;
104- }
107+ GET_PLUGIN_CONFIG_OPT_OR_FAIL_AND_RETURN (graphSettings.pluginConfig , exportSettings);
105108 // clang-format off
106109 oss << R"(
107110 input_stream: "HTTP_REQUEST_PAYLOAD:input"
@@ -126,9 +129,13 @@ static Status createTextGenerationGraphTemplate(const std::string& directoryPath
126129 << graphSettings.targetDevice << R"( ",
127130 models_path: ")"
128131 << modelsPath << R"( ",
129- plugin_config: ')"
130- << std::get<std::string>(pluginConfigOrStatus) << R"( ',
131- enable_prefix_caching: )"
132+ )" ;
133+ if (pluginConfigOpt.has_value ()) {
134+ oss << R"( plugin_config: ')"
135+ << pluginConfigOpt.value () << R"( ',
136+ )" ;
137+ }
138+ oss << R"( enable_prefix_caching: )"
132139 << graphSettings.enablePrefixCaching << R"( ,
133140 cache_size: )"
134141 << graphSettings.cacheSize << R"( ,)" ;
@@ -204,12 +211,7 @@ static Status createRerankGraphTemplate(const std::string& directoryPath, const
204211 // Windows path creation - graph parser needs forward slashes in paths
205212 std::string modelsPath = constructModelsPath (graphSettings.modelPath , ggufFilename);
206213 SPDLOG_TRACE (" modelsPath: {}, directoryPath: {}, ggufFilename: {}" , modelsPath, directoryPath, ggufFilename.value_or (" std::nullopt" ));
207- auto pluginConfigOrStatus = GraphExport::createPluginString (graphSettings.pluginConfig , exportSettings);
208- if (std::holds_alternative<Status>(pluginConfigOrStatus)) {
209- auto status = std::get<Status>(pluginConfigOrStatus);
210- SPDLOG_ERROR (" Failed to create plugin config: {}" , status.string ());
211- return status;
212- }
214+ GET_PLUGIN_CONFIG_OPT_OR_FAIL_AND_RETURN (graphSettings.pluginConfig , exportSettings);
213215 // clang-format off
214216 oss << R"(
215217input_stream: "REQUEST_PAYLOAD:input"
@@ -228,7 +230,11 @@ node {
228230 max_allowed_chunks: )"
229231 << graphSettings.maxAllowedChunks << R"( ,
230232 target_device: ")" << graphSettings.targetDevice << R"( ",
231- plugin_config: ')" << std::get<std::string>(pluginConfigOrStatus) << R"( ',
233+ )" ;
234+ if (pluginConfigOpt.has_value ()) {
235+ oss << R"( plugin_config: ')" << pluginConfigOpt.value () << R"( ',)" ;
236+ }
237+ oss << R"(
232238 }
233239 }
234240})" ;
@@ -259,12 +265,7 @@ static Status createEmbeddingsGraphTemplate(const std::string& directoryPath, co
259265 oss << OVMS_VERSION_GRAPH_LINE;
260266 std::string modelsPath = constructModelsPath (graphSettings.modelPath , ggufFilename);
261267 SPDLOG_TRACE (" modelsPath: {}, directoryPath: {}, ggufFilename: {}" , modelsPath, directoryPath, ggufFilename.value_or (" std::nullopt" ));
262- auto pluginConfigOrStatus = GraphExport::createPluginString (graphSettings.pluginConfig , exportSettings);
263- if (std::holds_alternative<Status>(pluginConfigOrStatus)) {
264- auto status = std::get<Status>(pluginConfigOrStatus);
265- SPDLOG_ERROR (" Failed to create plugin config: {}" , status.string ());
266- return status;
267- }
268+ GET_PLUGIN_CONFIG_OPT_OR_FAIL_AND_RETURN (graphSettings.pluginConfig , exportSettings);
268269 // clang-format off
269270 oss << R"(
270271input_stream: "REQUEST_PAYLOAD:input"
@@ -287,8 +288,12 @@ node {
287288 pooling: )"
288289 << graphSettings.pooling << R"( ,
289290 target_device: ")" << graphSettings.targetDevice << R"( ",
290- plugin_config: ')" << std::get<std::string>(pluginConfigOrStatus) << R"( ',
291- }
291+ )" ;
292+ if (pluginConfigOpt.has_value ()) {
293+ oss << R"( plugin_config: ')" << pluginConfigOpt.value () << R"( ',
294+ )" ;
295+ }
296+ oss << R"( }
292297 }
293298})" ;
294299
@@ -315,13 +320,7 @@ static Status createImageGenerationGraphTemplate(const std::string& directoryPat
315320 auto & ggufFilename = hfSettings.ggufFilename ;
316321 std::string modelsPath = constructModelsPath (graphSettings.modelPath , ggufFilename);
317322 SPDLOG_TRACE (" modelsPath: {}, directoryPath: {}, ggufFilename: {}" , modelsPath, directoryPath, ggufFilename.value_or (" std::nullopt" ));
318- auto pluginConfigOrStatus = GraphExport::createPluginString (graphSettings.pluginConfig , exportSettings);
319- if (std::holds_alternative<Status>(pluginConfigOrStatus)) {
320- auto status = std::get<Status>(pluginConfigOrStatus);
321- SPDLOG_ERROR (" Failed to create plugin config: {}" , status.string ());
322- return status;
323- }
324- const std::string pluginConfig = std::get<std::string>(pluginConfigOrStatus);
323+ GET_PLUGIN_CONFIG_OPT_OR_FAIL_AND_RETURN (graphSettings.pluginConfig , exportSettings);
325324
326325 std::ostringstream oss;
327326 oss << OVMS_VERSION_GRAPH_LINE;
@@ -340,10 +339,9 @@ node: {
340339 [type.googleapis.com / mediapipe.ImageGenCalculatorOptions]: {
341340 models_path: ")" << graphSettings.modelPath << R"( "
342341 device: ")" << graphSettings.targetDevice << R"( ")" ;
343- // TODO by default our utility generates empty plugin config which may differ in behavior to nto setting it at all
344- if (pluginConfig.size () > 4 ) {
342+ if (pluginConfigOpt.has_value ()) {
345343 oss << R"(
346- plugin_config: ')" << std::get<std::string>(pluginConfigOrStatus ) << R"( ')" ;
344+ plugin_config: ')" << pluginConfigOpt. value ( ) << R"( ')" ;
347345 }
348346
349347 if (graphSettings.resolution .size ()) {
@@ -436,7 +434,7 @@ Status GraphExport::createServableConfig(const std::string& directoryPath, const
436434 return StatusCode::INTERNAL_ERROR;
437435}
438436
439- std::variant<std::string, Status> GraphExport::createPluginString (const PluginConfigSettingsImpl& pluginConfig, const ExportSettings& exportSettings) {
437+ std::variant<std::optional<std:: string> , Status> GraphExport::createPluginString (const PluginConfigSettingsImpl& pluginConfig, const ExportSettings& exportSettings) {
440438 auto & stringPluginConfig = exportSettings.pluginConfig ;
441439 rapidjson::Document d;
442440 d.SetObject ();
@@ -446,7 +444,6 @@ std::variant<std::string, Status> GraphExport::createPluginString(const PluginCo
446444 }
447445 }
448446 bool configNotEmpty = false ;
449-
450447 if (pluginConfig.kvCachePrecision .has_value ()) {
451448 rapidjson::Value name;
452449 name.SetString (pluginConfig.kvCachePrecision .value ().c_str (), d.GetAllocator ());
@@ -457,7 +454,6 @@ std::variant<std::string, Status> GraphExport::createPluginString(const PluginCo
457454 d.AddMember (" KV_CACHE_PRECISION" , name, d.GetAllocator ());
458455 configNotEmpty = true ;
459456 }
460-
461457 if (pluginConfig.maxPromptLength .has_value ()) {
462458 rapidjson::Value value;
463459 value.SetUint (pluginConfig.maxPromptLength .value ());
@@ -468,7 +464,6 @@ std::variant<std::string, Status> GraphExport::createPluginString(const PluginCo
468464 d.AddMember (" MAX_PROMPT_LEN" , value, d.GetAllocator ());
469465 configNotEmpty = true ;
470466 }
471-
472467 if (pluginConfig.modelDistributionPolicy .has_value ()) {
473468 rapidjson::Value value;
474469 value.SetString (pluginConfig.modelDistributionPolicy .value ().c_str (), d.GetAllocator ());
@@ -479,6 +474,16 @@ std::variant<std::string, Status> GraphExport::createPluginString(const PluginCo
479474 d.AddMember (" MODEL_DISTRIBUTION_POLICY" , value, d.GetAllocator ());
480475 configNotEmpty = true ;
481476 }
477+ if (pluginConfig.numStreams .has_value ()) {
478+ rapidjson::Value value;
479+ value.SetUint (pluginConfig.numStreams .value ());
480+ auto itr = d.FindMember (" NUM_STREAMS" );
481+ if (itr != d.MemberEnd ()) {
482+ return Status (StatusCode::PLUGIN_CONFIG_CONFLICTING_PARAMETERS, " Doubled NUM_STREAMS parameter in plugin config." );
483+ }
484+ d.AddMember (" NUM_STREAMS" , value, d.GetAllocator ());
485+ configNotEmpty = true ;
486+ }
482487 if (exportSettings.cacheDir .has_value ()) {
483488 rapidjson::Value value;
484489 value.SetString (exportSettings.cacheDir .value ().c_str (), d.GetAllocator ());
@@ -489,20 +494,17 @@ std::variant<std::string, Status> GraphExport::createPluginString(const PluginCo
489494 d.AddMember (" CACHE_DIR" , value, d.GetAllocator ());
490495 configNotEmpty = true ;
491496 }
492-
493- std::string pluginString = " { }" ;
494-
495497 if (configNotEmpty) {
496498 // Serialize the document to a JSON string
497499 rapidjson::StringBuffer buffer;
498500 rapidjson::Writer<rapidjson::StringBuffer> writer (buffer);
499501 d.Accept (writer);
500502
501503 // Output the JSON string
502- pluginString = buffer.GetString ();
504+ return buffer.GetString ();
505+ } else {
506+ return std::nullopt ;
503507 }
504-
505- return pluginString;
506508}
507509
508510} // namespace ovms
0 commit comments