mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-11-12 03:49:09 +00:00
feat: add Fibo 2.0 Dev and Edit Turbo support (#2180)
This commit is contained in:
1 parent
939895f00e
commit
2e2ba3faec
22 files changed
+931
-69
No files matched your search
@@ -113,6 +113,7 @@ const char* model_version_to_str[] = {
|
||||
"Iris-3B",
|
||||
"Flux.3 Image Klein",
|
||||
"MOSS-Image",
|
||||
"Fibo-2.0",
|
||||
};
|
||||
|
||||
static_assert(VERSION_COUNT == sizeof(model_version_to_str) / sizeof(model_version_to_str[0]),
|
||||
@@ -1499,7 +1500,8 @@ bool StableDiffusionGGML::build_denoiser() {
|
||||
sd_version_is_pid(version) ||
|
||||
sd_version_is_ideogram4(version) ||
|
||||
version == VERSION_IRIS ||
|
||||
version == VERSION_MOSS_IMAGE) {
|
||||
version == VERSION_MOSS_IMAGE ||
|
||||
version == VERSION_FIBO2) {
|
||||
pred_type = FLOW_PRED;
|
||||
if (sd_version_is_wan(version) || version == VERSION_MOSS_IMAGE) {
|
||||
default_flow_shift = 5.f;
|
||||
@@ -3205,7 +3207,9 @@ bool StableDiffusionGGML::is_flow_denoiser() {
|
||||
}
|
||||
|
||||
std::string StableDiffusionGGML::get_default_ref_image_preset(SDVersion version) const {
|
||||
if (sd_version_is_longcat(version)) {
|
||||
if (version == VERSION_FIBO2) {
|
||||
return "fibo2";
|
||||
} else if (sd_version_is_longcat(version)) {
|
||||
return "longcat";
|
||||
} else if (sd_version_is_flux(version)) {
|
||||
return "flux_kontext";
|
||||
@@ -3257,6 +3261,9 @@ RefImageParams StableDiffusionGGML::resolve_ref_image_params(const char* ref_ima
|
||||
LOG_INFO("Using '%s' preset for reference images", preset_name.c_str());
|
||||
params = REF_IMAGE_PRESETS.at(preset_name);
|
||||
}
|
||||
if (version == VERSION_QWEN_IMAGE_2_1) {
|
||||
params.vlm_use_vae_input = true;
|
||||
}
|
||||
|
||||
for (const auto& [key, value] : parse_key_value_args(ref_image_args, "reference image args")) {
|
||||
if (key == "pass_to_vlm") {
|
||||
@@ -3285,6 +3292,26 @@ RefImageParams StableDiffusionGGML::resolve_ref_image_params(const char* ref_ima
|
||||
if (!parse_strict_bool(value, params.resize_before_vae)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
}
|
||||
} else if (key == "resize_vae_to_target") {
|
||||
if (!parse_strict_bool(value, params.resize_vae_to_target)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
}
|
||||
} else if (key == "resize_single_ref_to_target") {
|
||||
if (!parse_strict_bool(value, params.resize_single_ref_to_target)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
}
|
||||
} else if (key == "vae_size_buckets") {
|
||||
if (!parse_strict_bool(value, params.vae_size_buckets)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
}
|
||||
} else if (key == "vae_center_crop") {
|
||||
if (!parse_strict_bool(value, params.vae_center_crop)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
}
|
||||
} else if (key == "vlm_use_vae_input") {
|
||||
if (!parse_strict_bool(value, params.vlm_use_vae_input)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
}
|
||||
} else if (key == "vae_input_max_pixels") {
|
||||
if (!parse_strict_int(value, params.vae_input_max_pixels)) {
|
||||
LOG_WARN("ignoring invalid reference image arg '%s=%s'", key.c_str(), value.c_str());
|
||||
|
||||
+21
-13
@@ -284,26 +284,34 @@ namespace sd::pipeline {
|
||||
LOG_VERBOSE("auto resize ref images");
|
||||
double vae_width;
|
||||
double vae_height;
|
||||
if (ref_image_params.resize_vae_to_target) {
|
||||
int factor = sd_version_is_qwen_image(sd->version) ? 32 : 16;
|
||||
if (ref_image_params.resize_vae_to_target || (ref_image_params.resize_single_ref_to_target && ref_images.size() == 1)) {
|
||||
vae_width = request->width;
|
||||
vae_height = request->height;
|
||||
} else {
|
||||
int default_pixels = sd->version == VERSION_QWEN_IMAGE_2_1 ? request->width * request->height : 1024 * 1024;
|
||||
int target_pixels = ref_image_params.vae_input_max_pixels > 0 ? ref_image_params.vae_input_max_pixels : default_pixels;
|
||||
int vae_image_size = std::min(target_pixels, request->width * request->height);
|
||||
vae_width = sqrt(vae_image_size * ref_images[i].shape()[0] / ref_images[i].shape()[1]);
|
||||
vae_height = vae_width * ref_images[i].shape()[1] / ref_images[i].shape()[0];
|
||||
if (ref_image_params.vae_size_buckets) {
|
||||
auto size = sd::select_image_size_bucket(static_cast<int>(ref_images[i].shape()[0]), static_cast<int>(ref_images[i].shape()[1]), target_pixels, factor, request->width, request->height);
|
||||
vae_width = size.first;
|
||||
vae_height = size.second;
|
||||
} else {
|
||||
int vae_image_size = std::min(target_pixels, request->width * request->height);
|
||||
vae_width = sqrt(vae_image_size * ref_images[i].shape()[0] / ref_images[i].shape()[1]);
|
||||
vae_height = vae_width * ref_images[i].shape()[1] / ref_images[i].shape()[0];
|
||||
}
|
||||
}
|
||||
|
||||
int factor = sd_version_is_qwen_image(sd->version) ? 32 : 16;
|
||||
vae_height = round(vae_height / factor) * factor;
|
||||
vae_width = round(vae_width / factor) * factor;
|
||||
|
||||
auto resized_ref_img = sd::ops::interpolate(ref_images[i],
|
||||
{static_cast<int>(vae_width),
|
||||
static_cast<int>(vae_height),
|
||||
ref_images[i].shape()[2],
|
||||
ref_images[i].shape()[3]});
|
||||
auto resized_ref_img = ref_image_params.vae_center_crop
|
||||
? sd::resize_and_center_crop(ref_images[i], static_cast<int>(vae_width), static_cast<int>(vae_height))
|
||||
: sd::ops::interpolate(ref_images[i],
|
||||
{static_cast<int>(vae_width),
|
||||
static_cast<int>(vae_height),
|
||||
ref_images[i].shape()[2],
|
||||
ref_images[i].shape()[3]});
|
||||
|
||||
LOG_VERBOSE("resize vae ref image %d from %" PRId64 "x%" PRId64 " to %" PRId64 "x%" PRId64,
|
||||
static_cast<int>(i),
|
||||
@@ -313,7 +321,7 @@ namespace sd::pipeline {
|
||||
resized_ref_img.shape()[0]);
|
||||
|
||||
ref_latent = sd->encode_first_stage(resized_ref_img);
|
||||
if (sd->version == VERSION_QWEN_IMAGE_2_1) {
|
||||
if (ref_image_params.vlm_use_vae_input) {
|
||||
ref_images[i] = std::move(resized_ref_img);
|
||||
}
|
||||
} else {
|
||||
@@ -482,8 +490,8 @@ namespace sd::pipeline {
|
||||
}
|
||||
condition_params.text = request->negative_prompt;
|
||||
condition_params.zero_out_masked = zero_out_masked;
|
||||
if (sd_version_is_llada_image(sd->version)) {
|
||||
// LLaDA-Image CFG keeps the source latent but drops its SigVQ features.
|
||||
if (sd_version_is_llada_image(sd->version) || sd->version == VERSION_FIBO2) {
|
||||
// Keep source latents in CFG, but omit source images from the text encoder.
|
||||
condition_params.ref_images = nullptr;
|
||||
}
|
||||
uncond = sd->get_learned_condition(condition_params);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "conditioning/conditioner.hpp"
|
||||
#include "conditioning/fibo2.hpp"
|
||||
#include "core/ggml_extend_backend.h"
|
||||
#include "core/util.h"
|
||||
#include "extensions/generation_extension.h"
|
||||
@@ -14,6 +15,7 @@
|
||||
#include "model/diffusion/boogu.hpp"
|
||||
#include "model/diffusion/control.hpp"
|
||||
#include "model/diffusion/ernie_image.hpp"
|
||||
#include "model/diffusion/fibo2.hpp"
|
||||
#include "model/diffusion/flux.hpp"
|
||||
#include "model/diffusion/flux3.hpp"
|
||||
#include "model/diffusion/hidream_o1.hpp"
|
||||
@@ -94,7 +96,12 @@ namespace sd::model_builders {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sd_version_is_sd3(version)) {
|
||||
if (version == VERSION_FIBO2) {
|
||||
result.conditioner = std::make_shared<Fibo2Conditioner>(ctx.backends.runtime_backend(SDBackendModule::TE),
|
||||
tensor_storage_map, weight_manager, tokenizers);
|
||||
result.diffusion = std::make_shared<Fibo2::Fibo2Runner>(ctx.backends.runtime_backend(SDBackendModule::DIFFUSION),
|
||||
tensor_storage_map, "model.diffusion_model", weight_manager);
|
||||
} else if (sd_version_is_sd3(version)) {
|
||||
result.conditioner = std::make_shared<SD3CLIPEmbedder>(ctx.backends.runtime_backend(SDBackendModule::TE),
|
||||
tensor_storage_map,
|
||||
weight_manager,
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace sd::pipeline {
|
||||
return LCM_SCHEDULER;
|
||||
} else if (sample_method == DDIM_TRAILING_SAMPLE_METHOD) {
|
||||
return SIMPLE_SCHEDULER;
|
||||
} else if (sd != nullptr && (sd_version_is_flux(sd->version) || sd->version == VERSION_QWEN_IMAGE_2_1)) {
|
||||
} else if (sd != nullptr && (sd_version_is_flux(sd->version) || sd->version == VERSION_QWEN_IMAGE_2_1 || sd->version == VERSION_FIBO2)) {
|
||||
return FLUX_SCHEDULER;
|
||||
} else if (sd != nullptr && sd_version_is_flux2(sd->version)) {
|
||||
return FLUX2_SCHEDULER;
|
||||
|
||||
Reference in new issue
Block a user