mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 01:04:32 +02:00
refactor schedulers first part
This commit is contained in:
@@ -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
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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']}),
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user