mirror of
https://github.com/vladmandic/automatic
synced 2026-09-18 16:54:33 +02:00
+4
-3
@@ -37,9 +37,8 @@
|
||||
- LoRA weights are no longer calculated on-the-fly during model execution, but are pre-calculated at the start
|
||||
this results in perceived overhead on generate startup, but results in overall faster execution as LoRA does not need to be processed on each step
|
||||
thanks @AI-Casanova
|
||||
- *note*: LoRA weights backups are required so LoRA can be unapplied, but can take quite a lot of system memory
|
||||
if you know you will not need to unapply LoRA, you can disable backups in *settings -> networks -> lora fuse*
|
||||
in which case, you need to reload model to unapply LoRA
|
||||
- LoRA weights can be applied/unapplied as on each generate or they can store weights backups for later use
|
||||
this setting has large performance and resource implications, see [Offload](https://github.com/vladmandic/automatic/wiki/Offload) wiki for details
|
||||
- **Model loader** improvements:
|
||||
- detect model components on model load fail
|
||||
- allow passing absolute path to model loader
|
||||
@@ -98,6 +97,8 @@
|
||||
- fix prompt caching
|
||||
- fix xyz grid skip final pass
|
||||
- fix sd upscale script
|
||||
- fix cogvideox-i2v
|
||||
- lora auto-apply tags remove duplicates
|
||||
|
||||
## Update for 2024-11-21
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ def prompt(p):
|
||||
loaded.tags = loaded.tags[:shared.opts.lora_apply_tags]
|
||||
all_tags.extend(loaded.tags)
|
||||
if len(all_tags) > 0:
|
||||
all_tags = list(set(all_tags))
|
||||
all_tags = [t for t in all_tags if t not in p.prompt]
|
||||
shared.log.debug(f"Load network: type=LoRA tags={all_tags} max={shared.opts.lora_apply_tags} apply")
|
||||
all_tags = ', '.join(all_tags)
|
||||
p.extra_generation_params["LoRA tags"] = all_tags
|
||||
@@ -121,13 +123,15 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork):
|
||||
# shared.log.debug(f'Activate network: type=LoRA model="{shared.opts.sd_model_checkpoint}"')
|
||||
self.active = True
|
||||
self.model = shared.opts.sd_model_checkpoint
|
||||
if 'text_encoder' in include:
|
||||
networks.timer.clear(complete=True)
|
||||
names, te_multipliers, unet_multipliers, dyn_dims = parse(p, params_list, step)
|
||||
networks.network_load(names, te_multipliers, unet_multipliers, dyn_dims) # load
|
||||
networks.network_activate(include, exclude)
|
||||
if len(networks.loaded_networks) > 0 and len(networks.applied_layers) > 0 and step == 0:
|
||||
infotext(p)
|
||||
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} time={networks.timer.summary}')
|
||||
shared.log.info(f'Load network: type=LoRA apply={[n.name for n in networks.loaded_networks]} mode={"fuse" if shared.opts.lora_fuse_diffusers else "backup"} te={te_multipliers} unet={unet_multipliers} time={networks.timer.summary}')
|
||||
|
||||
def deactivate(self, p):
|
||||
if shared.native and len(networks.diffuser_loaded) > 0:
|
||||
|
||||
@@ -42,6 +42,7 @@ module_types = [
|
||||
# section: load networks from disk
|
||||
|
||||
def load_diffusers(name, network_on_disk, lora_scale=shared.opts.extra_networks_default_multiplier) -> Union[network.Network, None]:
|
||||
t0 = time.time()
|
||||
name = name.replace(".", "_")
|
||||
shared.log.debug(f'Load network: type=LoRA name="{name}" file="{network_on_disk.filename}" detected={network_on_disk.sd_version} method=diffusers scale={lora_scale} fuse={shared.opts.lora_fuse_diffusers}')
|
||||
if not shared.native:
|
||||
@@ -67,6 +68,7 @@ def load_diffusers(name, network_on_disk, lora_scale=shared.opts.extra_networks_
|
||||
diffuser_scales.append(lora_scale)
|
||||
net = network.Network(name, network_on_disk)
|
||||
net.mtime = os.path.getmtime(network_on_disk.filename)
|
||||
timer.activate += time.time() - t0
|
||||
return net
|
||||
|
||||
|
||||
@@ -256,10 +258,12 @@ def network_load(names, te_multipliers=None, unet_multipliers=None, dyn_dims=Non
|
||||
if len(diffuser_loaded) > 0:
|
||||
shared.log.debug(f'Load network: type=LoRA loaded={diffuser_loaded} available={shared.sd_model.get_list_adapters()} active={shared.sd_model.get_active_adapters()} scales={diffuser_scales}')
|
||||
try:
|
||||
t0 = time.time()
|
||||
shared.sd_model.set_adapters(adapter_names=diffuser_loaded, adapter_weights=diffuser_scales)
|
||||
if shared.opts.lora_fuse_diffusers:
|
||||
shared.sd_model.fuse_lora(adapter_names=diffuser_loaded, lora_scale=1.0, fuse_unet=True, fuse_text_encoder=True) # fuse uses fixed scale since later apply does the scaling
|
||||
shared.sd_model.unload_lora_weights()
|
||||
timer.activate += time.time() - t0
|
||||
except Exception as e:
|
||||
shared.log.error(f'Load network: type=LoRA {e}')
|
||||
if debug:
|
||||
@@ -301,16 +305,15 @@ def network_backup_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.n
|
||||
bnb = model_quant.load_bnb('Load network: type=LoRA', silent=True)
|
||||
if bnb is not None:
|
||||
with devices.inference_context():
|
||||
weights_backup = bnb.functional.dequantize_4bit(weight, quant_state=weight.quant_state, quant_type=weight.quant_type, blocksize=weight.blocksize,)
|
||||
self.network_weights_backup = bnb.functional.dequantize_4bit(weight, quant_state=weight.quant_state, quant_type=weight.quant_type, blocksize=weight.blocksize,)
|
||||
self.quant_state = weight.quant_state
|
||||
self.quant_type = weight.quant_type
|
||||
self.blocksize = weight.blocksize
|
||||
else:
|
||||
weights_backup = weight.clone()
|
||||
weights_backup = weights_backup.to(devices.cpu)
|
||||
self.network_weights_backup = weights_backup.to(devices.cpu)
|
||||
else:
|
||||
weights_backup = weight.clone()
|
||||
weights_backup = weights_backup.to(devices.cpu)
|
||||
self.network_weights_backup = weight.clone().to(devices.cpu)
|
||||
|
||||
bias_backup = getattr(self, "network_bias_backup", None)
|
||||
if bias_backup is None:
|
||||
@@ -331,7 +334,10 @@ def network_backup_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.n
|
||||
|
||||
def network_calc_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.GroupNorm, torch.nn.LayerNorm, diffusers.models.lora.LoRACompatibleLinear, diffusers.models.lora.LoRACompatibleConv], network_layer_name: str):
|
||||
if shared.opts.diffusers_offload_mode == "none":
|
||||
self.to(devices.device)
|
||||
try:
|
||||
self.to(devices.device)
|
||||
except Exception:
|
||||
pass
|
||||
batch_updown = None
|
||||
batch_ex_bias = None
|
||||
for net in loaded_networks:
|
||||
@@ -501,7 +507,6 @@ def network_deactivate():
|
||||
|
||||
def network_activate(include=[], exclude=[]):
|
||||
t0 = time.time()
|
||||
timer.clear(complete=True)
|
||||
sd_model = getattr(shared.sd_model, "pipe", shared.sd_model) # wrapped model compatiblility
|
||||
if shared.opts.diffusers_offload_mode == "sequential":
|
||||
sd_models.disable_offload(sd_model)
|
||||
@@ -552,7 +557,7 @@ def network_activate(include=[], exclude=[]):
|
||||
if task is not None and len(applied_layers) == 0:
|
||||
pbar.remove_task(task) # hide progress bar for no action
|
||||
weights_devices, weights_dtypes = list(set([x for x in weights_devices if x is not None])), list(set([x for x in weights_dtypes if x is not None])) # noqa: C403 # pylint: disable=R1718
|
||||
timer.activate = time.time() - t0
|
||||
timer.activate += time.time() - t0
|
||||
if debug and len(loaded_networks) > 0:
|
||||
shared.log.debug(f'Load network: type=LoRA networks={len(loaded_networks)} components={components} modules={total} apply={len(applied_layers)} device={weights_devices} dtype={weights_dtypes} backup={backup_size} fuse={shared.opts.lora_fuse_diffusers} time={timer.summary}')
|
||||
modules.clear()
|
||||
|
||||
+10
-8
@@ -914,22 +914,24 @@ options_templates.update(options_section(('extra_networks', "Networks"), {
|
||||
|
||||
"extra_networks_model_sep": OptionInfo("<h2>Models</h2>", "", gr.HTML),
|
||||
"extra_network_reference": OptionInfo(False, "Use reference values when available", gr.Checkbox),
|
||||
"extra_networks_embed_sep": OptionInfo("<h2>Embeddings</h2>", "", gr.HTML),
|
||||
"diffusers_convert_embed": OptionInfo(False, "Auto-convert SD 1.5 embeddings to SDXL ", gr.Checkbox, {"visible": native}),
|
||||
"extra_networks_styles_sep": OptionInfo("<h2>Styles</h2>", "", gr.HTML),
|
||||
"extra_networks_styles": OptionInfo(True, "Show built-in styles"),
|
||||
"extra_networks_wildcard_sep": OptionInfo("<h2>Wildcards</h2>", "", gr.HTML),
|
||||
"wildcards_enabled": OptionInfo(True, "Enable file wildcards support"),
|
||||
|
||||
"extra_networks_lora_sep": OptionInfo("<h2>LoRA</h2>", "", gr.HTML),
|
||||
"extra_networks_default_multiplier": OptionInfo(1.0, "Default strength", gr.Slider, {"minimum": 0.0, "maximum": 2.0, "step": 0.01}),
|
||||
"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"),
|
||||
"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_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 in quantized models", gr.Radio, {"choices": ["NF4", "FP4"]}),
|
||||
"lora_quant": OptionInfo("NF4","LoRA precision when quantized", gr.Radio, {"choices": ["NF4", "FP4"]}),
|
||||
|
||||
"extra_networks_styles_sep": OptionInfo("<h2>Styles</h2>", "", gr.HTML),
|
||||
"extra_networks_styles": OptionInfo(True, "Show built-in styles"),
|
||||
"extra_networks_embed_sep": OptionInfo("<h2>Embeddings</h2>", "", gr.HTML),
|
||||
"diffusers_convert_embed": OptionInfo(False, "Auto-convert SD15 embeddings to SDXL ", gr.Checkbox, {"visible": native}),
|
||||
"extra_networks_wildcard_sep": OptionInfo("<h2>Wildcards</h2>", "", gr.HTML),
|
||||
"wildcards_enabled": OptionInfo(True, "Enable file wildcards support"),
|
||||
}))
|
||||
|
||||
options_templates.update(options_section((None, "Internal options"), {
|
||||
|
||||
+1
-1
Submodule wiki updated: 8960da514e...95f1749005
Reference in New Issue
Block a user