verify sampler index before use

This commit is contained in:
Vladimir Mandic
2023-12-30 08:38:45 -05:00
parent 176b341bdf
commit d3413c34a6
9 changed files with 58 additions and 19 deletions
+32 -2
View File
@@ -2,11 +2,41 @@
## Update for 2023-12-30
- Fixes:
- img2img interrogate
- **Fixes**:
- img2img clip and blip interrogate
- guard against invalid sampler index
- reset default cfg scale to 6.0
## Update for 2023-12-29
To wrap up this amazing year, we're releasing a new version of [SD.Next](https://github.com/vladmandic/automatic), this one is absolutely massive!
### Highlights
- Brand new Control module for *text, image, batch and video* processing
Native implementation of all control methods for both *SD15* and *SD-XL*
**ControlNet | ControlNet XS | Control LLLite | T2I Adapters | IP Adapters**
For details, see [Wiki](https://github.com/vladmandic/automatic/wiki/Control) documentation:
- Support for new models types out-of-the-box
This brings number of supported t2i/i2i model families to 13!
**Stable Diffusion 1.5/2.1 | SD-XL | LCM | Segmind | Kandinsky | Pixart-α | Würstchen | aMUSEd | DeepFloyd IF | UniDiffusion | SD-Distilled | BLiP Diffusion | etc.**
- New video capabilities:
**AnimateDiff | SVD | ModelScope | ZeroScope**
- Enhanced platform support
**Windows | Linux | MacOS** with **nVidia | AMD | IntelArc | DirectML | OpenVINO | ONNX+Olive** backends
- Better onboarding experience (first install)
with all model types available for single click download & load (networks -> reference)
- Performance optimizations!
For comparisment of different processing options and compile backends, see [Wiki](https://github.com/vladmandic/automatic/wiki/Benchmark)
As a highlight, we're reaching **~100 it/s** (no tricks, this is with full features enabled and end-to-end on a standard nVidia RTX4090)
- New [custom pipelines](https://github.com/vladmandic/automatic/blob/dev/scripts/example.py) framework for quickly porting any new pipeline
And others improvements in areas such as: Upscaling (up to 8x now with 40+ available upscalers), Inpainting (better quality), Prompt scheduling, new Sampler options, new LoRA types, additional UI themes, better HDR processing, built-in Video interpolation, parallel Batch processing, etc.
Plus some nifty new modules such as **FaceID** automatic face guidance using embeds during generation and **Depth 3D** image to 3D scene
### Full changelog
- **Control**
- native implementation of all image control methods:
**ControlNet**, **ControlNet XS**, **Control LLLite**, **T2I Adapters** and **IP Adapters**
+3 -3
View File
@@ -15,7 +15,7 @@ from modules.control.units import lite # Kohya ControlLLLite
from modules.control.units import t2iadapter # TencentARC T2I-Adapter
from modules.control.units import reference # ControlNet-Reference
from modules.control.units import ipadapter # IP-Adapter
from modules import devices, shared, errors, processing, images, sd_models, sd_samplers
from modules import devices, shared, errors, processing, images, sd_models
debug = shared.log.trace if os.environ.get('SD_CONTROL_DEBUG', None) is not None else lambda *args, **kwargs: None
@@ -90,8 +90,8 @@ def control_run(units: List[unit.Unit], inputs, inits, unit_type: str, is_genera
negative_prompt = negative,
styles = styles,
steps = steps,
sampler_name = sd_samplers.samplers[sampler_index].name,
latent_sampler = sd_samplers.samplers[sampler_index].name,
sampler_name = processing.get_sampler_name(sampler_index),
latent_sampler = processing.get_sampler_name(sampler_index),
seed = seed,
subseed = subseed,
subseed_strength = subseed_strength,
+3 -3
View File
@@ -11,7 +11,7 @@ from torch import einsum
from torch.nn.init import normal_, xavier_normal_, xavier_uniform_, kaiming_normal_, kaiming_uniform_, zeros_
from einops import rearrange, repeat
from ldm.util import default
from modules import devices, processing, sd_models, shared, sd_samplers, hashes, sd_hijack_checkpoint, errors
from modules import devices, processing, sd_models, shared, hashes, sd_hijack_checkpoint, errors
import modules.textual_inversion.dataset
from modules.textual_inversion import textual_inversion, ti_logging
from modules.textual_inversion.learn_schedule import LearnRateScheduler
@@ -445,7 +445,7 @@ def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None,
return name
def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, log_directory, training_width, training_height, varsize, steps, clip_grad_mode, clip_grad_value, shuffle_tags, tag_drop_out, latent_sampling_method, use_weight, create_image_every, save_hypernetwork_every, template_filename, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, log_directory, training_width, training_height, varsize, steps, clip_grad_mode, clip_grad_value, shuffle_tags, tag_drop_out, latent_sampling_method, use_weight, create_image_every, save_hypernetwork_every, template_filename, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height): # pylint: disable=unused-argument
# images allows training previews to have infotext. Importing it at the top causes a circular import problem.
from modules import images
@@ -672,7 +672,7 @@ def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradi
p.prompt = preview_prompt
p.negative_prompt = preview_negative_prompt
p.steps = preview_steps
p.sampler_name = sd_samplers.samplers[preview_sampler_index].name
p.sampler_name = processing.get_sampler_name(preview_sampler_index)
p.cfg_scale = preview_cfg_scale
p.seed = preview_seed
p.width = preview_width
+3 -3
View File
@@ -3,7 +3,7 @@ import itertools # SBM Batch frames
import numpy as np
from PIL import Image, ImageOps, ImageFilter, ImageEnhance, ImageChops, UnidentifiedImageError
import modules.scripts
from modules import sd_samplers, shared, processing, images
from modules import shared, processing, images
from modules.generation_parameters_copypaste import create_override_settings_dict
from modules.ui import plaintext_to_html
from modules.memstats import memory_stats
@@ -212,8 +212,8 @@ def img2img(id_task: str, mode: int,
seed_resize_from_h=seed_resize_from_h,
seed_resize_from_w=seed_resize_from_w,
seed_enable_extras=True,
sampler_name=sd_samplers.samplers_for_img2img[sampler_index].name,
latent_sampler=sd_samplers.samplers[latent_index].name,
sampler_name = processing.get_sampler_name(sampler_index, img=True),
latent_sampler = processing.get_sampler_name(latent_index, img=True),
batch_size=batch_size,
n_iter=n_iter,
steps=steps,
+10
View File
@@ -120,6 +120,16 @@ def txt2img_image_conditioning(sd_model, x, width, height):
return x.new_zeros(x.shape[0], 5, 1, 1, dtype=x.dtype, device=x.device)
def get_sampler_name(sampler_index: int, img: bool = False) -> str:
samplers = modules.sd_samplers.samplers if not img else modules.sd_samplers.samplers_for_img2img
if len(samplers) > sampler_index:
sampler_name = samplers[sampler_index].name
else:
sampler_name = "UniPC"
shared.log.warning(f'Sampler not found: index={sampler_index} available={[s.name for s in samplers]} fallback={sampler_name}')
return sampler_name
@dataclass(repr=False)
class StableDiffusionProcessing:
"""
-1
View File
@@ -350,7 +350,6 @@ def process_diffusers(p: StableDiffusionProcessing):
def update_sampler(sd_model, second_pass=False):
sampler_selection = p.latent_sampler if second_pass else p.sampler_name
# is_karras_compatible = sd_model.__class__.__init__.__annotations__.get("scheduler", None) == diffusers.schedulers.scheduling_utils.KarrasDiffusionSchedulers
if sd_model.__class__.__name__ in ['AmusedPipeline']:
return # models with their own schedulers
if hasattr(sd_model, 'scheduler') and sampler_selection != 'Default':
@@ -9,7 +9,7 @@ import safetensors.torch
import numpy as np
from PIL import Image, PngImagePlugin
from torch.utils.tensorboard import SummaryWriter
from modules import shared, devices, sd_hijack, processing, sd_models, images, sd_samplers, sd_hijack_checkpoint, errors
from modules import shared, devices, sd_hijack, processing, sd_models, images, sd_hijack_checkpoint, errors
import modules.textual_inversion.dataset
from modules.textual_inversion.learn_schedule import LearnRateScheduler
from modules.textual_inversion.image_embedding import embedding_to_b64, embedding_from_b64, insert_image_data_embed, extract_image_data_embed, caption_image_overlay
@@ -599,7 +599,7 @@ def train_embedding(id_task, embedding_name, learn_rate, batch_size, gradient_st
p.prompt = preview_prompt
p.negative_prompt = preview_negative_prompt
p.steps = preview_steps
p.sampler_name = sd_samplers.samplers[preview_sampler_index].name
p.sampler_name = processing.get_sampler_name(preview_sampler_index)
p.cfg_scale = preview_cfg_scale
p.seed = preview_seed
p.width = preview_width
+3 -3
View File
@@ -1,6 +1,6 @@
import os
import modules.scripts
from modules import sd_samplers, shared, processing
from modules import shared, processing
from modules.generation_parameters_copypaste import create_override_settings_dict
from modules.ui import plaintext_to_html
@@ -50,8 +50,8 @@ def txt2img(id_task,
seed_resize_from_h=seed_resize_from_h,
seed_resize_from_w=seed_resize_from_w,
seed_enable_extras=True,
sampler_name=sd_samplers.samplers[sampler_index].name,
latent_sampler=sd_samplers.samplers[latent_index].name,
sampler_name = processing.get_sampler_name(sampler_index),
latent_sampler = processing.get_sampler_name(latent_index),
batch_size=batch_size,
n_iter=n_iter,
steps=steps,
+2 -2
View File
@@ -183,10 +183,10 @@ def create_advanced_inputs(tab):
with gr.Accordion(open=False, label="Advanced", elem_id=f"{tab}_advanced", elem_classes=["small-accordion"]):
with gr.Group():
with FormRow():
cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='CFG scale', value=4.0, elem_id=f"{tab}_cfg_scale")
cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='CFG scale', value=6.0, elem_id=f"{tab}_cfg_scale")
clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=1, maximum=14, step=1, elem_id=f"{tab}_clip_skip", interactive=True)
with FormRow():
image_cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='Secondary CFG scale', value=4.0, elem_id=f"{tab}_image_cfg_scale")
image_cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='Secondary CFG scale', value=6.0, elem_id=f"{tab}_image_cfg_scale")
diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Guidance rescale', value=0.7, elem_id=f"{tab}_image_cfg_rescale", visible=shared.backend == shared.Backend.DIFFUSERS)
with gr.Group():
with FormRow():