mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
fix diffusers samplers
This commit is contained in:
+2
-2
@@ -285,6 +285,8 @@ def check_python():
|
||||
def check_torch():
|
||||
if args.quick:
|
||||
return
|
||||
if args.skip_torch:
|
||||
log.info('Skipping Torch tests')
|
||||
if args.profile:
|
||||
pr = cProfile.Profile()
|
||||
pr.enable()
|
||||
@@ -330,8 +332,6 @@ def check_torch():
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch torchvision')
|
||||
if 'torch' in torch_command and not args.version:
|
||||
install(torch_command, 'torch torchvision')
|
||||
if args.skip_torch:
|
||||
log.info('Skipping Torch tests')
|
||||
else:
|
||||
try:
|
||||
import torch
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ def torch_gc(force=False):
|
||||
if oom > previous_oom:
|
||||
previous_oom = oom
|
||||
shared.log.warning(f'GPU out-of-memory error: {mem}')
|
||||
if used > 90:
|
||||
if used > 95:
|
||||
shared.log.warning(f'GPU high memory utilization: {used}% {mem}')
|
||||
force = True
|
||||
|
||||
|
||||
@@ -123,8 +123,6 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
|
||||
width = int(image.width * scale_by)
|
||||
height = int(image.height * scale_by)
|
||||
|
||||
assert 0. <= denoising_strength <= 1., 'can only work with strength in [0.0, 1.0]'
|
||||
|
||||
p = processing.StableDiffusionProcessingImg2Img(
|
||||
sd_model=shared.sd_model,
|
||||
outpath_samples=shared.opts.outdir_samples or shared.opts.outdir_img2img_samples,
|
||||
|
||||
+12
-13
@@ -278,7 +278,7 @@ class Processed:
|
||||
self.sd_model_hash = shared.sd_model.sd_model_hash
|
||||
self.seed_resize_from_w = p.seed_resize_from_w
|
||||
self.seed_resize_from_h = p.seed_resize_from_h
|
||||
self.denoising_strength = getattr(p, 'denoising_strength', None)
|
||||
self.denoising_strength = p.denoising_strength
|
||||
self.extra_generation_params = p.extra_generation_params
|
||||
self.index_of_first_image = index_of_first_image
|
||||
self.styles = p.styles
|
||||
@@ -466,7 +466,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su
|
||||
"Variation seed": None if p.subseed_strength == 0 else all_subseeds[index],
|
||||
"Variation seed strength": None if p.subseed_strength == 0 else p.subseed_strength,
|
||||
"Seed resize from": None if p.seed_resize_from_w == 0 or p.seed_resize_from_h == 0 else f"{p.seed_resize_from_w}x{p.seed_resize_from_h}",
|
||||
"Denoising strength": getattr(p, 'denoising_strength', None),
|
||||
"Denoising strength": p.denoising_strength,
|
||||
"Conditional mask weight": getattr(p, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) if p.is_using_inpainting_conditioning else None,
|
||||
"Clip skip": p.clip_skip if p.clip_skip > 1 else None,
|
||||
"ENSD": opts.eta_noise_seed_delta if uses_ensd else None,
|
||||
@@ -728,11 +728,11 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
del samples_ddim
|
||||
|
||||
elif shared.backend == Backend.DIFFUSERS:
|
||||
if (not hasattr(shared.sd_model.scheduler, 'name')) or (shared.sd_model.scheduler.name != p.sampler_name):
|
||||
sampler = sd_samplers.all_samplers_map.get(p.sampler_name, None)
|
||||
if sampler is None:
|
||||
sampler = sd_samplers.all_samplers_map.get("UniPC")
|
||||
shared.sd_model.scheduler = sd_samplers.create_sampler(sampler.name, shared.sd_model) # TODO(Patrick): For wrapped pipelines this is currently a no-op
|
||||
# if (not hasattr(shared.sd_model.scheduler, 'name')) or (shared.sd_model.scheduler.name != p.sampler_name):
|
||||
sampler = sd_samplers.all_samplers_map.get(p.sampler_name, None)
|
||||
if sampler is None:
|
||||
sampler = sd_samplers.all_samplers_map.get("UniPC")
|
||||
sd_samplers.create_sampler(sampler.name, shared.sd_model) # TODO(Patrick): For wrapped pipelines this is currently a no-op
|
||||
|
||||
cross_attention_kwargs={}
|
||||
if lora_state['active']:
|
||||
@@ -746,7 +746,6 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
# TODO(PVP): change out to latents once possible with `diffusers`
|
||||
task_specific_kwargs = {"image": p.init_images[0], "mask_image": p.image_mask, "strength": p.denoising_strength}
|
||||
|
||||
|
||||
shared.sd_model.to(devices.device)
|
||||
pipe_args = set_pipeline_args(
|
||||
model=shared.sd_model,
|
||||
@@ -766,11 +765,11 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
shared.log.debug('Moving base model to CPU')
|
||||
shared.sd_model.to('cpu')
|
||||
|
||||
if (not hasattr(shared.sd_refiner.scheduler, 'name')) or (shared.sd_refiner.scheduler.name != p.latent_sampler):
|
||||
sampler = sd_samplers.all_samplers_map.get(p.latent_sampler, None)
|
||||
if sampler is None:
|
||||
sampler = sd_samplers.all_samplers_map.get("UniPC")
|
||||
shared.sd_refiner.scheduler = sd_samplers.create_sampler(sampler.name, shared.sd_refiner) # TODO(Patrick): For wrapped pipelines this is currently a no-op
|
||||
# if (not hasattr(shared.sd_refiner.scheduler, 'name')) or (shared.sd_refiner.scheduler.name != p.latent_sampler):
|
||||
sampler = sd_samplers.all_samplers_map.get(p.latent_sampler, None)
|
||||
if sampler is None:
|
||||
sampler = sd_samplers.all_samplers_map.get("UniPC")
|
||||
sd_samplers.create_sampler(sampler.name, shared.sd_refiner) # TODO(Patrick): For wrapped pipelines this is currently a no-op
|
||||
|
||||
shared.sd_refiner.to(devices.device)
|
||||
devices.torch_gc()
|
||||
|
||||
@@ -47,6 +47,8 @@ def create_sampler(name, model):
|
||||
return sampler
|
||||
elif shared.backend == shared.Backend.DIFFUSERS:
|
||||
sampler = config.constructor(model)
|
||||
if not hasattr(model, 'scheduler_config'):
|
||||
model.scheduler_config = sampler.sampler.config.copy()
|
||||
model.scheduler = sampler.sampler
|
||||
return sampler.sampler
|
||||
else:
|
||||
|
||||
@@ -22,20 +22,22 @@ except Exception as e:
|
||||
log.error(f'Diffusers import error: version={diffusers.__version__} error: {e}')
|
||||
|
||||
config = {
|
||||
'All': { 'num_train_timesteps': 1000, 'beta_schedule': 'linear', 'prediction_type': 'epsilon' },
|
||||
'UniPC': { 'beta_start': 0.0001, 'beta_end': 0.02,'solver_order': 2, 'thresholding': False, 'sample_max_value': 1.0, 'predict_x0': 'bh2', 'lower_order_final': True },
|
||||
'DDIM': { 'beta_start': 0.0001, 'beta_end': 0.02,'clip_sample': True, 'set_alpha_to_one': True, 'steps_offset': 0, 'thresholding': False, 'clip_sample_range': 1.0, 'sample_max_value': 1.0, 'timestep_spacing': 'linspace', 'rescale_betas_zero_snr': False },
|
||||
'DDPM': { 'beta_start': 0.0001, 'beta_end': 0.02,'variance_type': "fixed_small", 'clip_sample': True, 'thresholding': False, 'clip_sample_range': 1.0, 'sample_max_value': 1.0, 'timestep_spacing': 'linspace'},
|
||||
'KDPM2': {'beta_start': 0.00085, 'beta_end': 0.012, 'steps_offset': 0 },
|
||||
'KDPM2 a': {'beta_start': 0.00085, 'beta_end': 0.012, 'steps_offset': 0 },
|
||||
'DEIS': { 'beta_start': 0.0001, 'beta_end': 0.02,'solver_order': 2, 'thresholding': False, 'sample_max_value': 1.0, 'algorithm_type': "deis", 'solver_type': "logrho", 'lower_order_final': True },
|
||||
'Euler': {'beta_start': 0.0001, 'beta_end': 0.02, 'interpolation_type': "linear", 'use_karras_sigmas': False },
|
||||
'Euler a': { 'beta_start': 0.0001, 'beta_end': 0.02 },
|
||||
'Heun': { 'beta_start': 0.0001, 'beta_end': 0.02,'use_karras_sigmas': False },
|
||||
'PNDM': { 'beta_start': 0.0001, 'beta_end': 0.02,'skip_prk_steps': False, 'set_alpha_to_one': False, 'steps_offset': 0 },
|
||||
'DPM 1S': { 'beta_start': 0.0001, 'beta_end': 0.02,'solver_order': 2, 'thresholding': False, 'sample_max_value': 1.0, 'algorithm_type': "dpmsolver++", 'solver_type': "midpoint", 'lower_order_final': True, 'use_karras_sigmas': False },
|
||||
'DPM 2M': { 'beta_start': 0.0001, 'beta_end': 0.02,'thresholding': False, 'sample_max_value': 1.0, 'algorithm_type': "dpmsolver++", 'solver_type': "midpoint", 'lower_order_final': True, 'use_karras_sigmas': False },
|
||||
'LMSD': { 'beta_start': 0.0001, 'beta_end': 0.02,'use_karras_sigmas': False, 'timestep_spacing': 'linspace', 'steps_offset': 0 },
|
||||
# TODO beta_start, beta_end are typically per-scheduler, but we don't want them as they should be taken from the model itself as those are values model was trained on
|
||||
# TODO prediction_type is ideally set in model as well, but it maybe needed that we do auto-detect of model type in the future
|
||||
'All': { 'num_train_timesteps': 1000, 'beta_start': 0.0001, 'beta_end': 0.02, 'beta_schedule': 'linear', 'prediction_type': 'epsilon' },
|
||||
'DDIM': { 'clip_sample': True, 'set_alpha_to_one': True, 'steps_offset': 0, 'thresholding': False, 'clip_sample_range': 1.0, 'sample_max_value': 1.0, 'timestep_spacing': 'linspace', 'rescale_betas_zero_snr': False },
|
||||
'DDPM': { 'variance_type': "fixed_small", 'clip_sample': True, 'thresholding': False, 'clip_sample_range': 1.0, 'sample_max_value': 1.0, 'timestep_spacing': 'linspace'},
|
||||
'DEIS': { 'solver_order': 2, 'thresholding': False, 'sample_max_value': 1.0, 'algorithm_type': "deis", 'solver_type': "logrho", 'lower_order_final': True },
|
||||
'DPM 1S': { 'solver_order': 2, 'thresholding': False, 'sample_max_value': 1.0, 'algorithm_type': "dpmsolver++", 'solver_type': "midpoint", 'lower_order_final': True, 'use_karras_sigmas': False },
|
||||
'DPM 2M': { 'thresholding': False, 'sample_max_value': 1.0, 'algorithm_type': "dpmsolver++", 'solver_type': "midpoint", 'lower_order_final': True, 'use_karras_sigmas': False },
|
||||
'Euler a': { },
|
||||
'Euler': { 'interpolation_type': "linear", 'use_karras_sigmas': False },
|
||||
'Heun': { 'use_karras_sigmas': False },
|
||||
'KDPM2 a': { 'steps_offset': 0 },
|
||||
'KDPM2': { 'steps_offset': 0 },
|
||||
'LMSD': { 'use_karras_sigmas': False, 'timestep_spacing': 'linspace', 'steps_offset': 0 },
|
||||
'PNDM': { 'skip_prk_steps': False, 'set_alpha_to_one': False, 'steps_offset': 0 },
|
||||
'UniPC': { 'solver_order': 2, 'thresholding': False, 'sample_max_value': 1.0, 'predict_x0': 'bh2', 'lower_order_final': True },
|
||||
}
|
||||
|
||||
samplers_data_diffusers = [
|
||||
@@ -57,17 +59,22 @@ samplers_data_diffusers = [
|
||||
class DiffusionSampler:
|
||||
def __init__(self, name, constructor, model, **kwargs):
|
||||
self.config = {}
|
||||
self.config = config['All'].copy()
|
||||
self.config = config['All'].copy() # apply global defaults
|
||||
if not hasattr(model, 'scheduler'):
|
||||
return
|
||||
for key, value in config.get(name, {}).items(): # diffusers defaults
|
||||
for key, value in config.get(name, {}).items(): # apply diffusers per-scheduler defaults
|
||||
self.config[key] = value
|
||||
for key, value in model.scheduler.config.items(): # model defaults
|
||||
if hasattr(model.scheduler, 'scheduler_config'): # find model defaults
|
||||
orig_config = model.scheduler.scheduler_config
|
||||
else:
|
||||
orig_config = model.scheduler.config
|
||||
for key, value in orig_config.items(): # apply model defaults
|
||||
if key in self.config:
|
||||
self.config[key] = value
|
||||
for key, value in kwargs.items(): # user args
|
||||
for key, value in kwargs.items(): # apply user args, if any
|
||||
if key in self.config:
|
||||
self.config[key] = value
|
||||
# finally apply user preferences
|
||||
if opts.schedulers_prediction_type != 'default':
|
||||
self.config['prediction_type'] = opts.schedulers_prediction_type
|
||||
if opts.schedulers_beta_schedule != 'default':
|
||||
|
||||
+1
-1
Submodule wiki updated: fea0bd7d59...f0aae4958a
Reference in New Issue
Block a user