mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
add granular vae tiling options
Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2024-12-25
|
||||
|
||||
### Post release
|
||||
|
||||
- Add granular VAE tiling options in *settings -> variable auto encoder*
|
||||
- Add legacy option to use old LoRA loader in *settings -> networks*
|
||||
- Add sigma calculation to VAE preview, thanks @Disty0
|
||||
|
||||
## Update for 2024-12-24
|
||||
|
||||
### Highlights for 2024-12-24
|
||||
|
||||
@@ -129,7 +129,7 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork):
|
||||
if len(networks.loaded_networks) > 0 and step == 0:
|
||||
self.infotext(p)
|
||||
self.prompt(p)
|
||||
shared.log.info(f'Load network: type=LoRA apply={[n.name for n in networks.loaded_networks]} te={te_multipliers} unet={unet_multipliers} dims={dyn_dims} load={t1-t0:.2f}')
|
||||
shared.log.info(f'Load network: type=LoRA apply={[n.name for n in networks.loaded_networks]} method=legacy te={te_multipliers} unet={unet_multipliers} dims={dyn_dims} load={t1-t0:.2f}')
|
||||
|
||||
def deactivate(self, p):
|
||||
t0 = time.time()
|
||||
|
||||
@@ -182,11 +182,11 @@ def load_network(name, network_on_disk) -> network.Network:
|
||||
else:
|
||||
net.modules[key] = net_module
|
||||
if len(keys_failed_to_match) > 0:
|
||||
shared.log.warning(f'LoRA name="{name}" type={set(network_types)} unmatched={len(keys_failed_to_match)} matched={len(matched_networks)}')
|
||||
shared.log.warning(f'Load network: type=LoRA name="{name}" type={set(network_types)} unmatched={len(keys_failed_to_match)} matched={len(matched_networks)}')
|
||||
if debug:
|
||||
shared.log.debug(f'LoRA name="{name}" unmatched={keys_failed_to_match}')
|
||||
shared.log.debug(f'Load network: type=LoRA name="{name}" unmatched={keys_failed_to_match}')
|
||||
else:
|
||||
shared.log.debug(f'LoRA name="{name}" type={set(network_types)} keys={len(matched_networks)}')
|
||||
shared.log.debug(f'Load network: type=LoRA name="{name}" type={set(network_types)} keys={len(matched_networks)}')
|
||||
if len(matched_networks) == 0:
|
||||
return None
|
||||
lora_cache[name] = net
|
||||
|
||||
@@ -57,7 +57,8 @@ def infotext_pasted(infotext, d): # pylint: disable=unused-argument
|
||||
d["Prompt"] = re.sub(re_lora, network_replacement, d["Prompt"])
|
||||
|
||||
|
||||
if not shared.native:
|
||||
if shared.opts.lora_legacy:
|
||||
shared.log.debug('Register network: type=LoRA method=legacy')
|
||||
script_callbacks.on_app_started(api_networks)
|
||||
script_callbacks.on_before_ui(before_ui)
|
||||
script_callbacks.on_model_loaded(networks.assign_network_names_to_compvis_modules)
|
||||
|
||||
@@ -154,4 +154,4 @@ def list_extensions():
|
||||
for dirname, path, is_builtin in extension_paths:
|
||||
extension = Extension(name=dirname, path=path, enabled=dirname not in disabled_extensions, is_builtin=is_builtin)
|
||||
extensions.append(extension)
|
||||
shared.log.debug(f'Disabled extensions: {[e.name for e in extensions if not e.enabled]}')
|
||||
shared.log.debug(f'Extensions disabled: {[e.name for e in extensions if not e.enabled]}')
|
||||
|
||||
@@ -18,7 +18,7 @@ def register_extra_network(extra_network):
|
||||
def register_default_extra_networks():
|
||||
from modules.ui_extra_networks_styles import ExtraNetworkStyles
|
||||
register_extra_network(ExtraNetworkStyles())
|
||||
if shared.native:
|
||||
if not shared.opts.lora_legacy:
|
||||
from modules.lora.networks import extra_network_lora
|
||||
register_extra_network(extra_network_lora)
|
||||
if shared.opts.hypernetwork_enabled:
|
||||
|
||||
@@ -131,11 +131,11 @@ def load_safetensors(name, network_on_disk) -> Union[network.Network, None]:
|
||||
else:
|
||||
net.modules[key] = net_module
|
||||
if len(keys_failed_to_match) > 0:
|
||||
shared.log.warning(f'LoRA name="{name}" type={set(network_types)} unmatched={len(keys_failed_to_match)} matched={len(matched_networks)}')
|
||||
shared.log.warning(f'Load network: type=LoRA name="{name}" type={set(network_types)} unmatched={len(keys_failed_to_match)} matched={len(matched_networks)}')
|
||||
if debug:
|
||||
shared.log.debug(f'LoRA name="{name}" unmatched={keys_failed_to_match}')
|
||||
shared.log.debug(f'Load network: type=LoRA name="{name}" unmatched={keys_failed_to_match}')
|
||||
else:
|
||||
shared.log.debug(f'LoRA name="{name}" type={set(network_types)} keys={len(matched_networks)} direct={shared.opts.lora_fuse_diffusers}')
|
||||
shared.log.debug(f'Load network: type=LoRA name="{name}" type={set(network_types)} keys={len(matched_networks)} direct={shared.opts.lora_fuse_diffusers}')
|
||||
if len(matched_networks) == 0:
|
||||
return None
|
||||
lora_cache[name] = net
|
||||
@@ -311,8 +311,14 @@ def network_backup_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.n
|
||||
t0 = time.time()
|
||||
|
||||
weights_backup = getattr(self, "network_weights_backup", None)
|
||||
if (shared.opts.lora_fuse_diffusers and not isinstance(weights_backup, bool)) or (not shared.opts.lora_fuse_diffusers and isinstance(weights_backup, bool)):
|
||||
weights_backup = None # invalidate so we can change direct/backup on-the-fly
|
||||
bias_backup = getattr(self, "network_bias_backup", None)
|
||||
if weights_backup is not None or bias_backup is not None:
|
||||
if (shared.opts.lora_fuse_diffusers and not isinstance(weights_backup, bool)) or (not shared.opts.lora_fuse_diffusers and isinstance(weights_backup, bool)): # invalidate so we can change direct/backup on-the-fly
|
||||
weights_backup = None
|
||||
bias_backup = None
|
||||
self.network_weights_backup = weights_backup
|
||||
self.network_bias_backup = bias_backup
|
||||
|
||||
if weights_backup is None and wanted_names != (): # pylint: disable=C1803
|
||||
weight = getattr(self, 'weight', None)
|
||||
self.network_weights_backup = None
|
||||
@@ -340,7 +346,6 @@ def network_backup_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.n
|
||||
else:
|
||||
self.network_weights_backup = weight.clone().to(devices.cpu)
|
||||
|
||||
bias_backup = getattr(self, "network_bias_backup", None)
|
||||
if bias_backup is None:
|
||||
if getattr(self, 'bias', None) is not None:
|
||||
if shared.opts.lora_fuse_diffusers:
|
||||
@@ -407,6 +412,10 @@ def network_calc_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.
|
||||
def network_apply_direct(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.GroupNorm, torch.nn.LayerNorm, diffusers.models.lora.LoRACompatibleLinear, diffusers.models.lora.LoRACompatibleConv], updown: torch.Tensor, ex_bias: torch.Tensor, deactivate: bool = False):
|
||||
weights_backup = getattr(self, "network_weights_backup", False)
|
||||
bias_backup = getattr(self, "network_bias_backup", False)
|
||||
if not isinstance(weights_backup, bool):
|
||||
weights_backup = True
|
||||
if not isinstance(bias_backup, bool):
|
||||
bias_backup = True
|
||||
if not weights_backup and not bias_backup:
|
||||
return None, None
|
||||
t0 = time.time()
|
||||
|
||||
+20
-10
@@ -226,15 +226,7 @@ def copy_diffuser_options(new_pipe, orig_pipe):
|
||||
set_accelerate(new_pipe)
|
||||
|
||||
|
||||
def set_diffuser_options(sd_model, vae = None, op: str = 'model', offload=True):
|
||||
if sd_model is None:
|
||||
shared.log.warning(f'{op} is not loaded')
|
||||
return
|
||||
|
||||
if hasattr(sd_model, "watermark"):
|
||||
sd_model.watermark = NoWatermark()
|
||||
if not (hasattr(sd_model, "has_accelerate") and sd_model.has_accelerate):
|
||||
sd_model.has_accelerate = False
|
||||
def set_vae_options(sd_model, vae = None, op: str = 'model'):
|
||||
if hasattr(sd_model, "vae"):
|
||||
if vae is not None:
|
||||
sd_model.vae = vae
|
||||
@@ -254,7 +246,13 @@ def set_diffuser_options(sd_model, vae = None, op: str = 'model', offload=True):
|
||||
sd_model.disable_vae_slicing()
|
||||
if hasattr(sd_model, "enable_vae_tiling"):
|
||||
if shared.opts.diffusers_vae_tiling:
|
||||
shared.log.debug(f'Setting {op}: component=VAE tiling=True')
|
||||
if hasattr(sd_model, 'vae') and hasattr(sd_model.vae, 'config') and hasattr(sd_model.vae.config, 'sample_size') and isinstance(sd_model.vae.config.sample_size, int):
|
||||
sd_model.vae.tile_sample_min_size = int(shared.opts.diffusers_vae_tile_size)
|
||||
sd_model.vae.tile_latent_min_size = int(sd_model.vae.config.sample_size / (2 ** (len(sd_model.vae.config.block_out_channels) - 1)))
|
||||
sd_model.vae.tile_overlap_factor = float(shared.opts.diffusers_vae_tile_overlap)
|
||||
shared.log.debug(f'Setting {op}: component=VAE tiling=True tile={sd_model.vae.tile_sample_min_size} overlap={sd_model.vae.tile_overlap_factor}')
|
||||
else:
|
||||
shared.log.debug(f'Setting {op}: component=VAE tiling=True')
|
||||
sd_model.enable_vae_tiling()
|
||||
else:
|
||||
sd_model.disable_vae_tiling()
|
||||
@@ -262,6 +260,18 @@ def set_diffuser_options(sd_model, vae = None, op: str = 'model', offload=True):
|
||||
shared.log.debug(f'Setting {op}: component=VQVAE upcast=True')
|
||||
sd_model.vqvae.to(torch.float32) # vqvae is producing nans in fp16
|
||||
|
||||
|
||||
def set_diffuser_options(sd_model, vae = None, op: str = 'model', offload=True):
|
||||
if sd_model is None:
|
||||
shared.log.warning(f'{op} is not loaded')
|
||||
return
|
||||
|
||||
if hasattr(sd_model, "watermark"):
|
||||
sd_model.watermark = NoWatermark()
|
||||
if not (hasattr(sd_model, "has_accelerate") and sd_model.has_accelerate):
|
||||
sd_model.has_accelerate = False
|
||||
|
||||
set_vae_options(sd_model, vae, op)
|
||||
set_diffusers_attention(sd_model)
|
||||
|
||||
if shared.opts.diffusers_fuse_projections and hasattr(sd_model, 'fuse_qkv_projections'):
|
||||
|
||||
+8
-3
@@ -366,7 +366,7 @@ def list_samplers():
|
||||
|
||||
def temp_disable_extensions():
|
||||
disable_safe = ['sd-webui-controlnet', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris', 'sd-webui-agent-scheduler', 'clip-interrogator-ext', 'stable-diffusion-webui-rembg', 'sd-extension-chainner', 'stable-diffusion-webui-images-browser']
|
||||
disable_diffusers = ['sd-webui-controlnet', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris', 'sd-webui-animatediff', 'Lora']
|
||||
disable_diffusers = ['sd-webui-controlnet', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris', 'sd-webui-animatediff']
|
||||
disable_themes = ['sd-webui-lobe-theme', 'cozy-nest', 'sdnext-modernui']
|
||||
disable_original = []
|
||||
disabled = []
|
||||
@@ -422,6 +422,8 @@ def temp_disable_extensions():
|
||||
for ext in disable_original:
|
||||
if ext.lower() not in opts.disabled_extensions:
|
||||
disabled.append(ext)
|
||||
if not opts.lora_legacy:
|
||||
disabled.append('Lora')
|
||||
cmd_opts.controlnet_loglevel = 'WARNING'
|
||||
return disabled
|
||||
|
||||
@@ -504,6 +506,8 @@ options_templates.update(options_section(('vae_encoder', "Variable Auto Encoder"
|
||||
"no_half_vae": OptionInfo(False if not cmd_opts.use_openvino else True, "Full precision (--no-half-vae)"),
|
||||
"diffusers_vae_slicing": OptionInfo(True, "VAE slicing", gr.Checkbox, {"visible": native}),
|
||||
"diffusers_vae_tiling": OptionInfo(cmd_opts.lowvram or cmd_opts.medvram, "VAE tiling", gr.Checkbox, {"visible": native}),
|
||||
"diffusers_vae_tile_size": OptionInfo(1024, "VAE tile size", gr.Slider, {"minimum": 256, "maximum": 4096, "step": 8 }),
|
||||
"diffusers_vae_tile_overlap": OptionInfo(0.1, "VAE tile overlap", gr.Slider, {"minimum": 0, "maximum": 0.9, "step": 0.1 }),
|
||||
"sd_vae_sliced_encode": OptionInfo(False, "VAE sliced encode", gr.Checkbox, {"visible": not native}),
|
||||
"nan_skip": OptionInfo(False, "Skip Generation if NaN found in latents", gr.Checkbox),
|
||||
"rollback_vae": OptionInfo(False, "Attempt VAE roll back for NaN values"),
|
||||
@@ -924,8 +928,9 @@ options_templates.update(options_section(('extra_networks', "Networks"), {
|
||||
"lora_preferred_name": OptionInfo("filename", "LoRA preferred name", gr.Radio, {"choices": ["filename", "alias"], "visible": False}),
|
||||
"lora_add_hashes_to_infotext": OptionInfo(False, "LoRA add hash info to metadata"),
|
||||
"lora_fuse_diffusers": OptionInfo(True, "LoRA fuse directly to model"),
|
||||
"lora_force_diffusers": OptionInfo(False if not cmd_opts.use_openvino else True, "LoRA force loading of all models using Diffusers"),
|
||||
"lora_maybe_diffusers": OptionInfo(False, "LoRA force loading of specific models using Diffusers"),
|
||||
"lora_legacy": OptionInfo(not native, "LoRA load using legacy method"),
|
||||
"lora_force_diffusers": OptionInfo(False if not cmd_opts.use_openvino else True, "LoRA load using Diffusers method"),
|
||||
"lora_maybe_diffusers": OptionInfo(False, "LoRA load using Diffusers method for selected models"),
|
||||
"lora_apply_tags": OptionInfo(0, "LoRA auto-apply tags", gr.Slider, {"minimum": -1, "maximum": 32, "step": 1}),
|
||||
"lora_in_memory_limit": OptionInfo(0, "LoRA memory cache", gr.Slider, {"minimum": 0, "maximum": 24, "step": 1}),
|
||||
"lora_quant": OptionInfo("NF4","LoRA precision when quantized", gr.Radio, {"choices": ["NF4", "FP4"]}),
|
||||
|
||||
@@ -100,7 +100,7 @@ def initialize():
|
||||
modules.sd_models.setup_model()
|
||||
timer.startup.record("models")
|
||||
|
||||
if shared.native:
|
||||
if not shared.opts.lora_legacy:
|
||||
import modules.lora.networks as lora_networks
|
||||
lora_networks.list_available_networks()
|
||||
timer.startup.record("lora")
|
||||
|
||||
+1
-1
Submodule wiki updated: 22951c9818...b2b4036823
Reference in New Issue
Block a user