Skip to content

Commit eb8095c

Browse files
committed
feat: add support for the eta parameter to ancestral samplers
1 parent 69f49b3 commit eb8095c

5 files changed

Lines changed: 35 additions & 11 deletions

File tree

examples/cli/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ Generation Options:
109109
medium
110110
--skip-layer-start <float> SLG enabling point (default: 0.01)
111111
--skip-layer-end <float> SLG disabling point (default: 0.2)
112-
--eta <float> eta in DDIM, only for DDIM and TCD (default: 0)
112+
--eta <float> noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)
113113
--flow-shift <float> shift value for Flow models like SD3.x or WAN (default: auto)
114114
--high-noise-cfg-scale <float> (high noise) unconditional guidance scale: (default: 7.0)
115115
--high-noise-img-cfg-scale <float> (high noise) image guidance scale for inpaint or instruct-pix2pix models (default: same as --cfg-scale)
116116
--high-noise-guidance <float> (high noise) distilled guidance scale for models with guidance input (default: 3.5)
117117
--high-noise-slg-scale <float> (high noise) skip layer guidance (SLG) scale, only for DiT models: (default: 0)
118118
--high-noise-skip-layer-start <float> (high noise) SLG enabling point (default: 0.01)
119119
--high-noise-skip-layer-end <float> (high noise) SLG disabling point (default: 0.2)
120-
--high-noise-eta <float> (high noise) eta in DDIM, only for DDIM and TCD (default: 0)
120+
--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)
121121
--strength <float> strength for noising/unnoising (default: 0.75)
122122
--pm-style-strength <float>
123123
--control-strength <float> strength to apply Control Net (default: 0.9). 1.0 corresponds to full destruction of information in init image

examples/common/common.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ struct SDGenerationParams {
11971197
&sample_params.guidance.slg.layer_end},
11981198
{"",
11991199
"--eta",
1200-
"eta in DDIM, only for DDIM and TCD (default: 0)",
1200+
"noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)",
12011201
&sample_params.eta},
12021202
{"",
12031203
"--flow-shift",
@@ -1229,7 +1229,7 @@ struct SDGenerationParams {
12291229
&high_noise_sample_params.guidance.slg.layer_end},
12301230
{"",
12311231
"--high-noise-eta",
1232-
"(high noise) eta in DDIM, only for DDIM and TCD (default: 0)",
1232+
"(high noise) noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)",
12331233
&high_noise_sample_params.eta},
12341234
{"",
12351235
"--strength",

examples/server/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,15 @@ Default Generation Options:
189189
medium
190190
--skip-layer-start <float> SLG enabling point (default: 0.01)
191191
--skip-layer-end <float> SLG disabling point (default: 0.2)
192-
--eta <float> eta in DDIM, only for DDIM and TCD (default: 0)
192+
--eta <float> noise multiplier (default: 0 for ddim_trailing, tcd, res_multistep and res_2s; 1 for euler_a and dpm++2s_a)
193193
--flow-shift <float> shift value for Flow models like SD3.x or WAN (default: auto)
194194
--high-noise-cfg-scale <float> (high noise) unconditional guidance scale: (default: 7.0)
195195
--high-noise-img-cfg-scale <float> (high noise) image guidance scale for inpaint or instruct-pix2pix models (default: same as --cfg-scale)
196196
--high-noise-guidance <float> (high noise) distilled guidance scale for models with guidance input (default: 3.5)
197197
--high-noise-slg-scale <float> (high noise) skip layer guidance (SLG) scale, only for DiT models: (default: 0)
198198
--high-noise-skip-layer-start <float> (high noise) SLG enabling point (default: 0.01)
199199
--high-noise-skip-layer-end <float> (high noise) SLG disabling point (default: 0.2)
200-
--high-noise-eta <float> (high noise) eta in DDIM, only for DDIM and TCD (default: 0)
200+
--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)
201201
--strength <float> strength for noising/unnoising (default: 0.75)
202202
--pm-style-strength <float>
203203
--control-strength <float> strength to apply Control Net (default: 0.9). 1.0 corresponds to full destruction of information in init image

src/denoiser.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,10 @@ static sd::Tensor<float> sample_k_diffusion(sample_method_t method,
802802
sd::Tensor<float> denoised = std::move(denoised_opt);
803803
sd::Tensor<float> d = (x - denoised) / sigma;
804804
float sigma_up, sigma_down;
805-
generate_ancestral_step(sigma_up, sigma_down, sigmas[i], sigmas[i + 1]);
805+
generate_ancestral_step(sigma_up, sigma_down, sigmas[i], sigmas[i + 1], eta);
806806
float dt = sigma_down - sigmas[i];
807807
x += d * dt;
808-
if (sigmas[i + 1] > 0) {
808+
if (sigmas[i + 1] > 0 && sigma_up > 0.0f) {
809809
x += sd::Tensor<float>::randn_like(x, rng) * sigma_up;
810810
}
811811
}
@@ -883,7 +883,7 @@ static sd::Tensor<float> sample_k_diffusion(sample_method_t method,
883883
}
884884
sd::Tensor<float> denoised = std::move(denoised_opt);
885885
float sigma_up, sigma_down;
886-
generate_ancestral_step(sigma_up, sigma_down, sigmas[i], sigmas[i + 1]);
886+
generate_ancestral_step(sigma_up, sigma_down, sigmas[i], sigmas[i + 1], eta);
887887
auto t_fn = [](float sigma) -> float { return -log(sigma); };
888888
auto sigma_fn = [](float t) -> float { return exp(-t); };
889889

@@ -903,7 +903,7 @@ static sd::Tensor<float> sample_k_diffusion(sample_method_t method,
903903
x = (sigma_fn(t_next) / sigma_fn(t)) * (x) - (exp(-h) - 1) * denoised2;
904904
}
905905

906-
if (sigmas[i + 1] > 0) {
906+
if (sigmas[i + 1] > 0 && sigma_up > 0.0f) {
907907
x += sd::Tensor<float>::randn_like(x, rng) * sigma_up;
908908
}
909909
}

src/stable-diffusion.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2225,6 +2225,7 @@ void sd_sample_params_init(sd_sample_params_t* sample_params) {
22252225
sample_params->scheduler = SCHEDULER_COUNT;
22262226
sample_params->sample_method = SAMPLE_METHOD_COUNT;
22272227
sample_params->sample_steps = 20;
2228+
sample_params->eta = INFINITY;
22282229
sample_params->custom_sigmas = nullptr;
22292230
sample_params->custom_sigmas_count = 0;
22302231
sample_params->flow_shift = INFINITY;
@@ -2438,6 +2439,25 @@ static scheduler_t resolve_scheduler(sd_ctx_t* sd_ctx,
24382439
return scheduler;
24392440
}
24402441

2442+
static float resolve_eta(sd_ctx_t* sd_ctx,
2443+
float eta,
2444+
enum sample_method_t sample_method) {
2445+
if (eta == INFINITY) {
2446+
switch(sample_method) {
2447+
case DDIM_TRAILING_SAMPLE_METHOD:
2448+
case TCD_SAMPLE_METHOD:
2449+
case RES_MULTISTEP_SAMPLE_METHOD:
2450+
case RES_2S_SAMPLE_METHOD:
2451+
return 0.0f;
2452+
case EULER_A_SAMPLE_METHOD:
2453+
case DPMPP2S_A_SAMPLE_METHOD:
2454+
return 1.0f;
2455+
default: ;
2456+
}
2457+
}
2458+
return eta;
2459+
}
2460+
24412461
struct GenerationRequest {
24422462
std::string prompt;
24432463
std::string negative_prompt;
@@ -2586,6 +2606,7 @@ struct GenerationRequest {
25862606
struct SamplePlan {
25872607
enum sample_method_t sample_method = SAMPLE_METHOD_COUNT;
25882608
enum sample_method_t high_noise_sample_method = SAMPLE_METHOD_COUNT;
2609+
float eta = 0.f;
25892610
int sample_steps = 0;
25902611
int high_noise_sample_steps = 0;
25912612
int total_steps = 0;
@@ -2597,6 +2618,7 @@ struct SamplePlan {
25972618
const sd_img_gen_params_t* sd_img_gen_params,
25982619
const GenerationRequest& request) {
25992620
sample_method = sd_img_gen_params->sample_params.sample_method;
2621+
eta = sd_img_gen_params->sample_params.eta;
26002622
sample_steps = sd_img_gen_params->sample_params.sample_steps;
26012623
resolve(sd_ctx, &request, &sd_img_gen_params->sample_params);
26022624
}
@@ -2644,6 +2666,8 @@ struct SamplePlan {
26442666
sd_ctx->sd->version);
26452667
}
26462668

2669+
eta = resolve_eta(sd_ctx, eta, sample_method);
2670+
26472671
if (high_noise_sample_steps < 0) {
26482672
for (size_t i = 0; i < sigmas.size(); ++i) {
26492673
if (sigmas[i] < moe_boundary) {
@@ -3123,7 +3147,7 @@ SD_API sd_image_t* generate_image(sd_ctx_t* sd_ctx, const sd_img_gen_params_t* s
31233147
latents.control_image,
31243148
request.control_strength,
31253149
request.guidance,
3126-
request.eta,
3150+
plan.eta,
31273151
request.shifted_timestep,
31283152
plan.sample_method,
31293153
plan.sigmas,

0 commit comments

Comments
 (0)