Skip to content

Commit 5ea6262

Browse files
committed
feat: add KL Optimal scheduler
1 parent 200cb6f commit 5ea6262

File tree

6 files changed

+47
-6
lines changed

6 files changed

+47
-6
lines changed

denoiser.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,41 @@ struct SmoothStepScheduler : SigmaScheduler {
347347
}
348348
};
349349

350+
// Implementation adapted from https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15608
351+
struct KLOptimalScheduler : SigmaScheduler {
352+
std::vector<float> get_sigmas(uint32_t n, float sigma_min, float sigma_max, t_to_sigma_t t_to_sigma) override {
353+
std::vector<float> sigmas;
354+
355+
if (n == 0) {
356+
return sigmas;
357+
}
358+
if (n == 1) {
359+
sigmas.push_back(sigma_max);
360+
sigmas.push_back(0.0f);
361+
return sigmas;
362+
}
363+
364+
float alpha_min = std::atan(sigma_min);
365+
float alpha_max = std::atan(sigma_max);
366+
367+
for (uint32_t i = 0; i < n; ++i) {
368+
// t goes from 0.0 to 1.0
369+
float t = static_cast<float>(i) / static_cast<float>(n-1);
370+
371+
// Interpolate in the angle domain
372+
float angle = t * alpha_min + (1.0f - t) * alpha_max;
373+
374+
// Convert back to sigma
375+
sigmas.push_back(std::tan(angle));
376+
}
377+
378+
// Append the final zero to sigma
379+
sigmas.push_back(0.0f);
380+
381+
return sigmas;
382+
}
383+
};
384+
350385
struct Denoiser {
351386
virtual float sigma_min() = 0;
352387
virtual float sigma_max() = 0;
@@ -392,6 +427,10 @@ struct Denoiser {
392427
LOG_INFO("get_sigmas with SmoothStep scheduler");
393428
scheduler = std::make_shared<SmoothStepScheduler>();
394429
break;
430+
case KL_OPTIMAL_SCHEDULER:
431+
LOG_INFO("get_sigmas with KL Optimal scheduler");
432+
scheduler = std::make_shared<KLOptimalScheduler>();
433+
break;
395434
case LCM_SCHEDULER:
396435
LOG_INFO("get_sigmas with LCM scheduler");
397436
scheduler = std::make_shared<LCMScheduler>();

examples/cli/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ Generation Options:
119119
tcd] (default: euler for Flux/SD3/Wan, euler_a otherwise)
120120
--high-noise-sampling-method (high noise) sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm,
121121
ddim_trailing, tcd] default: euler for Flux/SD3/Wan, euler_a otherwise
122-
--scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, lcm],
122+
--scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, kl_optimal, lcm],
123123
default: discrete
124124
--sigmas custom sigma values for the sampler, comma-separated (e.g., "14.61,7.8,3.5,0.0").
125125
--skip-layers layers to skip for SLG steps (default: [7,8,9])

examples/common/common.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ struct SDGenerationParams {
12981298
on_high_noise_sample_method_arg},
12991299
{"",
13001300
"--scheduler",
1301-
"denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, lcm], default: discrete",
1301+
"denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, kl_optimal, lcm], default: discrete",
13021302
on_scheduler_arg},
13031303
{"",
13041304
"--sigmas",
@@ -1800,4 +1800,4 @@ uint8_t* load_image_from_memory(const char* image_bytes,
18001800
int expected_height = 0,
18011801
int expected_channel = 3) {
18021802
return load_image_common(true, image_bytes, len, width, height, expected_width, expected_height, expected_channel);
1803-
}
1803+
}

examples/server/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ Default Generation Options:
113113
tcd] (default: euler for Flux/SD3/Wan, euler_a otherwise)
114114
--high-noise-sampling-method (high noise) sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm,
115115
ddim_trailing, tcd] default: euler for Flux/SD3/Wan, euler_a otherwise
116-
--scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, lcm],
116+
--scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, kl_optimal, lcm],
117117
default: discrete
118118
--sigmas custom sigma values for the sampler, comma-separated (e.g., "14.61,7.8,3.5,0.0").
119119
--skip-layers layers to skip for SLG steps (default: [7,8,9])
120120
--high-noise-skip-layers (high noise) layers to skip for SLG steps (default: [7,8,9])
121121
-r, --ref-image reference image for Flux Kontext models (can be used multiple times)
122122
--easycache enable EasyCache for DiT models with optional "threshold,start_percent,end_percent" (default: 0.2,0.15,0.95)
123-
```
123+
```

stable-diffusion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2399,6 +2399,7 @@ const char* scheduler_to_str[] = {
23992399
"sgm_uniform",
24002400
"simple",
24012401
"smoothstep",
2402+
"kl_optimal",
24022403
"lcm",
24032404
};
24042405

@@ -3875,4 +3876,4 @@ SD_API sd_image_t* generate_video(sd_ctx_t* sd_ctx, const sd_vid_gen_params_t* s
38753876
LOG_INFO("generate_video completed in %.2fs", (t5 - t0) * 1.0f / 1000);
38763877

38773878
return result_images;
3878-
}
3879+
}

stable-diffusion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum scheduler_t {
6060
SGM_UNIFORM_SCHEDULER,
6161
SIMPLE_SCHEDULER,
6262
SMOOTHSTEP_SCHEDULER,
63+
KL_OPTIMAL_SCHEDULER,
6364
LCM_SCHEDULER,
6465
SCHEDULER_COUNT
6566
};

0 commit comments

Comments
 (0)