add granular vae tiling options

Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
Vladimir Mandic
2024-12-25 12:38:18 -05:00
parent 5db51d1adc
commit e7f0047d52
11 changed files with 61 additions and 28 deletions
+8
View File
@@ -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()
+3 -3
View File
@@ -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)
+1 -1
View File
@@ -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]}')
+1 -1
View File
@@ -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:
+15 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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"]}),
+1 -1
View File
@@ -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