Skip to content

Commit 45c4677

Browse files
authored
feat: add LCM scheduler (#983)
1 parent 869d023 commit 45c4677

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

denoiser.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,23 @@ struct SGMUniformScheduler : SigmaScheduler {
253253
}
254254
};
255255

256+
struct LCMScheduler : SigmaScheduler {
257+
std::vector<float> get_sigmas(uint32_t n, float sigma_min, float sigma_max, t_to_sigma_t t_to_sigma) override {
258+
std::vector<float> result;
259+
result.reserve(n + 1);
260+
const int original_steps = 50;
261+
const int k = TIMESTEPS / original_steps;
262+
for (int i = 0; i < n; i++) {
263+
// the rounding ensures we match the training schedule of the LCM model
264+
int index = (i * original_steps) / n;
265+
int timestep = (original_steps - index) * k - 1;
266+
result.push_back(t_to_sigma(timestep));
267+
}
268+
result.push_back(0.0f);
269+
return result;
270+
}
271+
};
272+
256273
struct KarrasScheduler : SigmaScheduler {
257274
std::vector<float> get_sigmas(uint32_t n, float sigma_min, float sigma_max, t_to_sigma_t t_to_sigma) override {
258275
// These *COULD* be function arguments here,
@@ -375,6 +392,10 @@ struct Denoiser {
375392
LOG_INFO("get_sigmas with SmoothStep scheduler");
376393
scheduler = std::make_shared<SmoothStepScheduler>();
377394
break;
395+
case LCM_SCHEDULER:
396+
LOG_INFO("get_sigmas with LCM scheduler");
397+
scheduler = std::make_shared<LCMScheduler>();
398+
break;
378399
default:
379400
LOG_INFO("get_sigmas with discrete scheduler (default)");
380401
scheduler = std::make_shared<DiscreteScheduler>();

examples/cli/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ Options:
107107
compatibility issues with quantized parameters, but it usually offers faster inference
108108
speed and, in some cases, lower memory usage. The at_runtime mode, on the other
109109
hand, is exactly the opposite.
110-
--scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple], default:
111-
discrete
110+
--scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, lcm],
111+
default: discrete
112112
--skip-layers layers to skip for SLG steps (default: [7,8,9])
113113
--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,
114114
ddim_trailing, tcd] default: euler for Flux/SD3/Wan, euler_a otherwise

examples/cli/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ void parse_args(int argc, const char** argv, SDParams& params) {
11971197
on_lora_apply_mode_arg},
11981198
{"",
11991199
"--scheduler",
1200-
"denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple], default: discrete",
1200+
"denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, lcm], default: discrete",
12011201
on_scheduler_arg},
12021202
{"",
12031203
"--skip-layers",

stable-diffusion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,7 @@ const char* scheduler_to_str[] = {
22682268
"sgm_uniform",
22692269
"simple",
22702270
"smoothstep",
2271+
"lcm",
22712272
};
22722273

22732274
const char* sd_scheduler_name(enum scheduler_t scheduler) {

stable-diffusion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum scheduler_t {
6161
SGM_UNIFORM_SCHEDULER,
6262
SIMPLE_SCHEDULER,
6363
SMOOTHSTEP_SCHEDULER,
64+
LCM_SCHEDULER,
6465
SCHEDULER_COUNT
6566
};
6667

0 commit comments

Comments
 (0)