Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ Generation Options:
medium
--skip-layer-start <float> SLG enabling point (default: 0.01)
--skip-layer-end <float> SLG disabling point (default: 0.2)
--eta <float> eta in DDIM, only for DDIM and TCD (default: 0)
--eta <float> noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)
--flow-shift <float> shift value for Flow models like SD3.x or WAN (default: auto)
--high-noise-cfg-scale <float> (high noise) unconditional guidance scale: (default: 7.0)
--high-noise-img-cfg-scale <float> (high noise) image guidance scale for inpaint or instruct-pix2pix models (default: same as --cfg-scale)
--high-noise-guidance <float> (high noise) distilled guidance scale for models with guidance input (default: 3.5)
--high-noise-slg-scale <float> (high noise) skip layer guidance (SLG) scale, only for DiT models: (default: 0)
--high-noise-skip-layer-start <float> (high noise) SLG enabling point (default: 0.01)
--high-noise-skip-layer-end <float> (high noise) SLG disabling point (default: 0.2)
--high-noise-eta <float> (high noise) eta in DDIM, only for DDIM and TCD (default: 0)
--high-noise-eta <float> (high noise) noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)
--strength <float> strength for noising/unnoising (default: 0.75)
--pm-style-strength <float>
--control-strength <float> strength to apply Control Net (default: 0.9). 1.0 corresponds to full destruction of information in init image
Expand Down
4 changes: 2 additions & 2 deletions examples/common/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,7 @@ struct SDGenerationParams {
&sample_params.guidance.slg.layer_end},
{"",
"--eta",
"eta in DDIM, only for DDIM and TCD (default: 0)",
"noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)",
&sample_params.eta},
{"",
"--flow-shift",
Expand Down Expand Up @@ -1229,7 +1229,7 @@ struct SDGenerationParams {
&high_noise_sample_params.guidance.slg.layer_end},
{"",
"--high-noise-eta",
"(high noise) eta in DDIM, only for DDIM and TCD (default: 0)",
"(high noise) noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)",
&high_noise_sample_params.eta},
{"",
"--strength",
Expand Down
4 changes: 2 additions & 2 deletions examples/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ Default Generation Options:
medium
--skip-layer-start <float> SLG enabling point (default: 0.01)
--skip-layer-end <float> SLG disabling point (default: 0.2)
--eta <float> eta in DDIM, only for DDIM and TCD (default: 0)
--eta <float> noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)
--flow-shift <float> shift value for Flow models like SD3.x or WAN (default: auto)
--high-noise-cfg-scale <float> (high noise) unconditional guidance scale: (default: 7.0)
--high-noise-img-cfg-scale <float> (high noise) image guidance scale for inpaint or instruct-pix2pix models (default: same as --cfg-scale)
--high-noise-guidance <float> (high noise) distilled guidance scale for models with guidance input (default: 3.5)
--high-noise-slg-scale <float> (high noise) skip layer guidance (SLG) scale, only for DiT models: (default: 0)
--high-noise-skip-layer-start <float> (high noise) SLG enabling point (default: 0.01)
--high-noise-skip-layer-end <float> (high noise) SLG disabling point (default: 0.2)
--high-noise-eta <float> (high noise) eta in DDIM, only for DDIM and TCD (default: 0)
--high-noise-eta <float> (high noise) noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)
--strength <float> strength for noising/unnoising (default: 0.75)
--pm-style-strength <float>
--control-strength <float> strength to apply Control Net (default: 0.9). 1.0 corresponds to full destruction of information in init image
Expand Down
69 changes: 30 additions & 39 deletions src/denoiser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,26 @@ struct Flux2FlowDenoiser : public FluxFlowDenoiser {

typedef std::function<ggml_tensor*(ggml_tensor*, float, int)> denoise_cb_t;

static void generate_ancestral_step(float& sigma_up, float& sigma_down, float sigma_from, float sigma_to, float eta = 1.0f) {
// sigma_up = min(sigma_to, eta * √(sigma_to² * (sigma_from² - sigma_to²) / sigma_from²))
// sigma_down = √(sigma_to² - sigma_sup²)
sigma_up = 0.0f;
sigma_down = sigma_to;
if (eta > 0.0f) {
float sigma_from_sq = sigma_from * sigma_from;
float sigma_to_sq = sigma_to * sigma_to;
if (sigma_from_sq > 0.0f) {
float term = sigma_to_sq * (sigma_from_sq - sigma_to_sq) / sigma_from_sq;
if (term > 0.0f) {
sigma_up = eta * std::sqrt(term);
}
}
sigma_up = std::min(sigma_up, sigma_to);
float sigma_down_sq = sigma_to_sq - sigma_up * sigma_up;
sigma_down = sigma_down_sq > 0.0f ? std::sqrt(sigma_down_sq) : 0.0f;
}
}

// k diffusion reverse ODE: dx = (x - D(x;\sigma)) / \sigma dt; \sigma(t) = t
static bool sample_k_diffusion(sample_method_t method,
denoise_cb_t model,
Expand Down Expand Up @@ -797,9 +817,8 @@ static bool sample_k_diffusion(sample_method_t method,
}

// get_ancestral_step
float sigma_up = std::min(sigmas[i + 1],
std::sqrt(sigmas[i + 1] * sigmas[i + 1] * (sigmas[i] * sigmas[i] - sigmas[i + 1] * sigmas[i + 1]) / (sigmas[i] * sigmas[i])));
float sigma_down = std::sqrt(sigmas[i + 1] * sigmas[i + 1] - sigma_up * sigma_up);
float sigma_up, sigma_down;
generate_ancestral_step(sigma_up, sigma_down, sigmas[i], sigmas[i + 1], eta);

// Euler method
float dt = sigma_down - sigmas[i];
Expand All @@ -813,7 +832,7 @@ static bool sample_k_diffusion(sample_method_t method,
}
}

if (sigmas[i + 1] > 0) {
if (sigmas[i + 1] > 0 && sigma_up > 0.0f) {
// x = x + noise_sampler(sigmas[i], sigmas[i + 1]) * s_noise * sigma_up
ggml_ext_im_set_randn_f32(noise, rng);
// noise = load_tensor_from_file(work_ctx, "./rand" + std::to_string(i+1) + ".bin");
Expand Down Expand Up @@ -990,9 +1009,8 @@ static bool sample_k_diffusion(sample_method_t method,
}

// get_ancestral_step
float sigma_up = std::min(sigmas[i + 1],
std::sqrt(sigmas[i + 1] * sigmas[i + 1] * (sigmas[i] * sigmas[i] - sigmas[i + 1] * sigmas[i + 1]) / (sigmas[i] * sigmas[i])));
float sigma_down = std::sqrt(sigmas[i + 1] * sigmas[i + 1] - sigma_up * sigma_up);
float sigma_up, sigma_down;
generate_ancestral_step(sigma_up, sigma_down, sigmas[i], sigmas[i + 1], eta);
auto t_fn = [](float sigma) -> float { return -log(sigma); };
auto sigma_fn = [](float t) -> float { return exp(-t); };

Expand Down Expand Up @@ -1035,7 +1053,7 @@ static bool sample_k_diffusion(sample_method_t method,
}

// Noise addition
if (sigmas[i + 1] > 0) {
if (sigmas[i + 1] > 0 && sigma_up > 0.0f) {
ggml_ext_im_set_randn_f32(noise, rng);
{
float* vec_x = (float*)x->data;
Expand Down Expand Up @@ -1719,22 +1737,8 @@ static bool sample_k_diffusion(sample_method_t method,

float sigma_from = sigmas[i];
float sigma_to = sigmas[i + 1];
float sigma_up = 0.0f;
float sigma_down = sigma_to;

if (eta > 0.0f) {
float sigma_from_sq = sigma_from * sigma_from;
float sigma_to_sq = sigma_to * sigma_to;
if (sigma_from_sq > 0.0f) {
float term = sigma_to_sq * (sigma_from_sq - sigma_to_sq) / sigma_from_sq;
if (term > 0.0f) {
sigma_up = eta * std::sqrt(term);
}
}
sigma_up = std::min(sigma_up, sigma_to);
float sigma_down_sq = sigma_to_sq - sigma_up * sigma_up;
sigma_down = sigma_down_sq > 0.0f ? std::sqrt(sigma_down_sq) : 0.0f;
}
float sigma_up, sigma_down;
generate_ancestral_step(sigma_up, sigma_down, sigma_from, sigma_to, eta);

if (sigma_down == 0.0f || !have_old_sigma) {
float dt = sigma_down - sigma_from;
Expand Down Expand Up @@ -1826,21 +1830,8 @@ static bool sample_k_diffusion(sample_method_t method,
return false;
}

float sigma_up = 0.0f;
float sigma_down = sigma_to;
if (eta > 0.0f) {
float sigma_from_sq = sigma_from * sigma_from;
float sigma_to_sq = sigma_to * sigma_to;
if (sigma_from_sq > 0.0f) {
float term = sigma_to_sq * (sigma_from_sq - sigma_to_sq) / sigma_from_sq;
if (term > 0.0f) {
sigma_up = eta * std::sqrt(term);
}
}
sigma_up = std::min(sigma_up, sigma_to);
float sigma_down_sq = sigma_to_sq - sigma_up * sigma_up;
sigma_down = sigma_down_sq > 0.0f ? std::sqrt(sigma_down_sq) : 0.0f;
}
float sigma_up, sigma_down;
generate_ancestral_step(sigma_up, sigma_down, sigma_from, sigma_to, eta);

float* vec_x = (float*)x->data;
float* vec_x0 = (float*)x0->data;
Expand Down
29 changes: 27 additions & 2 deletions src/stable-diffusion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2777,6 +2777,7 @@ void sd_sample_params_init(sd_sample_params_t* sample_params) {
sample_params->scheduler = SCHEDULER_COUNT;
sample_params->sample_method = SAMPLE_METHOD_COUNT;
sample_params->sample_steps = 20;
sample_params->eta = INFINITY;
sample_params->custom_sigmas = nullptr;
sample_params->custom_sigmas_count = 0;
sample_params->flow_shift = INFINITY;
Expand Down Expand Up @@ -2953,6 +2954,21 @@ enum sample_method_t sd_get_default_sample_method(const sd_ctx_t* sd_ctx) {
return EULER_A_SAMPLE_METHOD;
}

static float sd_get_default_eta(enum sample_method_t sample_method) {
switch(sample_method) {
case DDIM_TRAILING_SAMPLE_METHOD:
case TCD_SAMPLE_METHOD:
case RES_MULTISTEP_SAMPLE_METHOD:
case RES_2S_SAMPLE_METHOD:
return 0.0f;
case EULER_A_SAMPLE_METHOD:
case DPMPP2S_A_SAMPLE_METHOD:
return 1.0f;
default:
return INFINITY;
}
}

enum scheduler_t sd_get_default_scheduler(const sd_ctx_t* sd_ctx, enum sample_method_t sample_method) {
if (sd_ctx != nullptr && sd_ctx->sd != nullptr) {
auto edm_v_denoiser = std::dynamic_pointer_cast<EDMVDenoiser>(sd_ctx->sd->denoiser);
Expand Down Expand Up @@ -3331,7 +3347,16 @@ sd_image_t* generate_image(sd_ctx_t* sd_ctx, const sd_img_gen_params_t* sd_img_g
if (sample_method == SAMPLE_METHOD_COUNT) {
sample_method = sd_get_default_sample_method(sd_ctx);
}
LOG_INFO("sampling using %s method", sampling_methods_str[sample_method]);
float eta = sd_img_gen_params->sample_params.eta;
float default_eta = sd_get_default_eta(sample_method);
if (default_eta != INFINITY) {
if (eta == INFINITY) {
eta = default_eta;
}
LOG_INFO("sampling using %s method (eta %g)", sampling_methods_str[sample_method], eta);
} else {
LOG_INFO("sampling using %s method", sampling_methods_str[sample_method]);
}

int sample_steps = sd_img_gen_params->sample_params.sample_steps;
std::vector<float> sigmas;
Expand Down Expand Up @@ -3546,7 +3571,7 @@ sd_image_t* generate_image(sd_ctx_t* sd_ctx, const sd_img_gen_params_t* sd_img_g
SAFE_STR(sd_img_gen_params->negative_prompt),
sd_img_gen_params->clip_skip,
guidance,
sd_img_gen_params->sample_params.eta,
eta,
sd_img_gen_params->sample_params.shifted_timestep,
width,
height,
Expand Down
Loading