From f2b84b15b6c8366751041a713028e2431cda63af Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Wed, 4 Sep 2024 10:36:49 -0400 Subject: [PATCH] update script callbacks --- modules/control/run.py | 1 + modules/img2img.py | 1 + modules/scripts.py | 21 +++++++++++- modules/txt2img.py | 1 + scripts/animatediff.py | 74 ++++++++++++++++++------------------------ 5 files changed, 55 insertions(+), 43 deletions(-) diff --git a/modules/control/run.py b/modules/control/run.py index a69b30198..f41c82dd2 100644 --- a/modules/control/run.py +++ b/modules/control/run.py @@ -646,6 +646,7 @@ def control_run(units: List[unit.Unit] = [], inputs: List[Image.Image] = [], ini processed: processing.Processed = processing.process_images(p) # run actual pipeline else: script_run = True + processed = p.scripts.after(p, processed, *p.script_args) output = None if processed is not None: output = processed.images diff --git a/modules/img2img.py b/modules/img2img.py index 319d02171..38620ebd0 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -103,6 +103,7 @@ def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args) for k, v in items.items(): image.info[k] = v images.save_image(image, path=output_dir, basename=basename, seed=None, prompt=None, extension=ext, info=geninfo, short_filename=True, no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=image.info, forced_filename=forced_filename) + proce = modules.scripts.scripts_img2img.after(p, proc, *args) shared.log.debug(f'Processed: images={len(batch_image_files)} memory={memory_stats()} batch') diff --git a/modules/scripts.py b/modules/scripts.py index ef24e359a..9e92b7f35 100644 --- a/modules/scripts.py +++ b/modules/scripts.py @@ -488,7 +488,26 @@ class ScriptRunner: if not hasattr(p, 'init_images') and p.task_args.get('image', None) is not None: p.init_images = p.task_args['image'] parsed = p.per_script_args.get(script.title(), args[script.args_from:script.args_to]) - processed = script.run(p, *parsed) + if hasattr(script, 'run'): + processed = script.run(p, *parsed) + else: + errors.log.error(f'Script: file="{script.filename}" no run function defined') + s.record(script.title()) + s.report() + return processed + + def after(self, p, processed, *args): + s = ScriptSummary('after') + script_index = args[0] if len(args) > 0 else 0 + if script_index == 0: + return None + script = self.selectable_scripts[script_index-1] + if script is None or not hasattr(script, 'after'): + return None + parsed = p.per_script_args.get(script.title(), args[script.args_from:script.args_to]) + after_processed = script.after(p, processed, *parsed) + if after_processed is not None: + processed = after_processed s.record(script.title()) s.report() return processed diff --git a/modules/txt2img.py b/modules/txt2img.py index 76b0a7c45..22ff74d3e 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -89,6 +89,7 @@ def txt2img(id_task, processed = scripts.scripts_txt2img.run(p, *args) if processed is None: processed = processing.process_images(p) + processed = scripts.scripts_txt2img.after(p, processed, *args) p.close() if processed is None: return [], '', '', 'Error: processing failed' diff --git a/scripts/animatediff.py b/scripts/animatediff.py index 86177cf17..e99d0ddbe 100644 --- a/scripts/animatediff.py +++ b/scripts/animatediff.py @@ -1,15 +1,3 @@ -""" -Lightweight AnimateDiff implementation in Diffusers -Docs: -TODO animatediff items: -- SDXL -- Custom models -- Custom LORAs -- Enable second pass -- TemporalDiff: https://huggingface.co/CiaraRowles/TemporalDiff/tree/main -- AnimateFace: https://huggingface.co/nlper2022/animatediff_face_512/tree/main -""" - import os import gradio as gr import diffusers @@ -141,8 +129,9 @@ class Script(scripts.Script): def title(self): return 'AnimateDiff' - def show(self, _is_img2img): - return scripts.AlwaysVisible if shared.native else False + def show(self, is_img2img): + # return scripts.AlwaysVisible if shared.native else False + return not is_img2img def ui(self, _is_img2img): @@ -154,38 +143,39 @@ class Script(scripts.Script): gr.update(visible=video_type == 'MP4'), ] - with gr.Accordion('AnimateDiff', open=False, elem_id='animatediff'): + with gr.Row(): + gr.HTML("  AnimateDiff
") + with gr.Row(): + adapter_index = gr.Dropdown(label='Adapter', choices=list(ADAPTERS), value='None') + frames = gr.Slider(label='Frames', minimum=1, maximum=64, step=1, value=16) + with gr.Row(): + override_scheduler = gr.Checkbox(label='Override sampler', value=True) + with gr.Row(): + lora_index = gr.Dropdown(label='Lora', choices=list(LORAS), value='None') + strength = gr.Slider(label='Strength', minimum=0.0, maximum=2.0, step=0.05, value=1.0) + with gr.Row(): + latent_mode = gr.Checkbox(label='Latent mode', value=True, visible=False) + with gr.Row(): + video_type = gr.Dropdown(label='Video file', choices=['None', 'GIF', 'PNG', 'MP4'], value='None') + duration = gr.Slider(label='Duration', minimum=0.25, maximum=10, step=0.25, value=2, visible=False) + with gr.Accordion('FreeInit', open=False): with gr.Row(): - adapter_index = gr.Dropdown(label='Adapter', choices=list(ADAPTERS), value='None') - frames = gr.Slider(label='Frames', minimum=1, maximum=64, step=1, value=16) + fi_method = gr.Dropdown(label='Method', choices=['none', 'butterworth', 'ideal', 'gaussian'], value='none') with gr.Row(): - override_scheduler = gr.Checkbox(label='Override sampler', value=True) + # fi_fast = gr.Checkbox(label='Fast sampling', value=False) + fi_iters = gr.Slider(label='Iterations', minimum=1, maximum=10, step=1, value=3) + fi_order = gr.Slider(label='Order', minimum=1, maximum=10, step=1, value=4) with gr.Row(): - lora_index = gr.Dropdown(label='Lora', choices=list(LORAS), value='None') - strength = gr.Slider(label='Strength', minimum=0.0, maximum=2.0, step=0.05, value=1.0) - with gr.Row(): - latent_mode = gr.Checkbox(label='Latent mode', value=True, visible=False) - with gr.Row(): - video_type = gr.Dropdown(label='Video file', choices=['None', 'GIF', 'PNG', 'MP4'], value='None') - duration = gr.Slider(label='Duration', minimum=0.25, maximum=10, step=0.25, value=2, visible=False) - with gr.Accordion('FreeInit', open=False): - with gr.Row(): - fi_method = gr.Dropdown(label='Method', choices=['none', 'butterworth', 'ideal', 'gaussian'], value='none') - with gr.Row(): - # fi_fast = gr.Checkbox(label='Fast sampling', value=False) - fi_iters = gr.Slider(label='Iterations', minimum=1, maximum=10, step=1, value=3) - fi_order = gr.Slider(label='Order', minimum=1, maximum=10, step=1, value=4) - with gr.Row(): - fi_spatial = gr.Slider(label='Spatial frequency', minimum=0.0, maximum=1.0, step=0.05, value=0.25) - fi_temporal = gr.Slider(label='Temporal frequency', minimum=0.0, maximum=1.0, step=0.05, value=0.25) - with gr.Row(): - gif_loop = gr.Checkbox(label='Loop', value=True, visible=False) - mp4_pad = gr.Slider(label='Pad frames', minimum=0, maximum=24, step=1, value=1, visible=False) - mp4_interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False) - video_type.change(fn=video_type_change, inputs=[video_type], outputs=[duration, gif_loop, mp4_pad, mp4_interpolate]) + fi_spatial = gr.Slider(label='Spatial frequency', minimum=0.0, maximum=1.0, step=0.05, value=0.25) + fi_temporal = gr.Slider(label='Temporal frequency', minimum=0.0, maximum=1.0, step=0.05, value=0.25) + with gr.Row(): + gif_loop = gr.Checkbox(label='Loop', value=True, visible=False) + mp4_pad = gr.Slider(label='Pad frames', minimum=0, maximum=24, step=1, value=1, visible=False) + mp4_interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False) + video_type.change(fn=video_type_change, inputs=[video_type], outputs=[duration, gif_loop, mp4_pad, mp4_interpolate]) return [adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal] - def process(self, p: processing.StableDiffusionProcessing, adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal): # pylint: disable=arguments-differ, unused-argument + def run(self, p: processing.StableDiffusionProcessing, adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal): # pylint: disable=arguments-differ, unused-argument adapter = ADAPTERS[adapter_index] lora = LORAS[lora_index] set_adapter(adapter) @@ -228,7 +218,7 @@ class Script(scripts.Script): if not latent_mode: p.task_args['output_type'] = 'np' - def postprocess(self, p: processing.StableDiffusionProcessing, processed: processing.Processed, adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal): # pylint: disable=arguments-differ, unused-argument + def after(self, p: processing.StableDiffusionProcessing, processed: processing.Processed, adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal): # pylint: disable=arguments-differ, unused-argument from modules.images import save_video if video_type != 'None': save_video(p, filename=None, images=processed.images, video_type=video_type, duration=duration, loop=gif_loop, pad=mp4_pad, interpolate=mp4_interpolate)