mirror of
https://github.com/vladmandic/automatic
synced 2026-09-03 03:20:45 +02:00
update settings and fix references to state
This commit is contained in:
@@ -34,7 +34,7 @@ shared.options_templates.update(shared.options_section(('extra_networks', "Extra
|
||||
"lora_add_hashes_to_infotext": shared.OptionInfo(True, "Add Lora hashes to infotext"),
|
||||
# "lora_show_all": shared.OptionInfo(False, "Always show all networks on the Lora page").info("otherwise, those detected as for incompatible version of Stable Diffusion will be hidden"),
|
||||
# "lora_hide_unknown_for_versions": shared.OptionInfo([], "Hide networks of unknown versions for model versions", gr.CheckboxGroup, {"choices": ["SD1", "SD2", "SDXL"]}),
|
||||
"lora_in_memory_limit": shared.OptionInfo(0, "Number of Lora networks to keep cached in memory", gr.Number, {"precision": 0}),
|
||||
"lora_in_memory_limit": shared.OptionInfo(0, "Lora in-memory cache", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
}))
|
||||
|
||||
|
||||
|
||||
@@ -1240,6 +1240,9 @@ def apply_token_merging(sd_model, token_merging_ratio=0):
|
||||
except Exception:
|
||||
pass
|
||||
if token_merging_ratio > 0:
|
||||
if shared.opts.hypertile_unet_enabled:
|
||||
shared.log.warning('Token merging not supported with HyperTile for UNet')
|
||||
return
|
||||
try:
|
||||
tomesd.apply_patch(
|
||||
sd_model,
|
||||
|
||||
@@ -2,10 +2,10 @@ from collections import namedtuple
|
||||
import numpy as np
|
||||
import torch
|
||||
from PIL import Image
|
||||
from modules import devices, processing, images, sd_vae_approx, sd_samplers
|
||||
import modules.shared as shared
|
||||
from modules import devices, processing, images, sd_vae_approx, sd_samplers, shared
|
||||
import modules.taesd.sd_vae_taesd as sd_vae_taesd
|
||||
|
||||
|
||||
SamplerData = namedtuple('SamplerData', ['name', 'constructor', 'aliases', 'options'])
|
||||
approximation_indexes = {"Full VAE": 0, "Approximate NN": 1, "Approximate simple": 2, "TAESD": 3}
|
||||
|
||||
@@ -44,7 +44,8 @@ def single_sample_to_image(sample, approximation=None):
|
||||
return Image.new(mode="RGB", size=(512, 512))
|
||||
x_sample = torch.clamp(255 * x_sample, min=0.0, max=255).cpu()
|
||||
x_sample = np.moveaxis(x_sample.numpy(), 0, 2).astype(np.uint8)
|
||||
return Image.fromarray(x_sample)
|
||||
image = Image.fromarray(x_sample)
|
||||
return image
|
||||
|
||||
|
||||
def sample_to_image(samples, index=0, approximation=None):
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import math
|
||||
import ldm.models.diffusion.ddim
|
||||
import ldm.models.diffusion.plms
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from modules.shared import state
|
||||
from modules import sd_samplers_common, prompt_parser, shared
|
||||
import modules.unipc
|
||||
|
||||
@@ -43,8 +40,8 @@ class VanillaStableDiffusionSampler:
|
||||
return 0
|
||||
|
||||
def launch_sampling(self, steps, func):
|
||||
state.sampling_steps = steps
|
||||
state.sampling_step = 0
|
||||
shared.state.sampling_steps = steps
|
||||
shared.state.sampling_step = 0
|
||||
try:
|
||||
return func()
|
||||
except sd_samplers_common.InterruptedException:
|
||||
@@ -57,12 +54,12 @@ class VanillaStableDiffusionSampler:
|
||||
return res
|
||||
|
||||
def before_sample(self, x, ts, cond, unconditional_conditioning):
|
||||
if state.interrupted or state.skipped:
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
raise sd_samplers_common.InterruptedException
|
||||
if state.paused:
|
||||
if shared.state.paused:
|
||||
shared.log.debug('Sampling paused')
|
||||
while state.paused:
|
||||
if state.interrupted or state.skipped:
|
||||
while shared.state.paused:
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
raise sd_samplers_common.InterruptedException
|
||||
import time
|
||||
time.sleep(0.1)
|
||||
@@ -120,7 +117,7 @@ class VanillaStableDiffusionSampler:
|
||||
self.last_latent = self.init_latent * self.mask + self.nmask * last_latent if self.mask is not None else last_latent
|
||||
sd_samplers_common.store_latent(self.last_latent)
|
||||
self.step += 1
|
||||
state.sampling_step = self.step
|
||||
shared.state.sampling_step = self.step
|
||||
|
||||
def after_sample(self, x, ts, cond, uncond, res):
|
||||
if not self.is_unipc:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from modules.shared import opts, log
|
||||
from modules import shared
|
||||
from modules import sd_samplers_common
|
||||
|
||||
try:
|
||||
@@ -20,7 +20,7 @@ try:
|
||||
)
|
||||
except Exception as e:
|
||||
import diffusers
|
||||
log.error(f'Diffusers import error: version={diffusers.__version__} error: {e}')
|
||||
shared.log.error(f'Diffusers import error: version={diffusers.__version__} error: {e}')
|
||||
|
||||
config = {
|
||||
# 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
|
||||
@@ -82,25 +82,25 @@ class DiffusionSampler:
|
||||
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':
|
||||
self.config['beta_schedule'] = opts.schedulers_beta_schedule
|
||||
if shared.opts.schedulers_prediction_type != 'default':
|
||||
self.config['prediction_type'] = shared.opts.schedulers_prediction_type
|
||||
if shared.opts.schedulers_beta_schedule != 'default':
|
||||
self.config['beta_schedule'] = shared.opts.schedulers_beta_schedule
|
||||
if 'use_karras_sigmas' in self.config:
|
||||
self.config['use_karras_sigmas'] = opts.schedulers_use_karras
|
||||
self.config['use_karras_sigmas'] = shared.opts.schedulers_use_karras
|
||||
if 'thresholding' in self.config:
|
||||
self.config['thresholding'] = opts.schedulers_use_thresholding
|
||||
self.config['thresholding'] = shared.opts.schedulers_use_thresholding
|
||||
if 'lower_order_final' in self.config:
|
||||
self.config['lower_order_final'] = opts.schedulers_use_loworder
|
||||
self.config['lower_order_final'] = shared.opts.schedulers_use_loworder
|
||||
if 'solver_order' in self.config:
|
||||
self.config['solver_order'] = opts.schedulers_solver_order
|
||||
self.config['solver_order'] = shared.opts.schedulers_solver_order
|
||||
if 'predict_x0' in self.config:
|
||||
self.config['predict_x0'] = opts.uni_pc_variant
|
||||
self.config['predict_x0'] = shared.opts.uni_pc_variant
|
||||
if name == 'DPM++ 2M':
|
||||
self.config['algorithm_type'] = opts.schedulers_dpm_solver
|
||||
if 'beta_start' in self.config and opts.schedulers_beta_start > 0:
|
||||
self.config['beta_start'] = opts.schedulers_beta_start
|
||||
if 'beta_end' in self.config and opts.schedulers_beta_end > 0:
|
||||
self.config['beta_end'] = opts.schedulers_beta_end
|
||||
self.config['algorithm_type'] = shared.opts.schedulers_dpm_solver
|
||||
if 'beta_start' in self.config and shared.opts.schedulers_beta_start > 0:
|
||||
self.config['beta_start'] = shared.opts.schedulers_beta_start
|
||||
if 'beta_end' in self.config and shared.opts.schedulers_beta_end > 0:
|
||||
self.config['beta_end'] = shared.opts.schedulers_beta_end
|
||||
self.sampler = constructor(**self.config)
|
||||
self.sampler.name = name
|
||||
|
||||
@@ -7,7 +7,6 @@ from modules import prompt_parser
|
||||
from modules import devices
|
||||
from modules import sd_samplers_common
|
||||
|
||||
from modules.shared import opts, state
|
||||
import modules.shared as shared
|
||||
from modules.script_callbacks import CFGDenoiserParams, cfg_denoiser_callback
|
||||
from modules.script_callbacks import CFGDenoisedParams, cfg_denoised_callback
|
||||
@@ -78,12 +77,12 @@ class CFGDenoiser(torch.nn.Module):
|
||||
return denoised
|
||||
|
||||
def forward(self, x, sigma, uncond, cond, cond_scale, s_min_uncond, image_cond):
|
||||
if state.interrupted or state.skipped:
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
raise sd_samplers_common.InterruptedException
|
||||
if state.paused:
|
||||
if shared.state.paused:
|
||||
shared.log.debug('Sampling paused')
|
||||
while state.paused:
|
||||
if state.interrupted or state.skipped:
|
||||
while shared.state.paused:
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
raise sd_samplers_common.InterruptedException
|
||||
import time
|
||||
time.sleep(0.1)
|
||||
@@ -116,7 +115,7 @@ class CFGDenoiser(torch.nn.Module):
|
||||
sigma_in = torch.cat([torch.stack([sigma[i] for _ in range(n)]) for i, n in enumerate(repeats)] + [sigma] + [sigma])
|
||||
image_cond_in = torch.cat([torch.stack([image_cond[i] for _ in range(n)]) for i, n in enumerate(repeats)] + [image_uncond] + [torch.zeros_like(self.init_latent)])
|
||||
|
||||
denoiser_params = CFGDenoiserParams(x_in, image_cond_in, sigma_in, state.sampling_step, state.sampling_steps, tensor, uncond)
|
||||
denoiser_params = CFGDenoiserParams(x_in, image_cond_in, sigma_in, shared.state.sampling_step, shared.state.sampling_steps, tensor, uncond)
|
||||
cfg_denoiser_callback(denoiser_params)
|
||||
x_in = denoiser_params.x
|
||||
image_cond_in = denoiser_params.image_cond
|
||||
@@ -179,14 +178,14 @@ class CFGDenoiser(torch.nn.Module):
|
||||
fake_uncond = torch.cat([x_out[i:i+1] for i in denoised_image_indexes])
|
||||
x_out = torch.cat([x_out, fake_uncond]) # we skipped uncond denoising, so we put cond-denoised image to where the uncond-denoised image should be
|
||||
|
||||
denoised_params = CFGDenoisedParams(x_out, state.sampling_step, state.sampling_steps, self.inner_model)
|
||||
denoised_params = CFGDenoisedParams(x_out, shared.state.sampling_step, shared.state.sampling_steps, self.inner_model)
|
||||
cfg_denoised_callback(denoised_params)
|
||||
|
||||
devices.test_for_nans(x_out, "unet")
|
||||
|
||||
if opts.live_preview_content == "Prompt":
|
||||
if shared.opts.live_preview_content == "Prompt":
|
||||
sd_samplers_common.store_latent(torch.cat([x_out[i:i+1] for i in denoised_image_indexes]))
|
||||
elif opts.live_preview_content == "Negative prompt":
|
||||
elif shared.opts.live_preview_content == "Negative prompt":
|
||||
sd_samplers_common.store_latent(x_out[-uncond.shape[0]:])
|
||||
|
||||
if is_edit_model:
|
||||
@@ -199,7 +198,7 @@ class CFGDenoiser(torch.nn.Module):
|
||||
if self.mask is not None:
|
||||
denoised = self.init_latent * self.mask + self.nmask * denoised
|
||||
|
||||
after_cfg_callback_params = AfterCFGCallbackParams(denoised, state.sampling_step, state.sampling_steps)
|
||||
after_cfg_callback_params = AfterCFGCallbackParams(denoised, shared.state.sampling_step, shared.state.sampling_steps)
|
||||
cfg_after_cfg_callback(after_cfg_callback_params)
|
||||
denoised = after_cfg_callback_params.x
|
||||
|
||||
@@ -253,16 +252,16 @@ class KDiffusionSampler:
|
||||
def callback_state(self, d):
|
||||
step = d['i']
|
||||
latent = d["denoised"]
|
||||
if opts.live_preview_content == "Combined":
|
||||
if shared.opts.live_preview_content == "Combined":
|
||||
sd_samplers_common.store_latent(latent)
|
||||
self.last_latent = latent
|
||||
if self.stop_at is not None and step > self.stop_at:
|
||||
raise sd_samplers_common.InterruptedException
|
||||
state.sampling_step = step
|
||||
shared.state.sampling_step = step
|
||||
|
||||
def launch_sampling(self, steps, func):
|
||||
state.sampling_steps = steps
|
||||
state.sampling_step = 0
|
||||
shared.state.sampling_steps = steps
|
||||
shared.state.sampling_step = 0
|
||||
try:
|
||||
return func()
|
||||
except sd_samplers_common.InterruptedException:
|
||||
@@ -273,9 +272,9 @@ class KDiffusionSampler:
|
||||
|
||||
def initialize(self, p):
|
||||
if self.config.options.get('brownian_noise', None) is not None:
|
||||
self.config.options['brownian_noise'] = opts.data.get('schedulers_brownian_noise', False)
|
||||
self.config.options['brownian_noise'] = shared.opts.data.get('schedulers_brownian_noise', False)
|
||||
if self.config.options.get('scheduler', None) is not None:
|
||||
self.config.options['scheduler'] = opts.data.get('schedulers_sigma', None)
|
||||
self.config.options['scheduler'] = shared.opts.data.get('schedulers_sigma', None)
|
||||
if p is None:
|
||||
return
|
||||
|
||||
@@ -283,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.scheduler_eta
|
||||
self.eta = p.eta if p.eta is not None else shared.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 [])
|
||||
@@ -300,7 +299,7 @@ class KDiffusionSampler:
|
||||
return extra_params_kwargs
|
||||
|
||||
def get_sigmas(self, p, steps): # pylint: disable=unused-argument
|
||||
discard_next_to_last_sigma = opts.data.get('schedulers_discard_penultimate', True) if self.config.options.get('discard_next_to_last_sigma', None) is not None else False
|
||||
discard_next_to_last_sigma = shared.opts.data.get('schedulers_discard_penultimate', True) if self.config.options.get('discard_next_to_last_sigma', None) is not None else False
|
||||
steps += 1 if discard_next_to_last_sigma else 0
|
||||
|
||||
if self.config.options.get('scheduler', None) == 'default' or self.config.options.get('scheduler', None) is None:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import os
|
||||
|
||||
import torch
|
||||
from torch import nn
|
||||
from modules import devices, paths
|
||||
|
||||
|
||||
sd_vae_approx_model = None
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class VAEApprox(nn.Module):
|
||||
extra = 11
|
||||
try:
|
||||
x = nn.functional.interpolate(x, (x.shape[2] * 2, x.shape[3] * 2))
|
||||
x = nn.functional.pad(x, (extra, extra, extra, extra))
|
||||
x = nn.functional.pad(x, (extra, extra, extra, extra)) # pylint: disable=not-callable
|
||||
for layer in [self.conv1, self.conv2, self.conv3, self.conv4, self.conv5, self.conv6, self.conv7, self.conv8, ]:
|
||||
x = layer(x)
|
||||
x = nn.functional.leaky_relu(x, 0.1)
|
||||
@@ -34,7 +34,6 @@ class VAEApprox(nn.Module):
|
||||
|
||||
def model():
|
||||
global sd_vae_approx_model # pylint: disable=global-statement
|
||||
|
||||
if sd_vae_approx_model is None:
|
||||
from modules.shared import log
|
||||
model_path = os.path.join(paths.models_path, "VAE-approx", "model.pt")
|
||||
@@ -45,7 +44,6 @@ def model():
|
||||
sd_vae_approx_model.eval()
|
||||
sd_vae_approx_model.to(devices.device, devices.dtype)
|
||||
log.info(f"Loaded VAE-approx: model={model_path}")
|
||||
|
||||
return sd_vae_approx_model
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -517,7 +517,7 @@ options_templates.update(options_section(('saving-images', "Image Options"), {
|
||||
"samples_save": OptionInfo(True, "Always save all generated images"),
|
||||
"samples_format": OptionInfo('jpg', 'File format for generated images', gr.Dropdown, lambda: {"choices": ["jpg", "png", "webp", "tiff", "jp2"]}),
|
||||
"jpeg_quality": OptionInfo(90, "Quality for saved jpeg images", gr.Slider, {"minimum": 1, "maximum": 100, "step": 1}),
|
||||
"img_max_size_mp": OptionInfo(250, "Maximum allowed image size in megapixels", gr.Number),
|
||||
"img_max_size_mp": OptionInfo(250, "Maximum image size (MP)", gr.Slider, {"minimum": 100, "maximum": 2000, "step": 1}),
|
||||
"webp_lossless": OptionInfo(False, "Use lossless compression for webp images"),
|
||||
"save_selected_only": OptionInfo(True, "When using 'Save' button, only save a single selected image"),
|
||||
"samples_save_zip": OptionInfo(True, "Create zip archive when downloading multiple images"),
|
||||
@@ -621,9 +621,9 @@ options_templates.update(options_section(('sampler-params', "Sampler Settings"),
|
||||
# managed from ui.py for backend diffusers
|
||||
"schedulers_sep_diffusers": OptionInfo("<h2>Diffusers specific config</h2>", "", gr.HTML),
|
||||
"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_beta_schedule": OptionInfo("default", "Beta schedule", gr.Radio, lambda: {"choices": ['default', 'linear', 'scaled_linear', 'squaredcos_cap_v2']}),
|
||||
'schedulers_beta_start': OptionInfo(0, "Beta start", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.00001}),
|
||||
'schedulers_beta_end': OptionInfo(0, "Beta end", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.00001}),
|
||||
|
||||
# managed from ui.py for backend original k-diffusion
|
||||
"schedulers_sep_kdiffusers": OptionInfo("<h2>K-Diffusion specific config</h2>", "", gr.HTML),
|
||||
@@ -673,8 +673,8 @@ options_templates.update(options_section(('training', "Training"), {
|
||||
"dataset_filename_word_regex": OptionInfo("", "Filename word regex"),
|
||||
"dataset_filename_join_string": OptionInfo(" ", "Filename join string"),
|
||||
"embeddings_templates_dir": OptionInfo(os.path.join(paths.script_path, 'train', 'templates'), "Embeddings train templates directory", folder=True),
|
||||
"training_image_repeats_per_epoch": OptionInfo(1, "Number of repeats for a single input image per epoch", gr.Number, {"precision": 0}),
|
||||
"training_write_csv_every": OptionInfo(0, "Save CSV file containing the loss to log directory"),
|
||||
"training_image_repeats_per_epoch": OptionInfo(1, "Image repeats per epoch", gr.Slider, {"minimum": 1, "maximum": 100, "step": 1}),
|
||||
"training_write_csv_every": OptionInfo(0, "Save loss CSV file every n steps"),
|
||||
"training_enable_tensorboard": OptionInfo(False, "Enable tensorboard logging"),
|
||||
"training_tensorboard_save_images": OptionInfo(False, "Save generated images within tensorboard"),
|
||||
"training_tensorboard_flush_every": OptionInfo(120, "Tensorboard flush period"),
|
||||
|
||||
Reference in New Issue
Block a user