refactor schedulers first part

This commit is contained in:
Vladimir Mandic
2023-09-21 13:19:55 -04:00
parent 36324361bd
commit 4518cfb3b1
12 changed files with 50 additions and 53 deletions
+2 -3
View File
@@ -270,10 +270,9 @@ infotext_to_setting_name_mapping = [
('Parser', 'prompt_attention'),
('ENSD', 'eta_noise_seed_delta'),
('Noise multiplier', 'initial_noise_multiplier'),
('Eta', 'eta_ancestral'),
('Eta DDIM', 'eta_ddim'),
('Eta', 'scheduler_eta'),
('LoRA method', 'diffusers_lora_loader'),
('Discard penultimate sigma', 'always_discard_next_to_last_sigma'),
('Discard penultimate sigma', 'discard_next_to_last_sigma'),
('UniPC variant', 'uni_pc_variant'),
('UniPC skip type', 'uni_pc_skip_type'),
('UniPC order', 'schedulers_solver_order'),
+2 -2
View File
@@ -25,7 +25,7 @@ def calculate_sha256(filename, quiet=False):
hash_sha256 = hashlib.sha256()
blksize = 1024 * 1024
if not quiet:
with progress.open(filename, 'rb', description=f'Calculating hash: [cyan]{filename}', auto_refresh=True, console=shared.console) as f:
with progress.open(filename, 'rb', description=f'[cyan]Calculating hash: [yellow]{filename}', auto_refresh=True, console=shared.console) as f:
for chunk in iter(lambda: f.read(blksize), b""):
hash_sha256.update(chunk)
else:
@@ -58,7 +58,7 @@ def sha256(filename, title, use_addnet_hash=False):
return None
shared.state.begin("hashing")
if use_addnet_hash:
with progress.open(filename, 'rb', description=f'Calculating hash: [cyan]{filename}', auto_refresh=True, console=shared.console) as f:
with progress.open(filename, 'rb', description=f'[cyan]Calculating hash: [yellow]{filename}', auto_refresh=True, console=shared.console) as f:
sha256_value = addnet_hash_safetensors(f)
else:
sha256_value = calculate_sha256(filename)
+1 -1
View File
@@ -1045,7 +1045,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
else:
image_conditioning = self.txt2img_image_conditioning(samples.to(dtype=devices.dtype_vae))
if self.latent_sampler == "PLMS":
self.latent_sampler = 'UniPC'
self.latent_sampler = 'UniPC'
if self.hr_force or latent_scale_mode is not None:
if self.denoising_strength > 0:
self.ops.append('hires')
+4 -4
View File
@@ -343,7 +343,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
prompts_2=[p.refiner_prompt] if len(p.refiner_prompt) > 0 else prompts,
negative_prompts_2=[p.refiner_negative] if len(p.refiner_negative) > 0 else negative_prompts,
num_inference_steps=calculate_base_steps(),
eta=shared.opts.eta_ddim,
eta=shared.opts.scheduler_eta,
guidance_rescale=p.diffusers_guidance_rescale,
denoising_start=0 if use_refiner_start else p.refiner_start if use_denoise_start else None,
denoising_end=p.refiner_start if use_refiner_start else 1 if use_denoise_start else None,
@@ -353,7 +353,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
**task_specific_kwargs
)
p.extra_generation_params['CFG rescale'] = p.diffusers_guidance_rescale
p.extra_generation_params["Eta DDIM"] = shared.opts.eta_ddim if shared.opts.eta_ddim is not None and shared.opts.eta_ddim > 0 else None
p.extra_generation_params["Eta"] = shared.opts.scheduler_eta if shared.opts.scheduler_eta is not None and shared.opts.scheduler_eta > 0 else None
try:
output = shared.sd_model(**base_args) # pylint: disable=not-callable
except AssertionError as e:
@@ -395,7 +395,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
prompts_2=[p.refiner_prompt] if len(p.refiner_prompt) > 0 else prompts,
negative_prompts_2=[p.refiner_negative] if len(p.refiner_negative) > 0 else negative_prompts,
num_inference_steps=int(p.hr_second_pass_steps // p.denoising_strength + 1),
eta=shared.opts.eta_ddim,
eta=shared.opts.scheduler_eta,
guidance_scale=p.image_cfg_scale if p.image_cfg_scale is not None else p.cfg_scale,
guidance_rescale=p.diffusers_guidance_rescale,
output_type='latent' if hasattr(shared.sd_model, 'vae') else 'np',
@@ -448,7 +448,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
prompts=[p.refiner_prompt] if len(p.refiner_prompt) > 0 else prompts[i],
negative_prompts=[p.refiner_negative] if len(p.refiner_negative) > 0 else negative_prompts[i],
num_inference_steps=int(p.refiner_steps // (1 - p.refiner_start)) if p.refiner_start > 0 and p.refiner_start < 1 and refiner_is_sdxl else int(p.refiner_steps // p.denoising_strength + 1) if refiner_is_sdxl else p.refiner_steps,
eta=shared.opts.eta_ddim,
eta=shared.opts.scheduler_eta,
strength=p.denoising_strength,
guidance_scale=p.image_cfg_scale if p.image_cfg_scale is not None else p.cfg_scale,
guidance_rescale=p.diffusers_guidance_rescale,
+1 -1
View File
@@ -617,7 +617,7 @@ def detect_pipeline(f: str, op: str = 'model'):
guess = 'Unknown'
shared.log.error(f'Model autodetect failed, set diffuser pipeline manually: {f}')
return None, None
shared.log.debug(f'Model autodetect {op}: {f} pipeline={guess} size={size} GB')
shared.log.debug(f'Model autodetect: {op}="{f}" pipeline="{guess}" size={size} GB')
except Exception as e:
shared.log.error(f'Error detecting diffusers pipeline: model={f} {e}')
return None, None
+4 -8
View File
@@ -61,14 +61,10 @@ def create_sampler(name, model):
def set_samplers():
global samplers, samplers_for_img2img # pylint: disable=global-statement
shown = shared.opts.show_samplers
if type(shown) is not list or len(shown) == 0:
shown = ['UniPC']
shown_img2img = set(shown)
shown = set(shown + ['PLMS'])
samplers = [x for x in all_samplers if x.name in shown]
samplers_for_img2img = [x for x in all_samplers if x.name in shown_img2img]
global samplers # pylint: disable=global-statement
global samplers_for_img2img # pylint: disable=global-statement
samplers = [x for x in all_samplers if x.name in shared.opts.show_samplers] if len(shared.opts.show_samplers) > 0 else all_samplers
samplers_for_img2img = [x for x in samplers if x.name != "PLMS"]
samplers_map.clear()
for sampler in all_samplers:
samplers_map[sampler.name.lower()] = sampler.name
+1 -1
View File
@@ -132,7 +132,7 @@ class VanillaStableDiffusionSampler:
def initialize(self, p):
if self.is_ddim:
self.eta = p.eta if p.eta is not None else shared.opts.eta_ddim
self.eta = p.eta if p.eta is not None else shared.opts.scheduler_eta
else:
self.eta = 0.0
if self.eta != 0.0:
+8 -6
View File
@@ -282,7 +282,7 @@ class KDiffusionSampler:
self.model_wrap_cfg.nmask = p.nmask if hasattr(p, 'nmask') else None
self.model_wrap_cfg.step = 0
self.model_wrap_cfg.image_cfg_scale = getattr(p, 'image_cfg_scale', None)
self.eta = p.eta if p.eta is not None else opts.eta_ancestral
self.eta = p.eta if p.eta is not None else opts.scheduler_eta
self.s_min_uncond = getattr(p, 's_min_uncond', 0.0)
k_diffusion.sampling.torch = TorchHijack(self.sampler_noises if self.sampler_noises is not None else [])
@@ -301,13 +301,15 @@ class KDiffusionSampler:
return extra_params_kwargs
def get_sigmas(self, p, steps):
discard_next_to_last_sigma = self.config is not None and self.config.options.get('discard_next_to_last_sigma', False)
if opts.always_discard_next_to_last_sigma:
if opts.discard_next_to_last_sigma == 'always':
discard_next_to_last_sigma = True
p.extra_generation_params["Discard penultimate sigma"] = True
if opts.never_discard_next_to_last_sigma:
p.extra_generation_params["Discard penultimate sigma"] = 'always'
elif opts.discard_next_to_last_sigma == 'never':
discard_next_to_last_sigma = False
p.extra_generation_params["Discard penultimate sigma"] = False
p.extra_generation_params["Discard penultimate sigma"] = 'never'
else:
discard_next_to_last_sigma = self.config is not None and self.config.options.get('discard_next_to_last_sigma', False)
steps += 1 if discard_next_to_last_sigma else 0
if p.sampler_noise_scheduler_override:
+5 -5
View File
@@ -147,12 +147,12 @@ def load_vae(model, vae_file=None, vae_source="unknown-source"):
if vae_file:
if cache_enabled and vae_file in checkpoints_loaded:
# use vae checkpoint cache
shared.log.info(f"Loading VAE weights: {get_filename(vae_file)} source={vae_source} cached=True")
shared.log.info(f"Loading VAE: model={get_filename(vae_file)} source={vae_source} cached=True")
store_base_vae(model)
_load_vae_dict(model, checkpoints_loaded[vae_file])
else:
if not os.path.isfile(vae_file):
shared.log.error(f"VAE doesn't exist: {vae_file} source={vae_source}")
shared.log.error(f"VAE not found: model={vae_file} source={vae_source}")
return
store_base_vae(model)
vae_dict_1 = load_vae_dict(vae_file)
@@ -178,9 +178,9 @@ def load_vae_diffusers(model_file, vae_file=None, vae_source="unknown-source"):
if vae_file is None:
return None
if not os.path.exists(vae_file):
shared.log.error(f'VAE not found: {vae_file}')
shared.log.error(f'VAE not found: model{vae_file}')
return None
shared.log.info(f"Loading diffusers VAE: {vae_file} source={vae_source}")
shared.log.info(f"Loading VAE: model={vae_file} source={vae_source}")
diffusers_load_config = {
"low_cpu_mem_usage": False,
"torch_dtype": devices.dtype_vae,
@@ -210,7 +210,7 @@ def load_vae_diffusers(model_file, vae_file=None, vae_source="unknown-source"):
# shared.log.debug(f'Diffusers VAE config: {vae.config}')
return vae
except Exception as e:
shared.log.error(f"Loading diffusers VAE failed: {vae_file} {e}")
shared.log.error(f"Loading VAE failed: model={vae_file} {e}")
return None
+1 -1
View File
@@ -44,7 +44,7 @@ def model():
sd_vae_approx_model.load_state_dict(torch.load(model_path, map_location='cpu' if devices.device.type != 'cuda' else None))
sd_vae_approx_model.eval()
sd_vae_approx_model.to(devices.device, devices.dtype)
log.info(f"Loaded VAE-approx model: {model_path}")
log.info(f"Loaded VAE-approx: model={model_path}")
return sd_vae_approx_model
+19 -19
View File
@@ -563,33 +563,33 @@ options_templates.update(options_section(('live-preview', "Live Previews"), {
}))
options_templates.update(options_section(('sampler-params', "Sampler Settings"), {
"show_samplers": OptionInfo(["Default", "Euler a", "UniPC", "DEIS", "DDIM", "DPM 1S", "DPM 2M", "DPM SDE", "DPM++ 2M SDE", "DPM++ 2M SDE Karras", "DPM2 Karras", "DPM++ 2M Karras"], "Show samplers in user interface", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers() if x.name != "PLMS"]}),
"show_samplers": OptionInfo([], "Show samplers in user interface", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers()]}),
'uni_pc_variant': OptionInfo("bh1", "UniPC variant", gr.Radio, {"choices": ["bh1", "bh2", "vary_coeff"]}),
'uni_pc_skip_type': OptionInfo("time_uniform", "UniPC skip type", gr.Radio, {"choices": ["time_uniform", "time_quadratic", "logSNR"]}),
'eta_noise_seed_delta': OptionInfo(0, "Noise seed delta (eta)", gr.Number, {"precision": 0}),
"eta_ddim": OptionInfo(0.0, "Noise multiplier for DDIM (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"schedulers_solver_order": OptionInfo(2, "Samplers solver order where applicable", gr.Slider, {"minimum": 1, "maximum": 5, "step": 1}),
"scheduler_eta": OptionInfo(1.0, "Noise multiplier (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"schedulers_solver_order": OptionInfo(2, "Solver order (where applicable)", gr.Slider, {"minimum": 1, "maximum": 5, "step": 1}),
"schedulers_sep_diffusers": OptionInfo("<h2>Diffusers specific config</h2>", "", gr.HTML),
"schedulers_prediction_type": OptionInfo("default", "Samplers override model prediction type", gr.Radio, lambda: {"choices": ['default', 'epsilon', 'sample', 'v-prediction']}),
"schedulers_use_karras": OptionInfo(True, "Samplers use Karras sigmas where applicable"),
"schedulers_use_loworder": OptionInfo(True, "Samplers use simplified solvers in final steps where applicable"),
"schedulers_use_thresholding": OptionInfo(False, "Samplers use dynamic thresholding where applicable"),
"schedulers_dpm_solver": OptionInfo("sde-dpmsolver++", "Samplers DPM solver algorithm", gr.Radio, lambda: {"choices": ['dpmsolver', 'dpmsolver++', 'sde-dpmsolver', 'sde-dpmsolver++']}),
"schedulers_beta_schedule": OptionInfo("default", "Samplers override beta schedule", gr.Radio, lambda: {"choices": ['default', 'linear', 'scaled_linear', 'squaredcos_cap_v2']}),
'schedulers_beta_start': OptionInfo(0, "Samplers override beta start", gr.Number, {}),
'schedulers_beta_end': OptionInfo(0, "Samplers override beta end", gr.Number, {}),
"schedulers_prediction_type": OptionInfo("default", "Override model prediction type", gr.Radio, lambda: {"choices": ['default', 'epsilon', 'sample', 'v-prediction']}),
"schedulers_use_karras": OptionInfo(True, "Use Karras sigmas (where applicable)"),
"schedulers_use_loworder": OptionInfo(True, "Use simplified solvers in final steps (where applicable)"),
"schedulers_use_thresholding": OptionInfo(False, "Use dynamic thresholding (where applicable)"),
"schedulers_dpm_solver": OptionInfo("sde-dpmsolver++", "DPM solver algorithm", gr.Radio, lambda: {"choices": ['dpmsolver', 'dpmsolver++', 'sde-dpmsolver', 'sde-dpmsolver++']}),
"schedulers_beta_schedule": OptionInfo("default", "Override beta schedule", gr.Radio, lambda: {"choices": ['default', 'linear', 'scaled_linear', 'squaredcos_cap_v2']}),
'schedulers_beta_start': OptionInfo(0, "Override beta start", gr.Number, {}),
'schedulers_beta_end': OptionInfo(0, "Override beta end", gr.Number, {}),
"schedulers_sep_kdiffusers": OptionInfo("<h2>K-Diffusion specific config</h2>", "", gr.HTML),
"always_batch_cond_uncond": OptionInfo(False, "Disable conditional batching enabled on low memory systems"),
"enable_quantization": OptionInfo(True, "Enable samplers quantization for sharper and cleaner results"),
"eta_ancestral": OptionInfo(1.0, "Noise multiplier for ancestral samplers (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
's_churn': OptionInfo(0.0, "sigma churn", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
's_min_uncond': OptionInfo(0.0, "sigma negative guidance minimum ", gr.Slider, {"minimum": 0.0, "maximum": 4.0, "step": 0.01}),
's_tmin': OptionInfo(0.0, "sigma tmin", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
's_noise': OptionInfo(1.0, "sigma noise", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma"),
'never_discard_next_to_last_sigma': OptionInfo(False, "Never discard next-to-last sigma"),
"enable_quantization": OptionInfo(True, "Enable quantization for sharper and cleaner results"),
's_churn': OptionInfo(0.0, "Sigma churn", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
's_min_uncond': OptionInfo(0.0, "Sigma negative guidance minimum ", gr.Slider, {"minimum": 0.0, "maximum": 4.0, "step": 0.01}),
's_tmin': OptionInfo(0.0, "Sigma tmin", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
's_noise': OptionInfo(1.0, "Sigma noise", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
'discard_next_to_last_sigma': OptionInfo("default", "Discard penultimate sigma", gr.Radio, lambda: {"choices": ['default', 'always', 'never']}),
# 'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma"),
# 'never_discard_next_to_last_sigma': OptionInfo(False, "Never discard next-to-last sigma"),
"schedulers_sep_compvis": OptionInfo("<h2>CompVis specific config</h2>", "", gr.HTML),
"ddim_discretize": OptionInfo('uniform', "DDIM discretize img2img", gr.Radio, {"choices": ['uniform', 'quad']}),
+2 -2
View File
@@ -33,9 +33,9 @@ def model(model_class = 'sd', model_type = 'decoder'):
vae = taesd_models[f'{model_class}-{model_type}']
vae.eval()
vae.to(devices.device, devices.dtype_vae)
log.info(f"Loaded VAE-approx model: {model_path}")
log.info(f"Loaded VAE-TAESD: model={model_path}")
else:
raise FileNotFoundError('TAESD model not found')
raise FileNotFoundError(f'TAESD model not found: {model_path}')
if vae is None:
return None
else: