mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-11-10 19:06:33 +00:00
feat: support for merging LoRA weights on model conversion (#2079)
Co-authored-by: leejet <leejet714@gmail.com>
This commit is contained in:
1 parent
bbdcad48dd
commit
f4b5326da7
7 files changed
+279
-23
No files matched your search
+12
-1
@@ -716,6 +716,15 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
|
||||
if (cli_params.mode == CONVERT) {
|
||||
std::vector<sd_lora_t> loras;
|
||||
loras.reserve(gen_params.lora_map.size() + gen_params.high_noise_lora_map.size());
|
||||
for (const auto& [path, multiplier] : gen_params.lora_map) {
|
||||
loras.push_back({false, multiplier, path.c_str()});
|
||||
}
|
||||
for (const auto& [path, multiplier] : gen_params.high_noise_lora_map) {
|
||||
loras.push_back({true, multiplier, path.c_str()});
|
||||
}
|
||||
|
||||
bool success = convert_with_components(ctx_params.model_path.c_str(),
|
||||
ctx_params.clip_l_path.c_str(),
|
||||
ctx_params.clip_g_path.c_str(),
|
||||
@@ -726,7 +735,9 @@ int main(int argc, const char* argv[]) {
|
||||
ctx_params.wtype,
|
||||
ctx_params.tensor_type_rules.c_str(),
|
||||
cli_params.convert_name,
|
||||
ctx_params.n_threads);
|
||||
ctx_params.n_threads,
|
||||
loras.empty() ? nullptr : loras.data(),
|
||||
(int)loras.size());
|
||||
if (!success) {
|
||||
LOG_ERROR("convert '%s'/'%s' to '%s' failed",
|
||||
ctx_params.model_path.c_str(),
|
||||
|
||||
@@ -2271,14 +2271,15 @@ bool SDGenerationParams::from_json_str(
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDGenerationParams::extract_and_remove_lora(const std::string& lora_model_dir) {
|
||||
bool SDGenerationParams::extract_and_remove_lora(const std::string& lora_model_dir) {
|
||||
if (lora_model_dir.empty()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
static const std::regex re(R"(<lora:([^:>]+):([^>]+)>)");
|
||||
static const std::vector<std::string> valid_ext = {".gguf", ".safetensors", ".pt", ".ckpt"};
|
||||
std::smatch m;
|
||||
|
||||
bool missing = false;
|
||||
std::string tmp = prompt;
|
||||
|
||||
while (std::regex_search(tmp, m, re)) {
|
||||
@@ -2320,8 +2321,9 @@ void SDGenerationParams::extract_and_remove_lora(const std::string& lora_model_d
|
||||
}
|
||||
if (!found) {
|
||||
LOG_WARN("can not found lora %s", final_path.lexically_normal().string().c_str());
|
||||
tmp = m.suffix().str();
|
||||
prompt = std::regex_replace(prompt, re, "", std::regex_constants::format_first_only);
|
||||
tmp = m.suffix().str();
|
||||
prompt = std::regex_replace(prompt, re, "", std::regex_constants::format_first_only);
|
||||
missing = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2337,6 +2339,8 @@ void SDGenerationParams::extract_and_remove_lora(const std::string& lora_model_d
|
||||
|
||||
tmp = m.suffix().str();
|
||||
}
|
||||
|
||||
return !missing;
|
||||
}
|
||||
|
||||
bool SDGenerationParams::width_and_height_are_set() const {
|
||||
@@ -2458,7 +2462,7 @@ bool SDGenerationParams::initialize_cache_params() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDGenerationParams::resolve(const std::string& lora_model_dir, const std::string& hires_upscalers_dir, bool strict) {
|
||||
bool SDGenerationParams::resolve(const std::string& lora_model_dir, const std::string& hires_upscalers_dir, bool strict, bool validate_missing_loras) {
|
||||
vae_tiling_params.extra_tiling_args = extra_tiling_args.empty() ? nullptr : extra_tiling_args.c_str();
|
||||
|
||||
if (high_noise_sample_params.sample_steps <= 0) {
|
||||
@@ -2502,7 +2506,9 @@ bool SDGenerationParams::resolve(const std::string& lora_model_dir, const std::s
|
||||
|
||||
prompt_with_lora = prompt;
|
||||
if (!lora_model_dir.empty()) {
|
||||
extract_and_remove_lora(lora_model_dir);
|
||||
if (!extract_and_remove_lora(lora_model_dir) && validate_missing_loras) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2630,7 +2636,7 @@ bool SDGenerationParams::resolve_and_validate(SDMode mode,
|
||||
const std::string& lora_model_dir,
|
||||
const std::string& hires_upscalers_dir,
|
||||
bool strict) {
|
||||
if (!resolve(lora_model_dir, hires_upscalers_dir, strict)) {
|
||||
if (!resolve(lora_model_dir, hires_upscalers_dir, strict, mode == CONVERT)) {
|
||||
return false;
|
||||
}
|
||||
if (!validate(mode)) {
|
||||
|
||||
@@ -313,12 +313,12 @@ struct SDGenerationParams {
|
||||
const std::function<std::string(const std::string&)>& lora_path_resolver = {});
|
||||
bool parse_image_preprocess_json(const std::string& json_str);
|
||||
bool initialize_cache_params();
|
||||
void extract_and_remove_lora(const std::string& lora_model_dir);
|
||||
bool extract_and_remove_lora(const std::string& lora_model_dir);
|
||||
bool width_and_height_are_set() const;
|
||||
void set_width_and_height_if_unset(int w, int h);
|
||||
int get_resolved_width() const;
|
||||
int get_resolved_height() const;
|
||||
bool resolve(const std::string& lora_model_dir, const std::string& hires_upscalers_dir, bool strict = false);
|
||||
bool resolve(const std::string& lora_model_dir, const std::string& hires_upscalers_dir, bool strict = false, bool validate_missing_loras = false);
|
||||
bool validate(SDMode mode);
|
||||
bool resolve_and_validate(SDMode mode,
|
||||
const std::string& lora_model_dir,
|
||||
|
||||
Reference in new issue
Block a user