diff --git a/denoiser.hpp b/denoiser.hpp index 7a8242e7d..00bad2ec7 100644 --- a/denoiser.hpp +++ b/denoiser.hpp @@ -276,6 +276,10 @@ struct KarrasScheduler : SigmaScheduler { // but does anybody ever bother to touch them? float rho = 7.f; + if (sigma_min <= 1e-6f) { + sigma_min = 1e-6f; + } + std::vector result(n + 1); float min_inv_rho = pow(sigma_min, (1.f / rho)); @@ -347,7 +351,11 @@ struct SmoothStepScheduler : SigmaScheduler { } }; -// Implementation adapted from https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15608 +/* +* KL Optimal: +* Original work from https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15608. +* Implemented using https://github.com/comfyanonymous/ComfyUI/pull/6206 as a reference. +*/ struct KLOptimalScheduler : SigmaScheduler { std::vector get_sigmas(uint32_t n, float sigma_min, float sigma_max, t_to_sigma_t t_to_sigma) override { std::vector sigmas; @@ -355,27 +363,29 @@ struct KLOptimalScheduler : SigmaScheduler { if (n == 0) { return sigmas; } + if (n == 1) { sigmas.push_back(sigma_max); sigmas.push_back(0.0f); return sigmas; } + if (sigma_min <= 1e-6f) { + sigma_min = 1e-6f; + } + + sigmas.reserve(n + 1); + float alpha_min = std::atan(sigma_min); float alpha_max = std::atan(sigma_max); for (uint32_t i = 0; i < n; ++i) { - // t goes from 0.0 to 1.0 - float t = static_cast(i) / static_cast(n - 1); - // Interpolate in the angle domain + float t = static_cast(i) / static_cast(n - 1); float angle = t * alpha_min + (1.0f - t) * alpha_max; - - // Convert back to sigma sigmas.push_back(std::tan(angle)); } - // Append the final zero to sigma sigmas.push_back(0.0f); return sigmas;