From f3be294d536bb63328bae369b0eb2cd5e4d68c2a Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 8 Feb 2024 12:56:06 -0500 Subject: [PATCH] add deep-cache support --- CHANGELOG.md | 5 +++-- TODO.md | 4 +++- installer.py | 2 ++ modules/sd_models_compile.py | 26 ++++++++++++++++++++++++++ modules/shared.py | 5 +++-- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1cb6e0c5..e7b41275c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,15 @@ ## Update for 2024-02-08 -TODO: controlnet, adetailer, img2img mask blur and padding - - **FaceID** now works with multiple input images - **ONNX**: - allow specify onnx default provider and cpu fallback *settings -> diffusers* - allow manual install of specific onnx flavor *settings -> onnx* +- add support for [deep-cache](https://github.com/horseee/DeepCache) model acceleration + it can produce massive speedups (2x-5x) with no overhead, but with some loss of quality + *settings -> compute -> model compile -> deep-cache* and *settings -> compute -> model compile -> cache interval* - **fixes**: - `ipex` handle dependencies, thanks @Disty0 - `insightface` handle dependencies diff --git a/TODO.md b/TODO.md index 34edd0de5..9ec95b57d 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,9 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma ## Candidates for next release +- lock down controlnet +- test adetails +- clip-skip with sdxl - multi-ipadapter: - control second pass: - diffusers public callbacks @@ -14,4 +17,3 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma - preprocess api - remove kohya from submodules - bind panZoom to control input -- deep-cache: diff --git a/installer.py b/installer.py index 280345935..d4a2d32c7 100644 --- a/installer.py +++ b/installer.py @@ -568,6 +568,8 @@ def check_torch(): log.debug(f'Cannot install xformers package: {e}') if opts.get('cuda_compile_backend', '') == 'hidet': install('hidet', 'hidet') + if opts.get('cuda_compile_backend', '') == 'deep-cache': + install('DeepCache') if opts.get('nncf_compress_weights', False) and not args.use_openvino: install('nncf==2.7.0', 'nncf') if args.profile: diff --git a/modules/sd_models_compile.py b/modules/sd_models_compile.py index a17b74b17..63977f4e6 100644 --- a/modules/sd_models_compile.py +++ b/modules/sd_models_compile.py @@ -23,6 +23,9 @@ class CompiledModelState: self.partitioned_modules = {} +deepcache_worker = None + + def ipex_optimize(sd_model): try: t0 = time.time() @@ -212,6 +215,25 @@ def compile_torch(sd_model): return sd_model +def compile_deepcache(sd_model): + global deepcache_worker # pylint: disable=global-statement + try: + from DeepCache import DeepCacheSDHelper + except Exception as e: + shared.log.warning(f'Model compile using deep-cache: {e}') + return sd_model + t0 = time.time() + if deepcache_worker is not None: + deepcache_worker.disable() + deepcache_worker = DeepCacheSDHelper(pipe=sd_model) + deepcache_worker.set_params(cache_interval=shared.opts.deep_cache_interval, cache_branch_id=0) + deepcache_worker.enable() + t1 = time.time() + shared.log.info(f"Model compile: task=DeepCache config={deepcache_worker.params} time={t1-t0:.2f}") + # config={'cache_interval': 3, 'cache_layer_id': 0, 'cache_block_id': 0, 'skip_mode': 'uniform'} time=0.00 + return sd_model + + def compile_diffusers(sd_model): if shared.opts.ipex_optimize: sd_model = ipex_optimize(sd_model) @@ -225,7 +247,11 @@ def compile_diffusers(sd_model): shared.log.info(f"Model compile: pipeline={sd_model.__class__.__name__} mode={shared.opts.cuda_compile_mode} backend={shared.opts.cuda_compile_backend} fullgraph={shared.opts.cuda_compile_fullgraph} compile={shared.opts.cuda_compile}") if shared.opts.cuda_compile_backend == 'stable-fast': sd_model = compile_stablefast(sd_model) + elif shared.opts.cuda_compile_backend == 'deep-cache': + sd_model = compile_deepcache(sd_model) else: + if deepcache_worker is not None: + deepcache_worker.disable() sd_model = compile_torch(sd_model) return sd_model diff --git a/modules/shared.py b/modules/shared.py index d27e04822..0f594a050 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -363,13 +363,15 @@ options_templates.update(options_section(('cuda', "Compute Settings"), { "cuda_compile_sep": OptionInfo("

Model Compile

", "", gr.HTML), "cuda_compile": OptionInfo([] if not cmd_opts.use_openvino else ["Model", "VAE", "Upscaler"], "Compile Model", gr.CheckboxGroup, {"choices": ["Model", "VAE", "Text Encoder", "Upscaler"]}), - "cuda_compile_backend": OptionInfo("none" if not cmd_opts.use_openvino else "openvino_fx", "Model compile backend", gr.Radio, {"choices": ['none', 'inductor', 'cudagraphs', 'aot_ts_nvfuser', 'hidet', 'ipex', 'openvino_fx', 'stable-fast', 'olive-ai']}), + "cuda_compile_backend": OptionInfo("none" if not cmd_opts.use_openvino else "openvino_fx", "Model compile backend", gr.Radio, {"choices": ['none', 'inductor', 'cudagraphs', 'aot_ts_nvfuser', 'hidet', 'ipex', 'openvino_fx', 'stable-fast', 'deep-cache', 'olive-ai']}), "cuda_compile_mode": OptionInfo("default", "Model compile mode", gr.Radio, {"choices": ['default', 'reduce-overhead', 'max-autotune', 'max-autotune-no-cudagraphs']}), "cuda_compile_fullgraph": OptionInfo(False, "Model compile fullgraph"), "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, "Dynamic quantization with TorchAO"), + "deep_cache_interval": OptionInfo(3.0, "DeepCache cache interval", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1}), + "nncf_compress_weights": OptionInfo([], "Compress Model weights with NNCF", gr.CheckboxGroup, {"choices": ["Model", "VAE", "Text Encoder"], "visible": backend == Backend.DIFFUSERS}), "ipex_sep": OptionInfo("

IPEX

", "", gr.HTML, {"visible": devices.backend == "ipex"}), @@ -904,7 +906,6 @@ devices.device, devices.device_interrogate, devices.device_gfpgan, devices.devic devices.onnx = [opts.onnx_execution_provider] if opts.onnx_cpu_fallback and 'CPUExecutionProvider' not in devices.onnx: devices.onnx.append('CPUExecutionProvider') -print("HERE1", opts.onnx_cpu_fallback, devices.onnx) device = devices.device batch_cond_uncond = opts.always_batch_cond_uncond or not (cmd_opts.lowvram or cmd_opts.medvram) parallel_processing_allowed = not cmd_opts.lowvram