12 Step |
概要
CPU向きの低ステップサンプラーです。リアルモデルで9ステップぐらいから使えます。
Eulerの絵は柔らかい感じの絵なので、途中からDPM++ 2Mに変えて少しパキッとした絵になるサンプラーにしました。
7 StepまではEuler Karrasと同じ絵になります。
あわせて読みたい
【WebUI 1111】低ステップ最強サンプラー Euler karras 追加方法 【Stable diffusion】
DPM++ 2Mは下記のサイトを参考に低ステップ向きに改良しています。
https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/8457
https://scrapbox.io/work4ai/hallatore%E6%B0%8F%E6%94%B9%E8%89%AF%E7%89%88DPM++_2M_Karras
追加方法
stable-diffusion-webui\modules\sd_samplers_kdiffusion.py の samplers_k_diffusionに下記の行を追加します。
('DPM++ 2M Karras test mix', 'sample_dpmpp_2m_test_mix', ['k_dpmpp_2m_ka'], {'scheduler': 'karras',}),
stable-diffusion-webui\repositories\k-diffusion\k_diffusion\sampling.pyの最後に下記のコードを追加します。
@torch.no_grad()def sample_dpmpp_2m_test_mix(model, x, sigmas, extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.):"""DPM-Solver++(2M) SDE."""extra_args = {} if extra_args is None else extra_argss_in = x.new_ones([x.shape[0]])sigma_fn = lambda t: t.neg().exp()t_fn = lambda sigma: sigma.log().neg()old_denoised = Noneh = Noneold_r = None#7stepまでEuler karrasと同じeulr = 5for i in trange(len(sigmas) - 1, disable=disable):if(i <= eulr):gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1) if s_tmin <= sigmas[i] <= s_tmax else 0.eps = torch.randn_like(x) * s_noisesigma_hat = sigmas[i] * (gamma + 1)if gamma > 0:x = x + eps * (sigma_hat ** 2 - sigmas[i] ** 2) ** 0.5denoised = model(x, sigma_hat * s_in, **extra_args)d = to_d(x, sigma_hat, denoised)if callback is not None:callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, 'denoised': denoised})dt = sigmas[i + 1] - sigma_hat# Euler methodx = x + d * dtsigma_progress = i / len(sigmas)adjustment_factor = 1 - (0.14 * (sigma_progress * sigma_progress))old_denoised = denoised * adjustment_factorelse:denoised = model(x, sigmas[i] * s_in, **extra_args)if callback is not None:callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised})t, t_next = t_fn(sigmas[i]), t_fn(sigmas[i + 1])h = t_next - tt_min = min(sigma_fn(t_next), sigma_fn(t))t_max = max(sigma_fn(t_next), sigma_fn(t))if old_denoised is None or sigmas[i + 1] == 0:x = (t_min / t_max) * x - (-h).expm1() * denoisedold_r = Noneelse:h_last = t - t_fn(sigmas[i - 1])h_min = min(h_last, h)h_max = max(h_last, h)r = h_max / h_minif old_r is None:old_r = rh_d = hdenoised_d = (1 + 1 / (2 * r)) * denoised - (1 / (2 * r)) * old_denoisedx = (t_min / t_max) * x - (-h_d).expm1() * denoised_dold_r = r#test new samplersigma_progress = i / len(sigmas)adjustment_factor = 1 - (0.14 * (sigma_progress * sigma_progress))old_denoised = denoised * adjustment_factorreturn x
再起動とリロードすると DPM++ 2M Karras test mix が追加されます。
参考画像
アニメモデル
12 Step |
9 Step |
リアルモデル
12 Step |
目が少し変なのはモデルの特徴だと思う。アップスケールすると治るかも。
12 Step |