mirror of
https://github.com/vladmandic/sdnext.git
synced 2026-10-12 02:24:13 +00:00
samplers expose base/max seq len, improve sampler options save, copy defaults
Signed-off-by: Vladimir Mandic <[email protected]>
This commit is contained in:
+5
-1
@@ -63,6 +63,9 @@ Plus quite a few other improvements and inevitable bug-fixes, see full changelog
|
||||
- processors: `DWPose`, `RTMW`, `RTMO`: image processor updates, thanks @kirtasshh
|
||||
refactored to use `ONNX` instead of obsolete `mmpose` lib and with additional configurable settings
|
||||
- lora: extend support for more model types
|
||||
- scheduler: expose base and max image sequence lengths
|
||||
recommended to change when target resolution is significantly different from the base resolution
|
||||
- detailer: add option to skip specific classes using `[SKIP=name]` in the detailer prompt, thanks @kirtasshh
|
||||
- **UI**
|
||||
- massive improvement to built-in tooltips/hints
|
||||
over 1,000 new entries, now at zero missing ui controls or settings
|
||||
@@ -94,7 +97,8 @@ Plus quite a few other improvements and inevitable bug-fixes, see full changelog
|
||||
- pixelsmith: vae tiling, thanks @li-lizhe
|
||||
- preview: remove flicker when finishing generation
|
||||
- prompt cache: bypass when condition images are encoded
|
||||
- sampler: when creating sampler, copy all valid options from default sampler
|
||||
- scheduler: when creating sampler, copy all valid options from default sampler
|
||||
- scheduler: debounce sampler options save
|
||||
- seedvr: handle temporal overap
|
||||
- styles: fix infotext parsing, thanks @obelisk-complex
|
||||
- temp file: gradio temp file error handling
|
||||
|
||||
@@ -397,6 +397,7 @@ def control_run(state: str = '', # pylint: disable=keyword-arg-before-vararg
|
||||
schedulers_base_shift: float | None = None, schedulers_max_shift: float | None = None, schedulers_rescale_betas: bool | None = None,
|
||||
schedulers_timestep_spacing: str | None = None, schedulers_timesteps_range: int | None = None,
|
||||
schedulers_sigma_adjust: float | None = None, schedulers_sigma_adjust_min: float | None = None, schedulers_sigma_adjust_max: float | None = None,
|
||||
schedulers_base_image_seq_len: int | None = None, schedulers_max_image_seq_len: int | None = None,
|
||||
scheduler_eta: float | None = None, eta_noise_seed_delta: int | None = None, enable_batch_seeds: bool | None = None,
|
||||
diffusers_generator_device: str | None = None, nan_skip: bool | None = None,
|
||||
sequential_seed: bool | None = None,
|
||||
@@ -573,6 +574,7 @@ def control_run(state: str = '', # pylint: disable=keyword-arg-before-vararg
|
||||
schedulers_base_shift=schedulers_base_shift, schedulers_max_shift=schedulers_max_shift,
|
||||
schedulers_rescale_betas=schedulers_rescale_betas, schedulers_timestep_spacing=schedulers_timestep_spacing,
|
||||
schedulers_timesteps_range=schedulers_timesteps_range,
|
||||
schedulers_base_image_seq_len=schedulers_base_image_seq_len, schedulers_max_image_seq_len=schedulers_max_image_seq_len,
|
||||
schedulers_sigma_adjust=schedulers_sigma_adjust, schedulers_sigma_adjust_min=schedulers_sigma_adjust_min,
|
||||
schedulers_sigma_adjust_max=schedulers_sigma_adjust_max,
|
||||
scheduler_eta=scheduler_eta, eta_noise_seed_delta=eta_noise_seed_delta,
|
||||
|
||||
@@ -123,6 +123,8 @@ mapping = [
|
||||
('Sampler beta end', 'schedulers_beta_end'),
|
||||
('Sampler range', 'schedulers_timesteps_range'),
|
||||
('Sampler shift', 'schedulers_shift'),
|
||||
('Sampler base seq', 'schedulers_base_image_seq_len'),
|
||||
('Sampler max seq', 'schedulers_max_image_seq_len'),
|
||||
('Sampler dynamic shift', 'schedulers_dynamic_shift'),
|
||||
# Token Merging
|
||||
('Mask weight', 'inpainting_mask_weight'),
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ def options_section(section_identifier: tuple[str, str], options_dict: dict[str,
|
||||
|
||||
class OptionInfo:
|
||||
def __init__(
|
||||
self,
|
||||
self, # pylint: disable=unused-argument
|
||||
default: Any = None,
|
||||
label="",
|
||||
component: type[Component] | type[DropdownEditable] | None = None,
|
||||
@@ -35,8 +35,8 @@ class OptionInfo:
|
||||
comment_before='',
|
||||
comment_after='',
|
||||
category_id=None, # pylint: disable=unused-argument
|
||||
*args, # pylint: disable=unused-argument
|
||||
**kwargs, # pylint: disable=unused-argument
|
||||
*args,
|
||||
**kwargs,
|
||||
): # pylint: disable=keyword-arg-before-vararg
|
||||
self.default = default
|
||||
self.label = label
|
||||
|
||||
@@ -239,6 +239,8 @@ class StableDiffusionProcessing:
|
||||
schedulers_sigma_adjust: float | None = None,
|
||||
schedulers_sigma_adjust_min: float | None = None,
|
||||
schedulers_sigma_adjust_max: float | None = None,
|
||||
schedulers_base_image_seq_len: int | None = None,
|
||||
schedulers_max_image_seq_len: int | None = None,
|
||||
scheduler_eta: float | None = None,
|
||||
eta_noise_seed_delta: int | None = None,
|
||||
enable_batch_seeds: bool | None = None,
|
||||
@@ -526,6 +528,8 @@ class StableDiffusionProcessing:
|
||||
self.schedulers_sigma_adjust = schedulers_sigma_adjust
|
||||
self.schedulers_sigma_adjust_min = schedulers_sigma_adjust_min
|
||||
self.schedulers_sigma_adjust_max = schedulers_sigma_adjust_max
|
||||
self.schedulers_base_image_seq_len = schedulers_base_image_seq_len
|
||||
self.schedulers_max_image_seq_len = schedulers_max_image_seq_len
|
||||
self.scheduler_eta = scheduler_eta
|
||||
self.eta_noise_seed_delta = eta_noise_seed_delta
|
||||
self.enable_batch_seeds = enable_batch_seeds
|
||||
|
||||
@@ -516,10 +516,10 @@ class DiffusionSampler:
|
||||
if 'beta_end' in self.config and get_override('schedulers_beta_end') > 0:
|
||||
self.config['beta_end'] = get_override('schedulers_beta_end')
|
||||
sched_shift = get_override('schedulers_shift')
|
||||
if 'shift' in self.config:
|
||||
self.config['shift'] = sched_shift if sched_shift > 0 else 3
|
||||
if 'flow_shift' in self.config:
|
||||
self.config['flow_shift'] = sched_shift if sched_shift > 0 else 3
|
||||
if 'shift' in self.config and sched_shift > 0:
|
||||
self.config['shift'] = sched_shift
|
||||
if 'flow_shift' in self.config and sched_shift > 0:
|
||||
self.config['flow_shift'] = sched_shift
|
||||
if 'use_dynamic_shifting' in self.config:
|
||||
self.config['use_dynamic_shifting'] = True if sched_shift == 0 else get_override('schedulers_dynamic_shift')
|
||||
if 'base_shift' in self.config:
|
||||
@@ -530,6 +530,10 @@ class DiffusionSampler:
|
||||
self.config['use_beta_sigmas'] = 'StableDiffusion3' in model.__class__.__name__
|
||||
if 'rescale_betas_zero_snr' in self.config:
|
||||
self.config['rescale_betas_zero_snr'] = get_override('schedulers_rescale_betas')
|
||||
if 'base_image_seq_len' in self.config and get_override('schedulers_base_image_seq_len') > 0:
|
||||
self.config['base_image_seq_len'] = get_override('schedulers_base_image_seq_len')
|
||||
if 'max_image_seq_len' in self.config and get_override('schedulers_max_image_seq_len') > 0:
|
||||
self.config['max_image_seq_len'] = get_override('schedulers_max_image_seq_len')
|
||||
sched_ts_spacing = get_override('schedulers_timestep_spacing')
|
||||
if 'timestep_spacing' in self.config and sched_ts_spacing != 'default' and sched_ts_spacing is not None:
|
||||
self.config['timestep_spacing'] = sched_ts_spacing
|
||||
@@ -558,7 +562,6 @@ class DiffusionSampler:
|
||||
for key in self.config.copy().keys():
|
||||
if key not in possible:
|
||||
del self.config[key]
|
||||
self.config['shift_terminal'] = 0.0
|
||||
debug_log(f'Sampler: name="{name}"')
|
||||
debug_log(f'Sampler: config={self.config}')
|
||||
debug_log(f'Sampler: signature={possible}')
|
||||
|
||||
@@ -858,6 +858,8 @@ def create_settings(cmd_opts):
|
||||
"schedulers_shift": OptionInfo(3, "Sampler shift", gr.Slider, {"minimum": 0.1, "maximum": 10, "step": 0.1, "visible": False}),
|
||||
"schedulers_fallback": OptionInfo(True, "Sampler fallback on invalid", gr.Checkbox, {"visible": False}),
|
||||
"schedulers_dynamic_shift": OptionInfo(False, "Sampler dynamic shift", gr.Checkbox, {"visible": False}),
|
||||
"schedulers_base_image_seq_len": OptionInfo(0, "Sampler base seq", gr.Slider, {"minimum": 0, "maximum": 1024, "step": 16, "visible": False}),
|
||||
"schedulers_max_image_seq_len": OptionInfo(0, "Sampler max seq", gr.Slider, {"minimum": 0, "maximum": 16384, "step": 16, "visible": False}),
|
||||
"schedulers_sigma_adjust": OptionInfo(1.0, "Sigma adjust", gr.Slider, {"minimum": 0.5, "maximum": 1.5, "step": 0.01, "visible": False}),
|
||||
"schedulers_sigma_adjust_min": OptionInfo(0.2, "Sigma adjust start", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01, "visible": False}),
|
||||
"schedulers_sigma_adjust_max": OptionInfo(0.8, "Sigma adjust end", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01, "visible": False}),
|
||||
|
||||
+45
-10
@@ -1,3 +1,4 @@
|
||||
import threading
|
||||
import gradio as gr
|
||||
from modules import shared, modelloader, ui_symbols, ui_common, sd_samplers
|
||||
from modules.logger import log
|
||||
@@ -5,6 +6,10 @@ from modules.ui_components import ToolButton
|
||||
from modules.caption import caption
|
||||
|
||||
|
||||
_save_timer = None
|
||||
_save_lock = threading.Lock()
|
||||
|
||||
|
||||
def create_toprow(is_img2img: bool = False, id_part: str | None = None, generate_visible: bool = True, negative_visible: bool = True, reprocess_visible: bool = True):
|
||||
def apply_styles(prompt, prompt_neg, styles):
|
||||
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles, wildcards=not shared.opts.extra_networks_apply_unparsed)
|
||||
@@ -251,63 +256,88 @@ def create_sampler_and_steps_selection(choices, tabname, default_steps:int=20):
|
||||
return steps, sampler_index
|
||||
|
||||
|
||||
def save_with_debounce(delay=0.5):
|
||||
global _save_timer # pylint: disable=global-statement
|
||||
with _save_lock:
|
||||
try:
|
||||
if _save_timer is not None and _save_timer.is_alive():
|
||||
_save_timer.cancel()
|
||||
except Exception as e:
|
||||
log.error(f'Sampler: save debounce cancel error: {e}')
|
||||
def _do_save():
|
||||
try:
|
||||
shared.opts.save(silent=True)
|
||||
except Exception as e:
|
||||
log.error(f'Sampler: save execution error: {e}')
|
||||
|
||||
_save_timer = threading.Timer(delay, _do_save)
|
||||
_save_timer.start()
|
||||
|
||||
|
||||
def create_sampler_options(tabname):
|
||||
|
||||
def set_sampler_options(sampler_options):
|
||||
shared.opts.data['schedulers_dynamic_shift'] = 'dynamic' in sampler_options
|
||||
shared.opts.data['schedulers_use_thresholding'] = 'thresholding' in sampler_options
|
||||
shared.opts.data['schedulers_use_loworder'] = 'low order' in sampler_options
|
||||
shared.opts.data['schedulers_rescale_betas'] = 'rescale' in sampler_options
|
||||
log.debug(f'Sampler set options: {sampler_options}')
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_fallback(fallback):
|
||||
log.debug(f'Sampler set options: fallback={fallback}')
|
||||
shared.opts.schedulers_fallback = fallback
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_timesteps(timesteps):
|
||||
log.debug(f'Sampler set options: timesteps={timesteps}')
|
||||
shared.opts.schedulers_timesteps = timesteps
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_spacing(spacing):
|
||||
log.debug(f'Sampler set options: spacing={spacing}')
|
||||
shared.opts.schedulers_timestep_spacing = spacing
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_sigma(sampler_sigma):
|
||||
log.debug(f'Sampler set options: sigma={sampler_sigma}')
|
||||
shared.opts.schedulers_sigma = sampler_sigma
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_order(sampler_order):
|
||||
log.debug(f'Sampler set options: order={sampler_order}')
|
||||
shared.opts.schedulers_solver_order = sampler_order
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_prediction(sampler_prediction):
|
||||
log.debug(f'Sampler set options: prediction={sampler_prediction}')
|
||||
shared.opts.schedulers_prediction_type = sampler_prediction
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_beta(sampler_beta):
|
||||
log.debug(f'Sampler set options: beta={sampler_beta}')
|
||||
shared.opts.schedulers_beta_schedule = sampler_beta
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_shift(sampler_shift, sampler_base_shift, sampler_max_shift):
|
||||
log.debug(f'Sampler set options: shift={sampler_shift} base={sampler_base_shift} max={sampler_max_shift}')
|
||||
shared.opts.schedulers_shift = sampler_shift
|
||||
shared.opts.schedulers_base_shift = sampler_base_shift
|
||||
shared.opts.schedulers_max_shift = sampler_max_shift
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
def set_sampler_seq_lens(base_image_seq_len, max_image_seq_len):
|
||||
log.debug(f'Sampler set options: base_image_seq_len={base_image_seq_len} max_image_seq_len={max_image_seq_len}')
|
||||
shared.opts.schedulers_base_image_seq_len = base_image_seq_len
|
||||
shared.opts.schedulers_max_image_seq_len = max_image_seq_len
|
||||
save_with_debounce()
|
||||
|
||||
def set_sigma_adjust(val, start, end):
|
||||
log.debug(f'Sampler set options: sigma={val} min={start} max={end}')
|
||||
shared.opts.schedulers_sigma_adjust = val
|
||||
shared.opts.schedulers_sigma_adjust_min = start
|
||||
shared.opts.schedulers_sigma_adjust_max = end
|
||||
shared.opts.save(silent=True)
|
||||
save_with_debounce()
|
||||
|
||||
# 'linear', 'scaled_linear', 'squaredcos_cap_v2'
|
||||
def set_sampler_preset(preset):
|
||||
@@ -336,6 +366,9 @@ def create_sampler_options(tabname):
|
||||
sampler_shift = gr.Slider(minimum=0, maximum=10, step=0.1, label="Flow shift", value=shared.opts.schedulers_shift, elem_id=f"{tabname}_sampler_shift")
|
||||
sampler_base_shift = gr.Slider(minimum=0, maximum=10, step=0.01, label="Base shift", value=shared.opts.schedulers_base_shift, elem_id=f"{tabname}_sampler_base_shift")
|
||||
sampler_max_shift = gr.Slider(minimum=0, maximum=10, step=0.01, label="Max shift", value=shared.opts.schedulers_max_shift, elem_id=f"{tabname}_sampler_max_shift")
|
||||
with gr.Row(elem_classes=['flex-break']):
|
||||
sampler_base_image_seq_len = gr.Slider(minimum=0, maximum=1024, step=16, label='Sampler base seq', value=shared.opts.schedulers_base_image_seq_len, elem_id=f"{tabname}_sampler_base_image_seq_len")
|
||||
sampler_max_image_seq_len = gr.Slider(minimum=0, maximum=16284, step=16, label='Sampler max seq', value=shared.opts.schedulers_max_image_seq_len, elem_id=f"{tabname}_sampler_max_image_seq_len")
|
||||
with gr.Row(elem_classes=['flex-break']):
|
||||
options = ['low order', 'thresholding', 'dynamic', 'rescale']
|
||||
values = []
|
||||
@@ -362,6 +395,8 @@ def create_sampler_options(tabname):
|
||||
sampler_sigma_adjust_val.change(fn=set_sigma_adjust, inputs=[sampler_sigma_adjust_val, sampler_sigma_adjust_min, sampler_sigma_adjust_max], outputs=[])
|
||||
sampler_sigma_adjust_min.change(fn=set_sigma_adjust, inputs=[sampler_sigma_adjust_val, sampler_sigma_adjust_min, sampler_sigma_adjust_max], outputs=[])
|
||||
sampler_sigma_adjust_max.change(fn=set_sigma_adjust, inputs=[sampler_sigma_adjust_val, sampler_sigma_adjust_min, sampler_sigma_adjust_max], outputs=[])
|
||||
sampler_base_image_seq_len.change(fn=set_sampler_seq_lens, inputs=[sampler_base_image_seq_len, sampler_max_image_seq_len], outputs=[])
|
||||
sampler_max_image_seq_len.change(fn=set_sampler_seq_lens, inputs=[sampler_base_image_seq_len, sampler_max_image_seq_len], outputs=[])
|
||||
|
||||
|
||||
def create_hires_inputs(tab):
|
||||
|
||||
@@ -393,6 +393,6 @@ def apply_patch():
|
||||
pretrained_model_name_or_path_or_dict = apply_lora_alphas(sd)
|
||||
except Exception:
|
||||
pass
|
||||
return original_lora_state_dict(cls, pretrained_model_name_or_path_or_dict, **kwargs)
|
||||
return original_lora_state_dict(cls, pretrained_model_name_or_path_or_dict, **kwargs) # pylint: disable=too-many-function-args
|
||||
|
||||
Flux2LoraLoaderMixin.lora_state_dict = patched_lora_state_dict
|
||||
|
||||
@@ -69,6 +69,8 @@ class Krea2InpaintPipeline(Krea2Img2ImgPipeline):
|
||||
latents: Optional[torch.Tensor] = None,
|
||||
output_type: str = "pil",
|
||||
return_dict: bool = True,
|
||||
dense_mask: bool = False,
|
||||
attention_kwargs: dict | None = None,
|
||||
callback_on_step_end: Optional[Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks]] = None,
|
||||
callback_on_step_end_tensor_inputs: List[str] = ["latents"],
|
||||
):
|
||||
|
||||
@@ -115,13 +115,17 @@ class LensImg2ImgPipeline(LensPipeline):
|
||||
strength: float = 0.8,
|
||||
height: int = 1024,
|
||||
width: int = 1024,
|
||||
base_resolution: Optional[int] = None,
|
||||
aspect_ratio: Optional[str] = None,
|
||||
num_inference_steps: int = 50,
|
||||
guidance_scale: float = 4.0,
|
||||
num_images_per_prompt: int = 1,
|
||||
generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
|
||||
latents: Optional[torch.Tensor] = None,
|
||||
prompt_embeds: Optional[List[torch.Tensor]] = None,
|
||||
prompt_mask: Optional[torch.Tensor] = None,
|
||||
negative_prompt_embeds: Optional[List[torch.Tensor]] = None,
|
||||
negative_prompt_mask: Optional[torch.Tensor] = None,
|
||||
output_type: str = "pil",
|
||||
return_dict: bool = True,
|
||||
callback_on_step_end: Optional[Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks]] = None,
|
||||
@@ -186,13 +190,17 @@ class LensInpaintPipeline(LensImg2ImgPipeline):
|
||||
strength: float = 0.8,
|
||||
height: int = 1024,
|
||||
width: int = 1024,
|
||||
base_resolution: Optional[int] = None,
|
||||
aspect_ratio: Optional[str] = None,
|
||||
num_inference_steps: int = 50,
|
||||
guidance_scale: float = 4.0,
|
||||
num_images_per_prompt: int = 1,
|
||||
generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
|
||||
latents: Optional[torch.Tensor] = None,
|
||||
prompt_embeds: Optional[List[torch.Tensor]] = None,
|
||||
prompt_mask: Optional[torch.Tensor] = None,
|
||||
negative_prompt_embeds: Optional[List[torch.Tensor]] = None,
|
||||
negative_prompt_mask: Optional[torch.Tensor] = None,
|
||||
output_type: str = "pil",
|
||||
return_dict: bool = True,
|
||||
callback_on_step_end: Optional[Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks]] = None,
|
||||
|
||||
Vendored
+1
-1
@@ -1229,4 +1229,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
Submodule wiki updated: aa79b78a5c...e73ebd8c79
Reference in New Issue
Block a user