mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
Merge branch 'dev' into ipadapter-end
This commit is contained in:
+3
-2
@@ -23,9 +23,10 @@
|
||||
- **Cross-attention** refactored cross-attention methods, thanks @Disty0
|
||||
- for backend:original, its unchanged: SDP, xFormers, Doggettxs, InvokeAI, Sub-quadratic, Split attention
|
||||
- for backend:diffuers, list is now: SDP, xFormers, Batch matrix-matrix, Split attention, Dynamic Attention BMM, Dynamic Attention SDP
|
||||
note: you may need to update your settings! if you were previously using split-attention, closest match is batch-matrix-matrix
|
||||
note: you may need to update your settings! Attention Slicing is renamed to Split attention
|
||||
- for ROCm, updated default cross-attention to Scaled Dot Product
|
||||
- **Dynamic Attention Slicing**, thanks @Disty0
|
||||
- dynamically slices attention queries in order to save vram based on query size and slice rate in GB
|
||||
- dynamically slices attention queries in order to keep them under the slice rate
|
||||
slicing gets only triggered if the query size is larger than the slice rate to gain performance
|
||||
*Dynamic Attention Slicing BMM* uses *Batch matrix-matrix*
|
||||
*Dynamic Attention Slicing SDP* uses *Scaled Dot Product*
|
||||
|
||||
@@ -12,3 +12,4 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma
|
||||
- masking api
|
||||
- preprocess api
|
||||
- bind panZoom to control input
|
||||
- onediff: <https://github.com/siliconflow/onediff>
|
||||
|
||||
@@ -128,9 +128,9 @@ def torch_bmm_32_bit(input, mat2, *, out=None):
|
||||
return hidden_states
|
||||
|
||||
original_scaled_dot_product_attention = torch.nn.functional.scaled_dot_product_attention
|
||||
def scaled_dot_product_attention_32_bit(query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False):
|
||||
def scaled_dot_product_attention_32_bit(query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False, **kwargs):
|
||||
if query.device.type != "xpu":
|
||||
return original_scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal)
|
||||
return original_scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, **kwargs)
|
||||
do_split, do_split_2, do_split_3, split_slice_size, split_2_slice_size, split_3_slice_size = find_sdpa_slice_sizes(query.shape, query.element_size())
|
||||
|
||||
# Slice SDPA
|
||||
@@ -153,7 +153,7 @@ def scaled_dot_product_attention_32_bit(query, key, value, attn_mask=None, dropo
|
||||
key[start_idx:end_idx, start_idx_2:end_idx_2, start_idx_3:end_idx_3],
|
||||
value[start_idx:end_idx, start_idx_2:end_idx_2, start_idx_3:end_idx_3],
|
||||
attn_mask=attn_mask[start_idx:end_idx, start_idx_2:end_idx_2, start_idx_3:end_idx_3] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal
|
||||
dropout_p=dropout_p, is_causal=is_causal, **kwargs
|
||||
)
|
||||
else:
|
||||
hidden_states[start_idx:end_idx, start_idx_2:end_idx_2] = original_scaled_dot_product_attention(
|
||||
@@ -161,7 +161,7 @@ def scaled_dot_product_attention_32_bit(query, key, value, attn_mask=None, dropo
|
||||
key[start_idx:end_idx, start_idx_2:end_idx_2],
|
||||
value[start_idx:end_idx, start_idx_2:end_idx_2],
|
||||
attn_mask=attn_mask[start_idx:end_idx, start_idx_2:end_idx_2] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal
|
||||
dropout_p=dropout_p, is_causal=is_causal, **kwargs
|
||||
)
|
||||
else:
|
||||
hidden_states[start_idx:end_idx] = original_scaled_dot_product_attention(
|
||||
@@ -169,9 +169,9 @@ def scaled_dot_product_attention_32_bit(query, key, value, attn_mask=None, dropo
|
||||
key[start_idx:end_idx],
|
||||
value[start_idx:end_idx],
|
||||
attn_mask=attn_mask[start_idx:end_idx] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal
|
||||
dropout_p=dropout_p, is_causal=is_causal, **kwargs
|
||||
)
|
||||
torch.xpu.synchronize(query.device)
|
||||
else:
|
||||
return original_scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal)
|
||||
return original_scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, **kwargs)
|
||||
return hidden_states
|
||||
|
||||
@@ -91,6 +91,8 @@ def get_device():
|
||||
device = "CPU"
|
||||
elif shared.cmd_opts.device_id is not None:
|
||||
device = f"GPU.{shared.cmd_opts.device_id}"
|
||||
if device not in core.available_devices:
|
||||
device = "GPU.0" if "GPU.0" in core.available_devices else "GPU" if "GPU" in core.available_devices else "CPU"
|
||||
elif "GPU" in core.available_devices:
|
||||
device = "GPU"
|
||||
elif "GPU.1" in core.available_devices:
|
||||
|
||||
@@ -115,11 +115,11 @@ class StableDiffusionProcessing:
|
||||
self.script_args_value: list = field(default=None, init=False)
|
||||
self.scripts_setup_complete: bool = field(default=False, init=False)
|
||||
# ip adapter
|
||||
self.ip_adapter_names = None
|
||||
self.ip_adapter_scales = 0.0
|
||||
self.ip_adapter_images = None
|
||||
self.ip_adapter_starts = None
|
||||
self.ip_adapter_ends = None
|
||||
self.ip_adapter_names = []
|
||||
self.ip_adapter_scales = [0.0]
|
||||
self.ip_adapter_images = []
|
||||
self.ip_adapter_starts = [0.0]
|
||||
self.ip_adapter_ends = [1.0]
|
||||
# hdr
|
||||
self.hdr_mode=hdr_mode
|
||||
self.hdr_brightness=hdr_brightness
|
||||
|
||||
@@ -44,8 +44,8 @@ def full_vae_decode(latents, model):
|
||||
upcast = (model.vae.dtype == torch.float16) and getattr(model.vae.config, 'force_upcast', False) and hasattr(model, 'upcast_vae')
|
||||
if upcast: # this is done by diffusers automatically if output_type != 'latent'
|
||||
model.upcast_vae()
|
||||
latents = latents.to(next(iter(model.vae.post_quant_conv.parameters())).dtype)
|
||||
|
||||
latents = latents.to(next(iter(model.vae.post_quant_conv.parameters())).dtype)
|
||||
decoded = model.vae.decode(latents / model.vae.config.scaling_factor, return_dict=False)[0]
|
||||
|
||||
# Delete PyTorch VAE after OpenVINO compile
|
||||
|
||||
@@ -49,7 +49,7 @@ def find_slice_sizes(query_shape, query_element_size, slice_rate=4):
|
||||
return do_split, do_split_2, do_split_3, split_slice_size, split_2_slice_size, split_3_slice_size
|
||||
|
||||
|
||||
def sliced_scaled_dot_product_attention(query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False):
|
||||
def sliced_scaled_dot_product_attention(query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False, **kwargs):
|
||||
do_split, do_split_2, do_split_3, split_slice_size, split_2_slice_size, split_3_slice_size = find_slice_sizes(query.shape, query.element_size(), slice_rate=shared.opts.dynamic_attention_slice_rate)
|
||||
|
||||
# Slice SDPA
|
||||
@@ -72,7 +72,7 @@ def sliced_scaled_dot_product_attention(query, key, value, attn_mask=None, dropo
|
||||
key[start_idx:end_idx, start_idx_2:end_idx_2, start_idx_3:end_idx_3],
|
||||
value[start_idx:end_idx, start_idx_2:end_idx_2, start_idx_3:end_idx_3],
|
||||
attn_mask=attn_mask[start_idx:end_idx, start_idx_2:end_idx_2, start_idx_3:end_idx_3] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal
|
||||
dropout_p=dropout_p, is_causal=is_causal, **kwargs
|
||||
)
|
||||
else:
|
||||
hidden_states[start_idx:end_idx, start_idx_2:end_idx_2] = F.scaled_dot_product_attention(
|
||||
@@ -80,7 +80,7 @@ def sliced_scaled_dot_product_attention(query, key, value, attn_mask=None, dropo
|
||||
key[start_idx:end_idx, start_idx_2:end_idx_2],
|
||||
value[start_idx:end_idx, start_idx_2:end_idx_2],
|
||||
attn_mask=attn_mask[start_idx:end_idx, start_idx_2:end_idx_2] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal
|
||||
dropout_p=dropout_p, is_causal=is_causal, **kwargs
|
||||
)
|
||||
else:
|
||||
hidden_states[start_idx:end_idx] = F.scaled_dot_product_attention(
|
||||
@@ -88,19 +88,21 @@ def sliced_scaled_dot_product_attention(query, key, value, attn_mask=None, dropo
|
||||
key[start_idx:end_idx],
|
||||
value[start_idx:end_idx],
|
||||
attn_mask=attn_mask[start_idx:end_idx] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal
|
||||
dropout_p=dropout_p, is_causal=is_causal, **kwargs
|
||||
)
|
||||
if devices.backend != "directml":
|
||||
getattr(torch, query.device.type).synchronize()
|
||||
else:
|
||||
return F.scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal)
|
||||
return F.scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, **kwargs)
|
||||
return hidden_states
|
||||
|
||||
|
||||
class DynamicAttnProcessorSDP:
|
||||
r"""
|
||||
dynamically slices attention queries based on query size and slice rate in GB
|
||||
dynamically slices attention queries in order to keep them under the slice rate
|
||||
slicing will not get triggered if the query size is smaller than the slice rate to gain performance
|
||||
|
||||
slice rate is in GB
|
||||
based on AttnProcessor V2
|
||||
"""
|
||||
|
||||
@@ -181,8 +183,10 @@ class DynamicAttnProcessorSDP:
|
||||
|
||||
class DynamicAttnProcessorBMM:
|
||||
r"""
|
||||
dynamically slices attention queries based on query size and slice rate in GB
|
||||
dynamically slices attention queries in order to keep them under the slice rate
|
||||
slicing will not get triggered if the query size is smaller than the slice rate to gain performance
|
||||
|
||||
slice rate is in GB
|
||||
based on AttnProcessor V1
|
||||
"""
|
||||
|
||||
|
||||
@@ -901,8 +901,6 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
else:
|
||||
modules.sd_hijack_accelerate.restore_accelerate()
|
||||
sd_model = pipeline.from_single_file(checkpoint_info.path, **diffusers_load_config)
|
||||
if shared.opts.diffusers_to_gpu:
|
||||
shared.log.debug(f'Model load: move={modules.sd_hijack_accelerate.tensor_to_timer:.2f}')
|
||||
if sd_model is not None and hasattr(sd_model, 'unet') and hasattr(sd_model.unet, 'config') and 'inpainting' in checkpoint_info.path.lower():
|
||||
shared.log.debug('Model patch: type=inpaint')
|
||||
sd_model.unet.config.in_channels = 9
|
||||
|
||||
+1
-3
@@ -318,9 +318,7 @@ elif devices.backend == "mps":
|
||||
cross_attention_optimization_default = "Scaled-Dot-Product" if backend == Backend.DIFFUSERS else "Doggettx's"
|
||||
elif devices.backend == "directml":
|
||||
cross_attention_optimization_default = "Dynamic Attention BMM" if backend == Backend.DIFFUSERS else "Sub-quadratic"
|
||||
elif devices.backend == "rocm":
|
||||
cross_attention_optimization_default = "Dynamic Attention BMM" if backend == Backend.DIFFUSERS else "Sub-quadratic"
|
||||
else: # cuda and ipex
|
||||
else: # cuda, rocm, ipex
|
||||
cross_attention_optimization_default ="Scaled-Dot-Product"
|
||||
|
||||
|
||||
|
||||
+1
-1
Submodule wiki updated: f294ce9411...102ab490f3
Reference in New Issue
Block a user