| import torch |
| import k_diffusion.sampling |
| from k_diffusion.sampling import to_d, default_noise_sampler, get_ancestral_step |
| from tqdm.auto import trange |
| from modules import sd_samplers, sd_samplers_common, sd_samplers_kdiffusion |
|
|
| _SAMPLER_REGISTERED = False |
|
|
|
|
| @torch.no_grad() |
| def sample_kohaku_lonyu_yog(model, x, sigmas, extra_args=None, callback=None, |
| disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), |
| s_noise=1., noise_sampler=None, eta=1.): |
| """ |
| Kohaku_LoNyu_Yog Sampler - Geometric Second-Order Method |
| """ |
| extra_args = {} if extra_args is None else extra_args |
| s_in = x.new_ones([x.shape[0]]) |
| noise_sampler = default_noise_sampler(x) if noise_sampler is None else noise_sampler |
|
|
| steps_total = len(sigmas) - 1 |
| halfway_point = steps_total // 2 |
|
|
| for i in trange(steps_total, disable=disable, desc="Kohaku Sampling"): |
| gamma = min(s_churn / steps_total, 2 ** 0.5 - 1) if s_tmin <= sigmas[i] <= s_tmax else 0. |
| sigma_hat = sigmas[i] * (gamma + 1) |
|
|
| if gamma > 0: |
| eps = torch.randn_like(x) * s_noise |
| x = x + eps * (sigma_hat ** 2 - sigmas[i] ** 2) ** 0.5 |
|
|
| denoised = model(x, sigma_hat * s_in, **extra_args) |
| d = to_d(x, sigma_hat, denoised) |
|
|
| sigma_down, sigma_up = get_ancestral_step(sigmas[i], sigmas[i + 1], eta=eta) |
| dt = sigma_down - sigmas[i] |
|
|
| if i <= halfway_point: |
| x_antipode = -x |
|
|
| denoised2 = model(x_antipode, sigma_hat * s_in, **extra_args) |
| d2 = to_d(x_antipode, sigma_hat, denoised2) |
|
|
| v_down = (d + d2) / 2 |
| x_closer = x + v_down * dt |
|
|
| denoised3 = model(x_closer, sigma_hat * s_in, **extra_args) |
| d3 = to_d(x_closer, sigma_hat, denoised3) |
|
|
| real_d = (d + d3) / 2 |
| x = x + real_d * dt |
|
|
| if sigma_up > 0: |
| x = x + noise_sampler(sigmas[i], sigmas[i + 1]) * s_noise * sigma_up |
| else: |
| x = x + d * dt |
| if sigma_up > 0: |
| x = x + noise_sampler(sigmas[i], sigmas[i + 1]) * s_noise * sigma_up |
|
|
| if callback is not None: |
| callback({ |
| 'x': x, |
| 'i': i, |
| 'sigma': sigmas[i], |
| 'sigma_hat': sigma_hat, |
| 'denoised': denoised |
| }) |
|
|
| return x |
|
|
|
|
| def register_kohaku_sampler(): |
| """Регистрирует Kohaku_LoNyu_Yog сэмплер в WebUI""" |
| global _SAMPLER_REGISTERED |
|
|
| if _SAMPLER_REGISTERED: |
| return |
|
|
| if any(s.name == 'Kohaku_LoNyu_Yog' for s in sd_samplers.all_samplers): |
| _SAMPLER_REGISTERED = True |
| return |
|
|
| if not hasattr(k_diffusion.sampling, 'sample_kohaku_lonyu_yog'): |
| setattr(k_diffusion.sampling, 'sample_kohaku_lonyu_yog', sample_kohaku_lonyu_yog) |
|
|
| sampler_data = sd_samplers_common.SamplerData( |
| name='Kohaku_LoNyu_Yog', |
| constructor=lambda model: sd_samplers_kdiffusion.KDiffusionSampler('sample_kohaku_lonyu_yog', model), |
| aliases=['kohaku', 'lonyu'], |
| options={'second_order': True} |
| ) |
|
|
| sd_samplers.all_samplers.append(sampler_data) |
| sd_samplers.all_samplers_map = {x.name: x for x in sd_samplers.all_samplers} |
|
|
| _SAMPLER_REGISTERED = True |
| print("✓ Kohaku_LoNyu_Yog sampler registered successfully!") |
|
|