mirror of
https://github.com/vladmandic/automatic
synced 2026-09-18 16:54:33 +02:00
add fused projections
This commit is contained in:
@@ -42,7 +42,6 @@ def apply_ip_adapter(pipe, p: processing.StableDiffusionProcessing, adapter, sca
|
||||
pipe.set_ip_adapter_scale(0)
|
||||
if loaded is not None:
|
||||
shared.log.debug('IP adapter: unload attention processor')
|
||||
pipe.unet.set_default_attn_processor()
|
||||
pipe.unet.config.encoder_hid_dim_type = None
|
||||
loaded = None
|
||||
return False
|
||||
@@ -74,7 +73,6 @@ def apply_ip_adapter(pipe, p: processing.StableDiffusionProcessing, adapter, sca
|
||||
t0 = time.time()
|
||||
if loaded is not None:
|
||||
# shared.log.debug('IP adapter: reset attention processor')
|
||||
pipe.unet.set_default_attn_processor()
|
||||
loaded = None
|
||||
else:
|
||||
shared.log.debug('IP adapter: load attention processor')
|
||||
|
||||
@@ -760,7 +760,9 @@ def set_diffuser_options(sd_model, vae = None, op: str = 'model'):
|
||||
sd_model.vqvae.to(torch.float32) # vqvae is producing nans in fp16
|
||||
if shared.opts.cross_attention_optimization == "xFormers" and hasattr(sd_model, 'enable_xformers_memory_efficient_attention'):
|
||||
sd_model.enable_xformers_memory_efficient_attention()
|
||||
|
||||
if shared.opts.diffusers_fuse_projections and hasattr(sd_model, 'fuse_qkv_projections'):
|
||||
shared.log.debug(f'Setting {op}: enable fused projections')
|
||||
sd_model.fuse_qkv_projections()
|
||||
if shared.opts.diffusers_eval:
|
||||
if hasattr(sd_model, "unet") and hasattr(sd_model.unet, "requires_grad_"):
|
||||
sd_model.unet.requires_grad_(False)
|
||||
@@ -771,6 +773,8 @@ def set_diffuser_options(sd_model, vae = None, op: str = 'model'):
|
||||
if hasattr(sd_model, "text_encoder") and hasattr(sd_model.text_encoder, "requires_grad_"):
|
||||
sd_model.text_encoder.requires_grad_(False)
|
||||
sd_model.text_encoder.eval()
|
||||
if shared.opts.diffusers_quantization:
|
||||
sd_model = sd_models_compile.dynamic_quantization(sd_model)
|
||||
|
||||
if shared.opts.opt_channelslast and hasattr(sd_model, 'unet'):
|
||||
shared.log.debug(f'Setting {op}: enable channels last')
|
||||
|
||||
@@ -130,6 +130,17 @@ def compile_torch(sd_model):
|
||||
torch._logging.set_logs(dynamo=log_level, aot=log_level, inductor=log_level) # pylint: disable=protected-access
|
||||
torch._dynamo.config.verbose = shared.opts.cuda_compile_verbose # pylint: disable=protected-access
|
||||
torch._dynamo.config.suppress_errors = shared.opts.cuda_compile_errors # pylint: disable=protected-access
|
||||
|
||||
try:
|
||||
torch._inductor.config.conv_1x1_as_mm = True # pylint: disable=protected-access
|
||||
torch._inductor.config.coordinate_descent_tuning = True # pylint: disable=protected-access
|
||||
torch._inductor.config.epilogue_fusion = False # pylint: disable=protected-access
|
||||
torch._inductor.config.coordinate_descent_check_all_directions = True # pylint: disable=protected-access
|
||||
torch._inductor.config.use_mixed_mm = True # pylint: disable=protected-access
|
||||
# torch._inductor.config.force_fuse_int_mm_with_mul = True # pylint: disable=protected-access
|
||||
except Exception as e:
|
||||
shared.log.error(f"Torch inductor config error: {e}")
|
||||
|
||||
t0 = time.time()
|
||||
if shared.opts.cuda_compile:
|
||||
if shared.opts.cuda_compile and (not hasattr(sd_model, 'unet') or not hasattr(sd_model.unet, 'config')):
|
||||
@@ -169,3 +180,28 @@ def compile_diffusers(sd_model):
|
||||
else:
|
||||
sd_model = compile_torch(sd_model)
|
||||
return sd_model
|
||||
|
||||
|
||||
def dynamic_quantization(sd_model):
|
||||
try:
|
||||
from torchao.quantization import quant_api
|
||||
except Exception as e:
|
||||
shared.log.error(f"Model dynamic quantization not supported: {e}")
|
||||
return sd_model
|
||||
|
||||
def dynamic_quant_filter_fn(mod, *args): # pylint: disable=unused-argument
|
||||
return (isinstance(mod, torch.nn.Linear) and mod.in_features > 16 and (mod.in_features, mod.out_features)
|
||||
not in [(1280, 640), (1920, 1280), (1920, 640), (2048, 1280), (2048, 2560), (2560, 1280), (256, 128), (2816, 1280), (320, 640), (512, 1536), (512, 256), (512, 512), (640, 1280), (640, 1920), (640, 320), (640, 5120), (640, 640), (960, 320), (960, 640)])
|
||||
|
||||
def conv_filter_fn(mod, *args): # pylint: disable=unused-argument
|
||||
return (isinstance(mod, torch.nn.Conv2d) and mod.kernel_size == (1, 1) and 128 in [mod.in_channels, mod.out_channels])
|
||||
|
||||
shared.log.info(f"Model dynamic quantization: pipeline={sd_model.__class__.__name__}")
|
||||
try:
|
||||
quant_api.swap_conv2d_1x1_to_linear(sd_model.unet, conv_filter_fn)
|
||||
quant_api.swap_conv2d_1x1_to_linear(sd_model.vae, conv_filter_fn)
|
||||
quant_api.apply_dynamic_quant(sd_model.unet, dynamic_quant_filter_fn)
|
||||
quant_api.apply_dynamic_quant(sd_model.vae, dynamic_quant_filter_fn)
|
||||
except Exception as e:
|
||||
shared.log.error(f"Model dynamic quantization error: {e}")
|
||||
return sd_model
|
||||
|
||||
@@ -317,6 +317,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
|
||||
"other_sep": OptionInfo("<h2>Execution precision</h2>", "", gr.HTML),
|
||||
"opt_channelslast": OptionInfo(False, "Use channels last as torch memory format "),
|
||||
"cudnn_benchmark": OptionInfo(False, "Enable full-depth cuDNN benchmark feature"),
|
||||
"diffusers_fuse_projections": OptionInfo(False, "Enable fused projections"),
|
||||
"torch_gc_threshold": OptionInfo(80, "Memory usage threshold before running Torch GC", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1}),
|
||||
|
||||
"cuda_compile_sep": OptionInfo("<h2>Model Compile</h2>", "", gr.HTML),
|
||||
@@ -329,6 +330,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
|
||||
"cuda_compile_precompile": OptionInfo(False, "Model compile precompile"),
|
||||
"cuda_compile_verbose": OptionInfo(False, "Model compile verbose mode"),
|
||||
"cuda_compile_errors": OptionInfo(True, "Model compile suppress errors"),
|
||||
"diffusers_quantization": OptionInfo(False, "Enable dynamic quantization"),
|
||||
|
||||
"ipex_sep": OptionInfo("<h2>IPEX, DirectML and OpenVINO</h2>", "", gr.HTML),
|
||||
"ipex_optimize": OptionInfo(False if not devices.backend == "ipex" else True, "Enable IPEX Optimize for Intel GPUs"),
|
||||
|
||||
Reference in New Issue
Block a user