From 0a3b65919e5d082e723dcba6f0677cf75daa66b2 Mon Sep 17 00:00:00 2001 From: Wagner Bruna Date: Tue, 31 Mar 2026 19:35:32 -0300 Subject: [PATCH] refactor: centralize CompVisDenoiser table calculations --- src/denoiser.hpp | 112 +++++++++++++++++++++------------------ src/stable-diffusion.cpp | 23 ++------ 2 files changed, 63 insertions(+), 72 deletions(-) diff --git a/src/denoiser.hpp b/src/denoiser.hpp index 1629b1a8e..2f8775f09 100644 --- a/src/denoiser.hpp +++ b/src/denoiser.hpp @@ -549,8 +549,48 @@ struct Denoiser { }; struct CompVisDenoiser : public Denoiser { - float sigmas[TIMESTEPS]; - float log_sigmas[TIMESTEPS]; + +private: + struct Constants { + const float beta_start = 0.00085f; + const float beta_end = 0.0120f; + float alphas_cumprods[TIMESTEPS]; + float sigmas[TIMESTEPS]; + float log_sigmas[TIMESTEPS]; + Constants() { + double ls_sqrt = std::sqrt(static_cast(beta_start)); + double le_sqrt = std::sqrt(static_cast(beta_end)); + double step = (le_sqrt - ls_sqrt) / (TIMESTEPS - 1); + double alphas_cumprod = 1.0; + + for (int i = 0; i < TIMESTEPS; ++i) { + double sqrt_beta = ls_sqrt + step * i; + alphas_cumprod *= (1.0 - (sqrt_beta * sqrt_beta)); + double sigma = std::sqrt((1.0 - alphas_cumprod) / alphas_cumprod); + alphas_cumprods[i] = static_cast(alphas_cumprod); + sigmas[i] = static_cast(sigma); + log_sigmas[i] = static_cast(std::log(sigma)); + } + } + static const Constants& get_instance() { + static Constants instance; + return instance; + } + }; + + const float *sigmas = get_sigmas(); + const float *log_sigmas = get_log_sigmas(); + +public: + static const float* get_sigmas() { + return Constants::get_instance().sigmas; + } + static const float* get_log_sigmas() { + return Constants::get_instance().log_sigmas; + } + static const float* get_alphas_cumprods() { + return Constants::get_instance().alphas_cumprods; + } float sigma_data = 1.0f; @@ -564,20 +604,12 @@ struct CompVisDenoiser : public Denoiser { float sigma_to_t(float sigma) override { float log_sigma = std::log(sigma); - std::vector dists; - dists.reserve(TIMESTEPS); - for (float log_sigma_val : log_sigmas) { - dists.push_back(log_sigma - log_sigma_val); - } + const float* high_ptr = std::upper_bound(log_sigmas, log_sigmas + TIMESTEPS, log_sigma); - int low_idx = 0; - for (size_t i = 0; i < TIMESTEPS; i++) { - if (dists[i] >= 0) { - low_idx++; - } - } - low_idx = std::min(std::max(low_idx - 1, 0), TIMESTEPS - 2); - int high_idx = low_idx + 1; + int high_idx = static_cast(high_ptr - log_sigmas); + int low_idx = high_idx - 1; + low_idx = std::clamp(low_idx, 0, TIMESTEPS - 2); + high_idx = low_idx + 1; float low = log_sigmas[low_idx]; float high = log_sigmas[high_idx]; @@ -1242,27 +1274,15 @@ static sd::Tensor sample_ddim_trailing(denoise_cb_t model, const std::vector& sigmas, std::shared_ptr rng, float eta) { - float beta_start = 0.00085f; - float beta_end = 0.0120f; - std::vector alphas_cumprod(TIMESTEPS); - std::vector compvis_sigmas(TIMESTEPS); - for (int i = 0; i < TIMESTEPS; i++) { - alphas_cumprod[i] = - (i == 0 ? 1.0f : alphas_cumprod[i - 1]) * - (1.0f - - std::pow(sqrtf(beta_start) + - (sqrtf(beta_end) - sqrtf(beta_start)) * - ((float)i / (TIMESTEPS - 1)), - 2)); - compvis_sigmas[i] = - std::sqrt((1 - alphas_cumprod[i]) / alphas_cumprod[i]); - } + + const float* alphas_cumprod = CompVisDenoiser::get_alphas_cumprods(); + const float* compvis_sigmas = CompVisDenoiser::get_sigmas(); int steps = static_cast(sigmas.size()) - 1; for (int i = 0; i < steps; i++) { int timestep = static_cast(roundf(TIMESTEPS - i * ((float)TIMESTEPS / steps))) - 1; int prev_timestep = timestep - TIMESTEPS / steps; - float sigma = static_cast(compvis_sigmas[timestep]); + float sigma = compvis_sigmas[timestep]; if (i == 0) { x *= std::sqrt(sigma * sigma + 1) / sigma; } else { @@ -1276,8 +1296,8 @@ static sd::Tensor sample_ddim_trailing(denoise_cb_t model, sd::Tensor model_output = std::move(model_output_opt); model_output = (x - model_output) * (1.0f / sigma); - float alpha_prod_t = static_cast(alphas_cumprod[timestep]); - float alpha_prod_t_prev = static_cast(prev_timestep >= 0 ? alphas_cumprod[prev_timestep] : alphas_cumprod[0]); + float alpha_prod_t = alphas_cumprod[timestep]; + float alpha_prod_t_prev = prev_timestep >= 0 ? alphas_cumprod[prev_timestep] : alphas_cumprod[0]; float beta_prod_t = 1.0f - alpha_prod_t; sd::Tensor pred_original_sample = ((x / std::sqrt(sigma * sigma + 1)) - @@ -1304,21 +1324,9 @@ static sd::Tensor sample_tcd(denoise_cb_t model, const std::vector& sigmas, std::shared_ptr rng, float eta) { - float beta_start = 0.00085f; - float beta_end = 0.0120f; - std::vector alphas_cumprod(TIMESTEPS); - std::vector compvis_sigmas(TIMESTEPS); - for (int i = 0; i < TIMESTEPS; i++) { - alphas_cumprod[i] = - (i == 0 ? 1.0f : alphas_cumprod[i - 1]) * - (1.0f - - std::pow(sqrtf(beta_start) + - (sqrtf(beta_end) - sqrtf(beta_start)) * - ((float)i / (TIMESTEPS - 1)), - 2)); - compvis_sigmas[i] = - std::sqrt((1 - alphas_cumprod[i]) / alphas_cumprod[i]); - } + + const float* alphas_cumprod = CompVisDenoiser::get_alphas_cumprods(); + const float* compvis_sigmas = CompVisDenoiser::get_sigmas(); int original_steps = 50; int steps = static_cast(sigmas.size()) - 1; @@ -1326,7 +1334,7 @@ static sd::Tensor sample_tcd(denoise_cb_t model, int timestep = TIMESTEPS - 1 - (TIMESTEPS / original_steps) * (int)floor(i * ((float)original_steps / steps)); int prev_timestep = i >= steps - 1 ? 0 : TIMESTEPS - 1 - (TIMESTEPS / original_steps) * (int)floor((i + 1) * ((float)original_steps / steps)); int timestep_s = (int)floor((1 - eta) * prev_timestep); - float sigma = static_cast(compvis_sigmas[timestep]); + float sigma = compvis_sigmas[timestep]; if (i == 0) { x *= std::sqrt(sigma * sigma + 1) / sigma; @@ -1341,10 +1349,10 @@ static sd::Tensor sample_tcd(denoise_cb_t model, sd::Tensor model_output = std::move(model_output_opt); model_output = (x - model_output) * (1.0f / sigma); - float alpha_prod_t = static_cast(alphas_cumprod[timestep]); + float alpha_prod_t = alphas_cumprod[timestep]; float beta_prod_t = 1.0f - alpha_prod_t; - float alpha_prod_t_prev = static_cast(prev_timestep >= 0 ? alphas_cumprod[prev_timestep] : alphas_cumprod[0]); - float alpha_prod_s = static_cast(alphas_cumprod[timestep_s]); + float alpha_prod_t_prev = prev_timestep >= 0 ? alphas_cumprod[prev_timestep] : alphas_cumprod[0]; + float alpha_prod_s = alphas_cumprod[timestep_s]; float beta_prod_s = 1.0f - alpha_prod_s; sd::Tensor pred_original_sample = ((x / std::sqrt(sigma * sigma + 1)) - diff --git a/src/stable-diffusion.cpp b/src/stable-diffusion.cpp index 093bed20e..214701b57 100644 --- a/src/stable-diffusion.cpp +++ b/src/stable-diffusion.cpp @@ -73,19 +73,9 @@ const char* sampling_methods_str[] = { /*================================================== Helper Functions ================================================*/ -void calculate_alphas_cumprod(float* alphas_cumprod, - float linear_start = 0.00085f, - float linear_end = 0.0120f, - int timesteps = TIMESTEPS) { - float ls_sqrt = sqrtf(linear_start); - float le_sqrt = sqrtf(linear_end); - float amount = le_sqrt - ls_sqrt; - float product = 1.0f; - for (int i = 0; i < timesteps; i++) { - float beta = ls_sqrt + amount * ((float)i / (timesteps - 1)); - product *= 1.0f - powf(beta, 2.0f); - alphas_cumprod[i] = product; - } +void calculate_alphas_cumprod(float* alphas_cumprod) { + const float * src = CompVisDenoiser::get_alphas_cumprods(); + std::copy(src, src + TIMESTEPS, alphas_cumprod); } static float get_cache_reuse_threshold(const sd_cache_params_t& params) { @@ -980,13 +970,6 @@ class StableDiffusionGGML { } } - auto comp_vis_denoiser = std::dynamic_pointer_cast(denoiser); - if (comp_vis_denoiser) { - for (int i = 0; i < TIMESTEPS; i++) { - comp_vis_denoiser->sigmas[i] = std::sqrt((1 - ((float*)alphas_cumprod_tensor->data)[i]) / ((float*)alphas_cumprod_tensor->data)[i]); - comp_vis_denoiser->log_sigmas[i] = std::log(comp_vis_denoiser->sigmas[i]); - } - } } ggml_free(ctx);