Merge pull request #7730 from CCRcmcpe/fix-dpm-sde-batch
Fix DPM++ SDE not deterministic across different batch sizes (#5210)
This commit is contained in:
commit
a77ac2eeaa
@ -269,6 +269,16 @@ class KDiffusionSampler:
|
|||||||
|
|
||||||
return sigmas
|
return sigmas
|
||||||
|
|
||||||
|
def create_noise_sampler(self, x, sigmas, p):
|
||||||
|
"""For DPM++ SDE: manually create noise sampler to enable deterministic results across different batch sizes"""
|
||||||
|
if shared.opts.no_dpmpp_sde_batch_determinism:
|
||||||
|
return None
|
||||||
|
|
||||||
|
from k_diffusion.sampling import BrownianTreeNoiseSampler
|
||||||
|
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max()
|
||||||
|
current_iter_seeds = p.all_seeds[p.iteration * p.batch_size:(p.iteration + 1) * p.batch_size]
|
||||||
|
return BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=current_iter_seeds)
|
||||||
|
|
||||||
def sample_img2img(self, p, x, noise, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
|
def sample_img2img(self, p, x, noise, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
|
||||||
steps, t_enc = sd_samplers_common.setup_img2img_steps(p, steps)
|
steps, t_enc = sd_samplers_common.setup_img2img_steps(p, steps)
|
||||||
|
|
||||||
@ -278,18 +288,24 @@ class KDiffusionSampler:
|
|||||||
xi = x + noise * sigma_sched[0]
|
xi = x + noise * sigma_sched[0]
|
||||||
|
|
||||||
extra_params_kwargs = self.initialize(p)
|
extra_params_kwargs = self.initialize(p)
|
||||||
if 'sigma_min' in inspect.signature(self.func).parameters:
|
parameters = inspect.signature(self.func).parameters
|
||||||
|
|
||||||
|
if 'sigma_min' in parameters:
|
||||||
## last sigma is zero which isn't allowed by DPM Fast & Adaptive so taking value before last
|
## last sigma is zero which isn't allowed by DPM Fast & Adaptive so taking value before last
|
||||||
extra_params_kwargs['sigma_min'] = sigma_sched[-2]
|
extra_params_kwargs['sigma_min'] = sigma_sched[-2]
|
||||||
if 'sigma_max' in inspect.signature(self.func).parameters:
|
if 'sigma_max' in parameters:
|
||||||
extra_params_kwargs['sigma_max'] = sigma_sched[0]
|
extra_params_kwargs['sigma_max'] = sigma_sched[0]
|
||||||
if 'n' in inspect.signature(self.func).parameters:
|
if 'n' in parameters:
|
||||||
extra_params_kwargs['n'] = len(sigma_sched) - 1
|
extra_params_kwargs['n'] = len(sigma_sched) - 1
|
||||||
if 'sigma_sched' in inspect.signature(self.func).parameters:
|
if 'sigma_sched' in parameters:
|
||||||
extra_params_kwargs['sigma_sched'] = sigma_sched
|
extra_params_kwargs['sigma_sched'] = sigma_sched
|
||||||
if 'sigmas' in inspect.signature(self.func).parameters:
|
if 'sigmas' in parameters:
|
||||||
extra_params_kwargs['sigmas'] = sigma_sched
|
extra_params_kwargs['sigmas'] = sigma_sched
|
||||||
|
|
||||||
|
if self.funcname == 'sample_dpmpp_sde':
|
||||||
|
noise_sampler = self.create_noise_sampler(x, sigmas, p)
|
||||||
|
extra_params_kwargs['noise_sampler'] = noise_sampler
|
||||||
|
|
||||||
self.model_wrap_cfg.init_latent = x
|
self.model_wrap_cfg.init_latent = x
|
||||||
self.last_latent = x
|
self.last_latent = x
|
||||||
extra_args={
|
extra_args={
|
||||||
@ -303,7 +319,7 @@ class KDiffusionSampler:
|
|||||||
|
|
||||||
return samples
|
return samples
|
||||||
|
|
||||||
def sample(self, p, x, conditioning, unconditional_conditioning, steps=None, image_conditioning = None):
|
def sample(self, p, x, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
|
||||||
steps = steps or p.steps
|
steps = steps or p.steps
|
||||||
|
|
||||||
sigmas = self.get_sigmas(p, steps)
|
sigmas = self.get_sigmas(p, steps)
|
||||||
@ -311,14 +327,20 @@ class KDiffusionSampler:
|
|||||||
x = x * sigmas[0]
|
x = x * sigmas[0]
|
||||||
|
|
||||||
extra_params_kwargs = self.initialize(p)
|
extra_params_kwargs = self.initialize(p)
|
||||||
if 'sigma_min' in inspect.signature(self.func).parameters:
|
parameters = inspect.signature(self.func).parameters
|
||||||
|
|
||||||
|
if 'sigma_min' in parameters:
|
||||||
extra_params_kwargs['sigma_min'] = self.model_wrap.sigmas[0].item()
|
extra_params_kwargs['sigma_min'] = self.model_wrap.sigmas[0].item()
|
||||||
extra_params_kwargs['sigma_max'] = self.model_wrap.sigmas[-1].item()
|
extra_params_kwargs['sigma_max'] = self.model_wrap.sigmas[-1].item()
|
||||||
if 'n' in inspect.signature(self.func).parameters:
|
if 'n' in parameters:
|
||||||
extra_params_kwargs['n'] = steps
|
extra_params_kwargs['n'] = steps
|
||||||
else:
|
else:
|
||||||
extra_params_kwargs['sigmas'] = sigmas
|
extra_params_kwargs['sigmas'] = sigmas
|
||||||
|
|
||||||
|
if self.funcname == 'sample_dpmpp_sde':
|
||||||
|
noise_sampler = self.create_noise_sampler(x, sigmas, p)
|
||||||
|
extra_params_kwargs['noise_sampler'] = noise_sampler
|
||||||
|
|
||||||
self.last_latent = x
|
self.last_latent = x
|
||||||
samples = self.launch_sampling(steps, lambda: self.func(self.model_wrap_cfg, x, extra_args={
|
samples = self.launch_sampling(steps, lambda: self.func(self.model_wrap_cfg, x, extra_args={
|
||||||
'cond': conditioning,
|
'cond': conditioning,
|
||||||
|
@ -414,6 +414,7 @@ options_templates.update(options_section(('sd', "Stable Diffusion"), {
|
|||||||
options_templates.update(options_section(('compatibility', "Compatibility"), {
|
options_templates.update(options_section(('compatibility', "Compatibility"), {
|
||||||
"use_old_emphasis_implementation": OptionInfo(False, "Use old emphasis implementation. Can be useful to reproduce old seeds."),
|
"use_old_emphasis_implementation": OptionInfo(False, "Use old emphasis implementation. Can be useful to reproduce old seeds."),
|
||||||
"use_old_karras_scheduler_sigmas": OptionInfo(False, "Use old karras scheduler sigmas (0.1 to 10)."),
|
"use_old_karras_scheduler_sigmas": OptionInfo(False, "Use old karras scheduler sigmas (0.1 to 10)."),
|
||||||
|
"no_dpmpp_sde_batch_determinism": OptionInfo(False, "Do not make DPM++ SDE deterministic across different batch sizes."),
|
||||||
"use_old_hires_fix_width_height": OptionInfo(False, "For hires fix, use width/height sliders to set final resolution rather than first pass (disables Upscale by, Resize width/height to)."),
|
"use_old_hires_fix_width_height": OptionInfo(False, "For hires fix, use width/height sliders to set final resolution rather than first pass (disables Upscale by, Resize width/height to)."),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user