mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-07-23 11:20:53 -05:00
fix: SDXL ControlNet (diffusers naming + graph size) (#1752)
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
#include "model_loader.h"
|
||||
#include "model_manager.h"
|
||||
|
||||
#define CONTROL_NET_GRAPH_SIZE 1536
|
||||
// Match main UNet's MAX_GRAPH_SIZE so SDXL ControlNet (transformer_depth={1,2,10}) fits.
|
||||
#define CONTROL_NET_GRAPH_SIZE MAX_GRAPH_SIZE
|
||||
|
||||
/*
|
||||
=================================== ControlNet ===================================
|
||||
|
||||
@@ -736,6 +736,62 @@ std::string convert_diffusers_dit_to_original_krea2(std::string name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// Convert a diffusers-format ControlNet tensor name to the original (LDM/lllyasviel) layout
|
||||
// declared by ControlNetBlock. Reuses the UNet down/mid conversion for the shared encoder
|
||||
// (down_blocks, mid_block, time_embedding, add_embedding, conv_in) and adds the ControlNet-only
|
||||
// mappings: input_hint_block, zero_convs, middle_block_out.
|
||||
std::string convert_diffusers_controlnet_to_original_sdxl(std::string name) {
|
||||
name = convert_diffusers_unet_to_original_sdxl(std::move(name));
|
||||
|
||||
static const std::vector<std::pair<std::string, std::string>> prefix_map = {
|
||||
{"controlnet_cond_embedding.conv_in.", "input_hint_block.0."},
|
||||
{"controlnet_cond_embedding.blocks.0.", "input_hint_block.2."},
|
||||
{"controlnet_cond_embedding.blocks.1.", "input_hint_block.4."},
|
||||
{"controlnet_cond_embedding.blocks.2.", "input_hint_block.6."},
|
||||
{"controlnet_cond_embedding.blocks.3.", "input_hint_block.8."},
|
||||
{"controlnet_cond_embedding.blocks.4.", "input_hint_block.10."},
|
||||
{"controlnet_cond_embedding.blocks.5.", "input_hint_block.12."},
|
||||
{"controlnet_cond_embedding.conv_out.", "input_hint_block.14."},
|
||||
{"controlnet_mid_block.", "middle_block_out.0."},
|
||||
};
|
||||
for (const auto& p : prefix_map) {
|
||||
if (starts_with(name, p.first)) {
|
||||
return p.second + name.substr(p.first.size());
|
||||
}
|
||||
}
|
||||
|
||||
static const std::string controlnet_down_prefix = "controlnet_down_blocks.";
|
||||
if (starts_with(name, controlnet_down_prefix)) {
|
||||
size_t rest_start = controlnet_down_prefix.size();
|
||||
size_t dot = name.find('.', rest_start);
|
||||
if (dot != std::string::npos) {
|
||||
std::string idx = name.substr(rest_start, dot - rest_start);
|
||||
return "zero_convs." + idx + ".0" + name.substr(dot);
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static bool is_diffusers_controlnet_name(const std::string& name) {
|
||||
static const std::vector<std::string> heads = {
|
||||
"controlnet_cond_embedding.",
|
||||
"controlnet_down_blocks.",
|
||||
"controlnet_mid_block.",
|
||||
"down_blocks.",
|
||||
"mid_block.",
|
||||
"time_embedding.",
|
||||
"add_embedding.",
|
||||
"conv_in.",
|
||||
};
|
||||
for (const auto& h : heads) {
|
||||
if (starts_with(name, h)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string convert_diffusion_model_name(std::string name, std::string prefix, SDVersion version) {
|
||||
if (sd_version_is_sd1(version) || sd_version_is_sd2(version)) {
|
||||
name = convert_diffusers_unet_to_original_sd1(name);
|
||||
@@ -1338,6 +1394,9 @@ std::string convert_tensor_name(std::string name, SDVersion version) {
|
||||
name = name.substr(pos + 1);
|
||||
}
|
||||
}
|
||||
if (sd_version_is_sdxl(version) && is_diffusers_controlnet_name(name)) {
|
||||
name = convert_diffusers_controlnet_to_original_sdxl(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_lora) {
|
||||
|
||||
Reference in New Issue
Block a user