|
@@ -37,10 +37,22 @@ public:
|
|
|
sd_ctx_params_t ctxParams;
|
|
sd_ctx_params_t ctxParams;
|
|
|
sd_ctx_params_init(&ctxParams);
|
|
sd_ctx_params_init(&ctxParams);
|
|
|
|
|
|
|
|
- std::cout << "Loading model: " << modelPath << std::endl;
|
|
|
|
|
|
|
+ // Get absolute path for logging
|
|
|
|
|
+ std::filesystem::path absModelPath = std::filesystem::absolute(modelPath);
|
|
|
|
|
+ std::cout << "Loading model from absolute path: " << absModelPath << std::endl;
|
|
|
|
|
|
|
|
- // Use folder-based path selection instead of architecture detection
|
|
|
|
|
- // This is more reliable and faster than parsing model files
|
|
|
|
|
|
|
+ // Create persistent string copies to fix lifetime issues
|
|
|
|
|
+ // These strings will remain valid for the entire lifetime of the context
|
|
|
|
|
+ std::string persistentModelPath = modelPath;
|
|
|
|
|
+ std::string persistentClipLPath = params.clipLPath;
|
|
|
|
|
+ std::string persistentClipGPath = params.clipGPath;
|
|
|
|
|
+ std::string persistentVaePath = params.vaePath;
|
|
|
|
|
+ std::string persistentTaesdPath = params.taesdPath;
|
|
|
|
|
+ std::string persistentControlNetPath = params.controlNetPath;
|
|
|
|
|
+ std::string persistentLoraModelDir = params.loraModelDir;
|
|
|
|
|
+ std::string persistentEmbeddingDir = params.embeddingDir;
|
|
|
|
|
+
|
|
|
|
|
+ // Use folder-based path selection with enhanced logic
|
|
|
bool useDiffusionModelPath = false;
|
|
bool useDiffusionModelPath = false;
|
|
|
std::string detectionSource = "folder";
|
|
std::string detectionSource = "folder";
|
|
|
|
|
|
|
@@ -48,22 +60,83 @@ public:
|
|
|
std::filesystem::path modelFilePath(modelPath);
|
|
std::filesystem::path modelFilePath(modelPath);
|
|
|
std::filesystem::path parentDir = modelFilePath.parent_path();
|
|
std::filesystem::path parentDir = modelFilePath.parent_path();
|
|
|
std::string parentDirName = parentDir.filename().string();
|
|
std::string parentDirName = parentDir.filename().string();
|
|
|
|
|
+ std::string modelFileName = modelFilePath.filename().string();
|
|
|
|
|
|
|
|
// Convert to lowercase for comparison
|
|
// Convert to lowercase for comparison
|
|
|
std::transform(parentDirName.begin(), parentDirName.end(), parentDirName.begin(), ::tolower);
|
|
std::transform(parentDirName.begin(), parentDirName.end(), parentDirName.begin(), ::tolower);
|
|
|
|
|
+ std::transform(modelFileName.begin(), modelFileName.end(), modelFileName.begin(), ::tolower);
|
|
|
|
|
|
|
|
// Variables for fallback detection
|
|
// Variables for fallback detection
|
|
|
ModelDetectionResult detectionResult;
|
|
ModelDetectionResult detectionResult;
|
|
|
bool detectionSuccessful = false;
|
|
bool detectionSuccessful = false;
|
|
|
|
|
+ bool isQwenModel = false;
|
|
|
|
|
+
|
|
|
|
|
+ // Check if this is a Qwen model based on filename
|
|
|
|
|
+ if (modelFileName.find("qwen") != std::string::npos) {
|
|
|
|
|
+ isQwenModel = true;
|
|
|
|
|
+ std::cout << "Detected Qwen model from filename: " << modelFileName << std::endl;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // Enhanced path selection logic
|
|
|
if (parentDirName == "diffusion_models" || parentDirName == "diffusion") {
|
|
if (parentDirName == "diffusion_models" || parentDirName == "diffusion") {
|
|
|
useDiffusionModelPath = true;
|
|
useDiffusionModelPath = true;
|
|
|
- std::cout << "Model is in diffusion_models directory, using diffusion_model_path" << std::endl;
|
|
|
|
|
|
|
+ std::cout << "Model is in " << parentDirName << " directory, using diffusion_model_path" << std::endl;
|
|
|
} else if (parentDirName == "checkpoints" || parentDirName == "stable-diffusion") {
|
|
} else if (parentDirName == "checkpoints" || parentDirName == "stable-diffusion") {
|
|
|
useDiffusionModelPath = false;
|
|
useDiffusionModelPath = false;
|
|
|
- std::cout << "Model is in checkpoints directory, using model_path" << std::endl;
|
|
|
|
|
|
|
+ std::cout << "Model is in " << parentDirName << " directory, using model_path" << std::endl;
|
|
|
|
|
+ } else if (parentDirName == "sd_models" || parentDirName.empty()) {
|
|
|
|
|
+ // Handle models in root /data/SD_MODELS/ directory
|
|
|
|
|
+ if (isQwenModel) {
|
|
|
|
|
+ // Qwen models should use diffusion_model_path regardless of directory
|
|
|
|
|
+ useDiffusionModelPath = true;
|
|
|
|
|
+ detectionSource = "qwen_root_detection";
|
|
|
|
|
+ std::cout << "Qwen model in root directory, preferring diffusion_model_path" << std::endl;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // For non-Qwen models in root, try architecture detection
|
|
|
|
|
+ std::cout << "Model is in root directory '" << parentDirName << "', attempting architecture detection" << std::endl;
|
|
|
|
|
+ detectionSource = "architecture_fallback";
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ detectionResult = ModelDetector::detectModel(modelPath);
|
|
|
|
|
+ detectionSuccessful = true;
|
|
|
|
|
+ std::cout << "Architecture detection found: " << detectionResult.architectureName << std::endl;
|
|
|
|
|
+ } catch (const std::exception& e) {
|
|
|
|
|
+ std::cerr << "Warning: Architecture detection failed: " << e.what() << ". Using default loading method." << std::endl;
|
|
|
|
|
+ detectionResult.architecture = ModelArchitecture::UNKNOWN;
|
|
|
|
|
+ detectionResult.architectureName = "Unknown";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (detectionSuccessful) {
|
|
|
|
|
+ switch (detectionResult.architecture) {
|
|
|
|
|
+ case ModelArchitecture::FLUX_SCHNELL:
|
|
|
|
|
+ case ModelArchitecture::FLUX_DEV:
|
|
|
|
|
+ case ModelArchitecture::FLUX_CHROMA:
|
|
|
|
|
+ case ModelArchitecture::SD_3:
|
|
|
|
|
+ case ModelArchitecture::QWEN2VL:
|
|
|
|
|
+ // Modern architectures use diffusion_model_path
|
|
|
|
|
+ useDiffusionModelPath = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case ModelArchitecture::SD_1_5:
|
|
|
|
|
+ case ModelArchitecture::SD_2_1:
|
|
|
|
|
+ case ModelArchitecture::SDXL_BASE:
|
|
|
|
|
+ case ModelArchitecture::SDXL_REFINER:
|
|
|
|
|
+ // Traditional SD models use model_path
|
|
|
|
|
+ useDiffusionModelPath = false;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case ModelArchitecture::UNKNOWN:
|
|
|
|
|
+ default:
|
|
|
|
|
+ // Unknown architectures fall back to model_path for backward compatibility
|
|
|
|
|
+ useDiffusionModelPath = false;
|
|
|
|
|
+ std::cout << "Warning: Unknown model architecture detected, using default model_path for backward compatibility" << std::endl;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ useDiffusionModelPath = false; // Default fallback
|
|
|
|
|
+ detectionSource = "default_fallback";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
- // Fallback: try architecture detection for unknown locations
|
|
|
|
|
|
|
+ // Unknown directory - try architecture detection
|
|
|
std::cout << "Model is in unknown directory '" << parentDirName << "', attempting architecture detection as fallback" << std::endl;
|
|
std::cout << "Model is in unknown directory '" << parentDirName << "', attempting architecture detection as fallback" << std::endl;
|
|
|
detectionSource = "architecture_fallback";
|
|
detectionSource = "architecture_fallback";
|
|
|
|
|
|
|
@@ -109,36 +182,43 @@ public:
|
|
|
|
|
|
|
|
// Set the appropriate model path based on folder location or fallback detection
|
|
// Set the appropriate model path based on folder location or fallback detection
|
|
|
if (useDiffusionModelPath) {
|
|
if (useDiffusionModelPath) {
|
|
|
- ctxParams.diffusion_model_path = modelPath.c_str();
|
|
|
|
|
|
|
+ ctxParams.diffusion_model_path = persistentModelPath.c_str();
|
|
|
ctxParams.model_path = nullptr; // Clear the traditional path
|
|
ctxParams.model_path = nullptr; // Clear the traditional path
|
|
|
std::cout << "Using diffusion_model_path (source: " << detectionSource << ")" << std::endl;
|
|
std::cout << "Using diffusion_model_path (source: " << detectionSource << ")" << std::endl;
|
|
|
} else {
|
|
} else {
|
|
|
- ctxParams.model_path = modelPath.c_str();
|
|
|
|
|
|
|
+ ctxParams.model_path = persistentModelPath.c_str();
|
|
|
ctxParams.diffusion_model_path = nullptr; // Clear the modern path
|
|
ctxParams.diffusion_model_path = nullptr; // Clear the modern path
|
|
|
std::cout << "Using model_path (source: " << detectionSource << ")" << std::endl;
|
|
std::cout << "Using model_path (source: " << detectionSource << ")" << std::endl;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Set optional model paths if provided
|
|
|
|
|
- if (!params.clipLPath.empty()) {
|
|
|
|
|
- ctxParams.clip_l_path = params.clipLPath.c_str();
|
|
|
|
|
|
|
+ // Set optional model paths using persistent strings to fix lifetime issues
|
|
|
|
|
+ if (!persistentClipLPath.empty()) {
|
|
|
|
|
+ ctxParams.clip_l_path = persistentClipLPath.c_str();
|
|
|
|
|
+ std::cout << "Using CLIP-L path: " << std::filesystem::absolute(persistentClipLPath) << std::endl;
|
|
|
}
|
|
}
|
|
|
- if (!params.clipGPath.empty()) {
|
|
|
|
|
- ctxParams.clip_g_path = params.clipGPath.c_str();
|
|
|
|
|
|
|
+ if (!persistentClipGPath.empty()) {
|
|
|
|
|
+ ctxParams.clip_g_path = persistentClipGPath.c_str();
|
|
|
|
|
+ std::cout << "Using CLIP-G path: " << std::filesystem::absolute(persistentClipGPath) << std::endl;
|
|
|
}
|
|
}
|
|
|
- if (!params.vaePath.empty()) {
|
|
|
|
|
- ctxParams.vae_path = params.vaePath.c_str();
|
|
|
|
|
|
|
+ if (!persistentVaePath.empty()) {
|
|
|
|
|
+ ctxParams.vae_path = persistentVaePath.c_str();
|
|
|
|
|
+ std::cout << "Using VAE path: " << std::filesystem::absolute(persistentVaePath) << std::endl;
|
|
|
}
|
|
}
|
|
|
- if (!params.taesdPath.empty()) {
|
|
|
|
|
- ctxParams.taesd_path = params.taesdPath.c_str();
|
|
|
|
|
|
|
+ if (!persistentTaesdPath.empty()) {
|
|
|
|
|
+ ctxParams.taesd_path = persistentTaesdPath.c_str();
|
|
|
|
|
+ std::cout << "Using TAESD path: " << std::filesystem::absolute(persistentTaesdPath) << std::endl;
|
|
|
}
|
|
}
|
|
|
- if (!params.controlNetPath.empty()) {
|
|
|
|
|
- ctxParams.control_net_path = params.controlNetPath.c_str();
|
|
|
|
|
|
|
+ if (!persistentControlNetPath.empty()) {
|
|
|
|
|
+ ctxParams.control_net_path = persistentControlNetPath.c_str();
|
|
|
|
|
+ std::cout << "Using ControlNet path: " << std::filesystem::absolute(persistentControlNetPath) << std::endl;
|
|
|
}
|
|
}
|
|
|
- if (!params.loraModelDir.empty()) {
|
|
|
|
|
- ctxParams.lora_model_dir = params.loraModelDir.c_str();
|
|
|
|
|
|
|
+ if (!persistentLoraModelDir.empty()) {
|
|
|
|
|
+ ctxParams.lora_model_dir = persistentLoraModelDir.c_str();
|
|
|
|
|
+ std::cout << "Using LoRA model directory: " << std::filesystem::absolute(persistentLoraModelDir) << std::endl;
|
|
|
}
|
|
}
|
|
|
- if (!params.embeddingDir.empty()) {
|
|
|
|
|
- ctxParams.embedding_dir = params.embeddingDir.c_str();
|
|
|
|
|
|
|
+ if (!persistentEmbeddingDir.empty()) {
|
|
|
|
|
+ ctxParams.embedding_dir = persistentEmbeddingDir.c_str();
|
|
|
|
|
+ std::cout << "Using embedding directory: " << std::filesystem::absolute(persistentEmbeddingDir) << std::endl;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Set performance parameters
|
|
// Set performance parameters
|
|
@@ -154,9 +234,11 @@ public:
|
|
|
ctxParams.wtype = StableDiffusionWrapper::stringToModelType(params.modelType);
|
|
ctxParams.wtype = StableDiffusionWrapper::stringToModelType(params.modelType);
|
|
|
|
|
|
|
|
// Create the stable-diffusion context
|
|
// Create the stable-diffusion context
|
|
|
|
|
+ std::cout << "Attempting to create stable-diffusion context with selected parameters..." << std::endl;
|
|
|
sdContext = new_sd_ctx(&ctxParams);
|
|
sdContext = new_sd_ctx(&ctxParams);
|
|
|
if (!sdContext) {
|
|
if (!sdContext) {
|
|
|
lastError = "Failed to create stable-diffusion context";
|
|
lastError = "Failed to create stable-diffusion context";
|
|
|
|
|
+ std::cerr << "Error: " << lastError << " with initial attempt" << std::endl;
|
|
|
|
|
|
|
|
// If we used diffusion_model_path and it failed, try fallback to model_path
|
|
// If we used diffusion_model_path and it failed, try fallback to model_path
|
|
|
if (useDiffusionModelPath) {
|
|
if (useDiffusionModelPath) {
|
|
@@ -165,31 +247,31 @@ public:
|
|
|
// Re-initialize context parameters
|
|
// Re-initialize context parameters
|
|
|
sd_ctx_params_init(&ctxParams);
|
|
sd_ctx_params_init(&ctxParams);
|
|
|
|
|
|
|
|
- // Set fallback model path
|
|
|
|
|
- ctxParams.model_path = modelPath.c_str();
|
|
|
|
|
|
|
+ // Set fallback model path using persistent string
|
|
|
|
|
+ ctxParams.model_path = persistentModelPath.c_str();
|
|
|
ctxParams.diffusion_model_path = nullptr;
|
|
ctxParams.diffusion_model_path = nullptr;
|
|
|
|
|
|
|
|
- // Re-apply other parameters
|
|
|
|
|
- if (!params.clipLPath.empty()) {
|
|
|
|
|
- ctxParams.clip_l_path = params.clipLPath.c_str();
|
|
|
|
|
|
|
+ // Re-apply other parameters using persistent strings
|
|
|
|
|
+ if (!persistentClipLPath.empty()) {
|
|
|
|
|
+ ctxParams.clip_l_path = persistentClipLPath.c_str();
|
|
|
}
|
|
}
|
|
|
- if (!params.clipGPath.empty()) {
|
|
|
|
|
- ctxParams.clip_g_path = params.clipGPath.c_str();
|
|
|
|
|
|
|
+ if (!persistentClipGPath.empty()) {
|
|
|
|
|
+ ctxParams.clip_g_path = persistentClipGPath.c_str();
|
|
|
}
|
|
}
|
|
|
- if (!params.vaePath.empty()) {
|
|
|
|
|
- ctxParams.vae_path = params.vaePath.c_str();
|
|
|
|
|
|
|
+ if (!persistentVaePath.empty()) {
|
|
|
|
|
+ ctxParams.vae_path = persistentVaePath.c_str();
|
|
|
}
|
|
}
|
|
|
- if (!params.taesdPath.empty()) {
|
|
|
|
|
- ctxParams.taesd_path = params.taesdPath.c_str();
|
|
|
|
|
|
|
+ if (!persistentTaesdPath.empty()) {
|
|
|
|
|
+ ctxParams.taesd_path = persistentTaesdPath.c_str();
|
|
|
}
|
|
}
|
|
|
- if (!params.controlNetPath.empty()) {
|
|
|
|
|
- ctxParams.control_net_path = params.controlNetPath.c_str();
|
|
|
|
|
|
|
+ if (!persistentControlNetPath.empty()) {
|
|
|
|
|
+ ctxParams.control_net_path = persistentControlNetPath.c_str();
|
|
|
}
|
|
}
|
|
|
- if (!params.loraModelDir.empty()) {
|
|
|
|
|
- ctxParams.lora_model_dir = params.loraModelDir.c_str();
|
|
|
|
|
|
|
+ if (!persistentLoraModelDir.empty()) {
|
|
|
|
|
+ ctxParams.lora_model_dir = persistentLoraModelDir.c_str();
|
|
|
}
|
|
}
|
|
|
- if (!params.embeddingDir.empty()) {
|
|
|
|
|
- ctxParams.embedding_dir = params.embeddingDir.c_str();
|
|
|
|
|
|
|
+ if (!persistentEmbeddingDir.empty()) {
|
|
|
|
|
+ ctxParams.embedding_dir = persistentEmbeddingDir.c_str();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Re-apply performance parameters
|
|
// Re-apply performance parameters
|
|
@@ -204,25 +286,78 @@ public:
|
|
|
// Re-apply model type
|
|
// Re-apply model type
|
|
|
ctxParams.wtype = StableDiffusionWrapper::stringToModelType(params.modelType);
|
|
ctxParams.wtype = StableDiffusionWrapper::stringToModelType(params.modelType);
|
|
|
|
|
|
|
|
|
|
+ std::cout << "Attempting to create context with fallback model_path..." << std::endl;
|
|
|
// Try creating context again with fallback
|
|
// Try creating context again with fallback
|
|
|
sdContext = new_sd_ctx(&ctxParams);
|
|
sdContext = new_sd_ctx(&ctxParams);
|
|
|
if (!sdContext) {
|
|
if (!sdContext) {
|
|
|
lastError = "Failed to create stable-diffusion context with both diffusion_model_path and model_path fallback";
|
|
lastError = "Failed to create stable-diffusion context with both diffusion_model_path and model_path fallback";
|
|
|
std::cerr << "Error: " << lastError << std::endl;
|
|
std::cerr << "Error: " << lastError << std::endl;
|
|
|
- return false;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Additional fallback: try with minimal parameters for GGUF models
|
|
|
|
|
+ if (modelFileName.find(".gguf") != std::string::npos || modelFileName.find(".ggml") != std::string::npos) {
|
|
|
|
|
+ std::cout << "Detected GGUF/GGML model, attempting minimal parameter fallback..." << std::endl;
|
|
|
|
|
+
|
|
|
|
|
+ // Re-initialize with minimal parameters
|
|
|
|
|
+ sd_ctx_params_init(&ctxParams);
|
|
|
|
|
+ ctxParams.model_path = persistentModelPath.c_str();
|
|
|
|
|
+ ctxParams.diffusion_model_path = nullptr;
|
|
|
|
|
+
|
|
|
|
|
+ // Set only essential parameters for GGUF
|
|
|
|
|
+ ctxParams.n_threads = params.nThreads;
|
|
|
|
|
+ ctxParams.wtype = StableDiffusionWrapper::stringToModelType(params.modelType);
|
|
|
|
|
+
|
|
|
|
|
+ std::cout << "Attempting to create context with minimal GGUF parameters..." << std::endl;
|
|
|
|
|
+ sdContext = new_sd_ctx(&ctxParams);
|
|
|
|
|
+
|
|
|
|
|
+ if (!sdContext) {
|
|
|
|
|
+ lastError = "Failed to create stable-diffusion context even with minimal GGUF parameters";
|
|
|
|
|
+ std::cerr << "Error: " << lastError << std::endl;
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ std::cout << "Successfully loaded GGUF model with minimal parameters: " << absModelPath << std::endl;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ std::cout << "Successfully loaded model with fallback to model_path: " << absModelPath << std::endl;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- std::cout << "Successfully loaded model with fallback to model_path: " << modelPath << std::endl;
|
|
|
|
|
} else {
|
|
} else {
|
|
|
- std::cerr << "Error: " << lastError << std::endl;
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ // Try minimal fallback for non-diffusion_model_path failures
|
|
|
|
|
+ if (modelFileName.find(".gguf") != std::string::npos || modelFileName.find(".ggml") != std::string::npos) {
|
|
|
|
|
+ std::cout << "Detected GGUF/GGML model, attempting minimal parameter fallback..." << std::endl;
|
|
|
|
|
+
|
|
|
|
|
+ // Re-initialize with minimal parameters
|
|
|
|
|
+ sd_ctx_params_init(&ctxParams);
|
|
|
|
|
+ ctxParams.model_path = persistentModelPath.c_str();
|
|
|
|
|
+
|
|
|
|
|
+ // Set only essential parameters for GGUF
|
|
|
|
|
+ ctxParams.n_threads = params.nThreads;
|
|
|
|
|
+ ctxParams.wtype = StableDiffusionWrapper::stringToModelType(params.modelType);
|
|
|
|
|
+
|
|
|
|
|
+ std::cout << "Attempting to create context with minimal GGUF parameters..." << std::endl;
|
|
|
|
|
+ sdContext = new_sd_ctx(&ctxParams);
|
|
|
|
|
+
|
|
|
|
|
+ if (!sdContext) {
|
|
|
|
|
+ lastError = "Failed to create stable-diffusion context even with minimal GGUF parameters";
|
|
|
|
|
+ std::cerr << "Error: " << lastError << std::endl;
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ std::cout << "Successfully loaded GGUF model with minimal parameters: " << absModelPath << std::endl;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ std::cerr << "Error: " << lastError << std::endl;
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Log successful loading with detection information
|
|
// Log successful loading with detection information
|
|
|
- std::cout << "Successfully loaded model: " << modelPath << std::endl;
|
|
|
|
|
|
|
+ std::cout << "Successfully loaded model: " << absModelPath << std::endl;
|
|
|
std::cout << " Detection source: " << detectionSource << std::endl;
|
|
std::cout << " Detection source: " << detectionSource << std::endl;
|
|
|
std::cout << " Loading method: " << (useDiffusionModelPath ? "diffusion_model_path" : "model_path") << std::endl;
|
|
std::cout << " Loading method: " << (useDiffusionModelPath ? "diffusion_model_path" : "model_path") << std::endl;
|
|
|
|
|
+ std::cout << " Parent directory: " << parentDirName << std::endl;
|
|
|
|
|
+ std::cout << " Model filename: " << modelFileName << std::endl;
|
|
|
|
|
|
|
|
// Log additional model properties if architecture detection was performed
|
|
// Log additional model properties if architecture detection was performed
|
|
|
if (detectionSuccessful) {
|
|
if (detectionSuccessful) {
|