From e783981f3d7a546ce9ed4e4f093e4fa8d77fabeb Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Tue, 9 Jun 2026 22:10:32 +0100 Subject: [PATCH] fix(samplers): honor fallback setting in remaining sampler fallback paths create_sampler restored the model default scheduler on a prediction-type mismatch, on an unknown sampler config, and on any scheduler-constructor exception regardless of schedulers_fallback; only SD_SAMPLER_DEBUG could turn the prediction mismatch into an error. Raise like the other capability gates when the fallback setting is disabled. An unresolved sampler name substituted UniPC before any of those gates could run; pass the requested name through instead, so it falls back to the model default (or raises when fallback is disabled) and the infotext records Default rather than the unresolved name. find_sampler now also resolves an unspecified sampler to Default instead of UniPC, matching the platform default used everywhere else. --- modules/processing_helpers.py | 10 +++++----- modules/sd_samplers.py | 16 +++++++++------- modules/sd_samplers_diffusers.py | 2 ++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/processing_helpers.py b/modules/processing_helpers.py index 1135ceccc..1d81bbd56 100644 --- a/modules/processing_helpers.py +++ b/modules/processing_helpers.py @@ -584,9 +584,9 @@ def update_sampler(p, sd_model, second_pass=False): if sampler_selection == 'None': return sampler = sd_samplers.find_sampler(sampler_selection) - if sampler is None: - log.warning(f'Sampler: "{sampler_selection}" not found') - sampler = sd_samplers.all_samplers_map.get("UniPC") + resolved = sampler is not None + if not resolved: + log.warning(f'Sampler: name="{sampler_selection}" not found') sched_override_keys = [ 'schedulers_prediction_type', 'schedulers_beta_schedule', 'schedulers_timesteps', 'schedulers_sigma', 'schedulers_use_thresholding', 'schedulers_use_loworder', @@ -596,8 +596,8 @@ def update_sampler(p, sd_model, second_pass=False): 'schedulers_timestep_spacing', 'schedulers_timesteps_range', ] scheduler_overrides = {k: getattr(p, k) for k in sched_override_keys if getattr(p, k, None) is not None} - sampler = sd_samplers.create_sampler(sampler.name, sd_model, scheduler_overrides=scheduler_overrides) - if sampler is None or sampler_selection == 'Default': + sampler = sd_samplers.create_sampler(sampler.name if resolved else sampler_selection, sd_model, scheduler_overrides=scheduler_overrides) + if sampler is None or not resolved or sampler_selection == 'Default': if second_pass: p.hr_sampler = 'Default' else: diff --git a/modules/sd_samplers.py b/modules/sd_samplers.py index d38ab0acf..ef46719ba 100644 --- a/modules/sd_samplers.py +++ b/modules/sd_samplers.py @@ -15,7 +15,7 @@ loaded_config = None def find_sampler(name:str): if name is None or name == 'None': - return all_samplers_map.get("UniPC", None) + return all_samplers_map.get("Default", None) for sampler in all_samplers: if sampler.name.lower() == name.lower() or name in sampler.aliases: return sampler @@ -107,6 +107,8 @@ def create_sampler(name, model, scheduler_overrides=None): config = find_sampler_config(name) if config is None or config.constructor is None: + if debug or not shared.opts.schedulers_fallback: + raise ValueError(f'Sampler: name="{name}" unknown') return restore_default(model, name) from modules import sd_samplers_diffusers @@ -126,16 +128,16 @@ def create_sampler(name, model, scheduler_overrides=None): pass elif (model is not None) and (is_flow and not requires_flow): log.error(f'Sampler: "{sampler.name}" cls={sampler.sampler.__class__.__name__} pipe={model.__class__.__name__} type={pred_type} model requires sampler with discrete prediction') - if not debug: - return restore_default(model, name) - else: + if debug or not shared.opts.schedulers_fallback: raise ValueError(f'Sampler: name="{sampler.name}" cls={sampler.sampler.__class__.__name__} type={pred_type} model requires sampler with discrete prediction') + else: + return restore_default(model, name) elif (model is not None) and (not is_flow and requires_flow): log.error(f'Sampler: "{sampler.name}" cls={sampler.sampler.__class__.__name__} pipe={model.__class__.__name__} type={pred_type} model requires sampler with flow prediction') - if not debug: - return restore_default(model, name) - else: + if debug or not shared.opts.schedulers_fallback: raise ValueError(f'Sampler: name="{sampler.name}" cls={sampler.sampler.__class__.__name__} type={pred_type} model requires sampler with flow prediction') + else: + return restore_default(model, name) # assign sampler if model is not None: diff --git a/modules/sd_samplers_diffusers.py b/modules/sd_samplers_diffusers.py index a6e10f63a..e69e426a7 100644 --- a/modules/sd_samplers_diffusers.py +++ b/modules/sd_samplers_diffusers.py @@ -519,6 +519,8 @@ class DiffusionSampler: log.error(f'Sampler: "{name}" {e}') if debug: errors.display(e, 'Samplers') + if debug or not shared.opts.schedulers_fallback: + raise self.sampler = None return