diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 8e635b3d3..f306c63f2 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v3 with: repository: AUTOMATIC1111/stable-diffusion-webui - ref: v1.5.1 + ref: v1.6.0 - name: Checkout Controlnet extension uses: actions/checkout@v3 with: diff --git a/scripts/deforum_helpers/deforum_controlnet.py b/scripts/deforum_helpers/deforum_controlnet.py index 0da7bccfc..e7deefcd1 100644 --- a/scripts/deforum_helpers/deforum_controlnet.py +++ b/scripts/deforum_helpers/deforum_controlnet.py @@ -18,6 +18,7 @@ # https://github.com/Mikubill/sd-webui-controlnet — controlnet repo import os +import copy import gradio as gr import scripts from PIL import Image @@ -264,7 +265,27 @@ def read_cn_data(cn_idx): if not any(os.path.exists(cn_inputframes) for cn_inputframes in cn_inputframes_list) and not any_loopback_mode: print(f'\033[33mNeither the base nor the masking frames for ControlNet were found. Using the regular pipeline\033[0m') - p.scripts = scripts.scripts_img2img if is_img2img else scripts.scripts_txt2img + # Remove all scripts except controlnet. + # + # This is required because controlnet's access to p.script_args invokes @script_args.setter, + # which triggers *all* alwayson_scripts' setup() functions, with whatever happens to be in script_args. + # In the case of seed.py (which we really don't need with deforum), this ovewrites our p.seed & co, which we + # had carefully prepared previously. So let's remove the scripts to avoid the problem. + # + # An alternative would be to populate all the args with the correct values + # for all scripts, but this seems even more fragile, as it would break + # if a1111 adds or removed scripts. + # + # Note that we must copy scripts.scripts_img2img or scripts.scripts_txt2img before mutating it + # because it persists across requests. Shallow-copying is sufficient because we only mutate a top-level + # reference (scripts.alwayson_scripts) + # + p.scripts = copy.copy(scripts.scripts_img2img if is_img2img else scripts.scripts_txt2img) + controlnet_script = find_controlnet_script(p) + p.scripts.alwayson_scripts = [controlnet_script] + # Filling the list with None is safe because only the length will be considered, + # and all cn args will be replaced. + p.script_args_value = [None] * controlnet_script.args_to def create_cnu_dict(cn_args, prefix, img_np, mask_np, frame_idx, CnSchKeys): @@ -292,9 +313,14 @@ def create_cnu_dict(cn_args, prefix, img_np, mask_np, frame_idx, CnSchKeys): cn_units = [cnet.ControlNetUnit(**create_cnu_dict(controlnet_args, f"cn_{i + 1}", img_np, mask_np, frame_idx, CnSchKeys)) for i, (img_np, mask_np) in enumerate(zip(images_np, masks_np))] - p.script_args = {"enabled": True} cnet.update_cn_script_in_processing(p, cn_units, is_img2img=is_img2img, is_ui=False) +def find_controlnet_script(p): + controlnet_script = next((script for script in p.scripts.alwayson_scripts if script.title().lower() == "controlnet"), None) + if not controlnet_script: + raise Exception("ControlNet script not found.") + return controlnet_script + def process_controlnet_input_frames(args, anim_args, controlnet_args, video_path, mask_path, outdir_suffix, id): if (video_path or mask_path) and getattr(controlnet_args, f'cn_{id}_enabled'): frame_path = os.path.join(args.outdir, f'controlnet_{id}_{outdir_suffix}') diff --git a/scripts/deforum_helpers/src/midas/backbones/beit.py b/scripts/deforum_helpers/src/midas/backbones/beit.py index 7a24e02cd..9d6d1e015 100644 --- a/scripts/deforum_helpers/src/midas/backbones/beit.py +++ b/scripts/deforum_helpers/src/midas/backbones/beit.py @@ -95,16 +95,23 @@ def block_forward(self, x, resolution, shared_rel_pos_bias: Optional[torch.Tenso """ Modification of timm.models.beit.py: Block.forward to support arbitrary window sizes. """ + + if hasattr(self, 'drop_path1'): + drop_path_compat = self.drop_path1 + elif hasattr(self.target, 'drop_path'): + drop_path_compat = self.drop_path + else: + raise AttributeError("Neither drop_path1 nor drop_path exists on the target.") + if self.gamma_1 is None: - x = x + self.drop_path(self.attn(self.norm1(x), resolution, shared_rel_pos_bias=shared_rel_pos_bias)) - x = x + self.drop_path(self.mlp(self.norm2(x))) + x = x + drop_path_compat(self.attn(self.norm1(x), resolution, shared_rel_pos_bias=shared_rel_pos_bias)) + x = x + drop_path_compat(self.mlp(self.norm2(x))) else: - x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), resolution, + x = x + drop_path_compat(self.gamma_1 * self.attn(self.norm1(x), resolution, shared_rel_pos_bias=shared_rel_pos_bias)) - x = x + self.drop_path(self.gamma_2 * self.mlp(self.norm2(x))) + x = x + drop_path_compat(self.gamma_2 * self.mlp(self.norm2(x))) return x - def beit_forward_features(self, x): """ Modification of timm.models.beit.py: Beit.forward_features to support arbitrary window sizes.