From 1807cd64e4de87dbd09198f8782832eab099596d Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Sat, 24 Aug 2024 00:43:21 -0500 Subject: [PATCH 01/11] Updated ControlNetAdvanced to work with Flux controlnet, beginning of rework of weights --- adv_control/control.py | 24 +++++++++++++++--------- adv_control/nodes_weight.py | 12 ++++++------ adv_control/utils.py | 3 +++ 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/adv_control/control.py b/adv_control/control.py index 4eb0d18..1d81e39 100644 --- a/adv_control/control.py +++ b/adv_control/control.py @@ -8,7 +8,7 @@ import comfy.utils import comfy.model_management import comfy.model_detection import comfy.controlnet as comfy_cn -from comfy.controlnet import ControlBase, ControlNet, ControlLora, T2IAdapter +from comfy.controlnet import ControlBase, ControlNet, ControlLora, T2IAdapter, StrengthType from comfy.model_patcher import ModelPatcher from .control_sparsectrl import SparseModelPatcher, SparseControlNet, SparseCtrlMotionWrapper, SparseSettings, SparseConst @@ -21,7 +21,7 @@ from .logger import logger class ControlNetAdvanced(ControlNet, AdvancedControlBase): - def __init__(self, control_model, timestep_keyframes: TimestepKeyframeGroup, global_average_pooling=False, compression_ratio=8, latent_format=None, device=None, load_device=None, manual_cast_dtype=None): + def __init__(self, control_model, timestep_keyframes: TimestepKeyframeGroup, global_average_pooling=False, compression_ratio=8, latent_format=None, device=None, load_device=None, manual_cast_dtype=None, extra_conds=["y"], strength_type=StrengthType.CONSTANT): super().__init__(control_model=control_model, global_average_pooling=global_average_pooling, compression_ratio=compression_ratio, latent_format=latent_format, device=device, load_device=load_device, manual_cast_dtype=manual_cast_dtype) AdvancedControlBase.__init__(self, super(), timestep_keyframes=timestep_keyframes, weights_default=ControlWeights.controlnet()) @@ -64,9 +64,9 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): actual_cond_hint_orig = self.cond_hint_original if self.cond_hint_original.size(0) < self.full_latent_length: actual_cond_hint_orig = extend_to_batch_size(tensor=actual_cond_hint_orig, batch_size=self.full_latent_length) - self.cond_hint = comfy.utils.common_upscale(actual_cond_hint_orig[self.sub_idxs], x_noisy.shape[3] * compression_ratio, x_noisy.shape[2] * compression_ratio, 'nearest-exact', "center") + self.cond_hint = comfy.utils.common_upscale(actual_cond_hint_orig[self.sub_idxs], x_noisy.shape[3] * compression_ratio, x_noisy.shape[2] * compression_ratio, self.upscale_algorithm, "center") else: - self.cond_hint = comfy.utils.common_upscale(self.cond_hint_original, x_noisy.shape[3] * compression_ratio, x_noisy.shape[2] * compression_ratio, 'nearest-exact', "center") + self.cond_hint = comfy.utils.common_upscale(self.cond_hint_original, x_noisy.shape[3] * compression_ratio, x_noisy.shape[2] * compression_ratio, self.upscale_algorithm, "center") if self.vae is not None: loaded_models = comfy.model_management.loaded_models(only_currently_used=True) self.cond_hint = self.vae.encode(self.cond_hint.movedim(1, -1)) @@ -81,17 +81,22 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): self.prepare_mask_cond_hint(x_noisy=x_noisy, t=t, cond=cond, batched_number=batched_number, dtype=dtype) context = cond.get('crossattn_controlnet', cond['c_crossattn']) - y = cond.get('y', None) - if y is not None: - y = y.to(dtype) + extra = self.extra_args.copy() + for c in self.extra_conds: + temp = cond.get(c, None) + if temp is not None: + extra[c] = temp.to(dtype) + timestep = self.model_sampling_current.timestep(t) x_noisy = self.model_sampling_current.calculate_input(t, x_noisy) - control = self.control_model(x=x_noisy.to(dtype), hint=self.cond_hint, timesteps=timestep.float(), context=context.to(dtype), y=y) + control = self.control_model(x=x_noisy.to(dtype), hint=self.cond_hint, timesteps=timestep.to(dtype), context=context.to(dtype), **extra) return self.control_merge(control, control_prev, output_dtype) def copy(self): c = ControlNetAdvanced(self.control_model, self.timestep_keyframes, global_average_pooling=self.global_average_pooling, load_device=self.load_device, manual_cast_dtype=self.manual_cast_dtype) + c.control_model = self.control_model + c.control_model_wrapped = self.control_model_wrapped self.copy_to(c) self.copy_to_advanced(c) return c @@ -99,7 +104,8 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): @staticmethod def from_vanilla(v: ControlNet, timestep_keyframe: TimestepKeyframeGroup=None) -> 'ControlNetAdvanced': to_return = ControlNetAdvanced(control_model=v.control_model, timestep_keyframes=timestep_keyframe, - global_average_pooling=v.global_average_pooling, compression_ratio=v.compression_ratio, latent_format=v.latent_format, device=v.device, load_device=v.load_device, manual_cast_dtype=v.manual_cast_dtype) + global_average_pooling=v.global_average_pooling, compression_ratio=v.compression_ratio, latent_format=v.latent_format, device=v.device, load_device=v.load_device, + manual_cast_dtype=v.manual_cast_dtype) v.copy_to(to_return) return to_return diff --git a/adv_control/nodes_weight.py b/adv_control/nodes_weight.py index 5b9bd04..263c529 100644 --- a/adv_control/nodes_weight.py +++ b/adv_control/nodes_weight.py @@ -42,7 +42,7 @@ class ScaledSoftMaskedUniversalWeights: "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), "cn_extras": ("CN_WEIGHTS_EXTRAS",), - "autosize": ("ACNAUTOSIZE", {"padding": 75}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } @@ -77,7 +77,7 @@ class ScaledSoftUniversalWeights: "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), "cn_extras": ("CN_WEIGHTS_EXTRAS",), - "autosize": ("ACNAUTOSIZE", {"padding": 20}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } @@ -115,7 +115,7 @@ class SoftControlNetWeights: "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), "cn_extras": ("CN_WEIGHTS_EXTRAS",), - "autosize": ("ACNAUTOSIZE", {"padding": 50}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } @@ -157,7 +157,7 @@ class CustomControlNetWeights: "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), "cn_extras": ("CN_WEIGHTS_EXTRAS",), - "autosize": ("ACNAUTOSIZE", {"padding": 65}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } @@ -190,7 +190,7 @@ class SoftT2IAdapterWeights: "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), "cn_extras": ("CN_WEIGHTS_EXTRAS",), - "autosize": ("ACNAUTOSIZE", {"padding": 55}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } @@ -223,7 +223,7 @@ class CustomT2IAdapterWeights: "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), "cn_extras": ("CN_WEIGHTS_EXTRAS",), - "autosize": ("ACNAUTOSIZE", {"padding": 65}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } diff --git a/adv_control/utils.py b/adv_control/utils.py index b71e371..df7a67e 100644 --- a/adv_control/utils.py +++ b/adv_control/utils.py @@ -175,6 +175,9 @@ class ControlWeights: def get(self, idx: int, control: dict[str, list[Tensor]], key: str, default=1.0) -> Union[float, Tensor]: # if weights is not none, return index if self.weights is not None: + # support live calculation + if callable(self.weights): + return self.weights(idx=idx, control=control, key=key) # if middle weight, need to pretend index is actually after all the output weights (if applicable) if key == "middle" and "output" in control: idx += len(control["output"]) From 49609d318f5df3baec1e4a9b92a0e8aded81fc38 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Sat, 24 Aug 2024 07:31:26 -0500 Subject: [PATCH 02/11] Refactored cn weights to separate out input, middle, and output blocks, improved soft weight behavior to generalize math to be architecture agnostic (for the most part) --- adv_control/control.py | 38 ++++++++--- adv_control/control_plusplus.py | 13 +++- adv_control/nodes.py | 14 ++-- adv_control/nodes_weight.py | 32 ++++----- adv_control/utils.py | 115 ++++++++++++++++++-------------- 5 files changed, 126 insertions(+), 86 deletions(-) diff --git a/adv_control/control.py b/adv_control/control.py index 1d81e39..4225a47 100644 --- a/adv_control/control.py +++ b/adv_control/control.py @@ -26,8 +26,16 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): AdvancedControlBase.__init__(self, super(), timestep_keyframes=timestep_keyframes, weights_default=ControlWeights.controlnet()) def get_universal_weights(self) -> ControlWeights: - raw_weights = [(self.weights.base_multiplier ** float(12 - i)) for i in range(13)] - return self.weights.copy_with_new_weights(raw_weights) + def cn_weights_func(idx: int, control: dict[str, list[Tensor]], key: str): + if key == "middle": + return 1.0 + c_len = len(control[key]) + raw_weights = [(self.weights.base_multiplier ** float((c_len) - i)) for i in range(c_len+1)] + raw_weights = raw_weights[:-1] + if key == "input": + raw_weights.reverse() + return raw_weights[idx] + return self.weights.copy_with_new_weights(new_weight_func=cn_weights_func) def get_control_advanced(self, x_noisy, t, cond, batched_number): # perform special version of get_control that supports sliding context and masks @@ -127,18 +135,28 @@ class T2IAdapterAdvanced(T2IAdapter, AdvancedControlBase): return AdvancedControlBase.control_merge_inject(self, control, control_prev, output_dtype) def get_universal_weights(self) -> ControlWeights: - raw_weights = [(self.weights.base_multiplier ** float(7 - i)) for i in range(8)] - raw_weights = [raw_weights[-8], raw_weights[-3], raw_weights[-2], raw_weights[-1]] - raw_weights = get_properly_arranged_t2i_weights(raw_weights) - raw_weights.reverse() # need to reverse to match recent ComfyUI changes - return self.weights.copy_with_new_weights(raw_weights) + def t2i_weights_func(idx: int, control: dict[str, list[Tensor]], key: str): + if key == "middle": + return 1.0 + c_len = 8 #len(control[key]) + raw_weights = [(self.weights.base_multiplier ** float((c_len-1) - i)) for i in range(c_len)] + raw_weights = [raw_weights[-c_len], raw_weights[-3], raw_weights[-2], raw_weights[-1]] + raw_weights = get_properly_arranged_t2i_weights(raw_weights) + if key == "input": + raw_weights.reverse() + return raw_weights[idx] + return self.weights.copy_with_new_weights(new_weight_func=t2i_weights_func) def get_calc_pow(self, idx: int, control: dict[str, list[Tensor]], key: str) -> int: + if key == "middle": + return 0 # match how T2IAdapterAdvanced deals with universal weights - indeces = [7 - i for i in range(8)] - indeces = [indeces[-8], indeces[-3], indeces[-2], indeces[-1]] + c_len = 8 #len(control[key]) + indeces = [(c_len-1) - i for i in range(c_len)] + indeces = [indeces[-c_len], indeces[-3], indeces[-2], indeces[-1]] indeces = get_properly_arranged_t2i_weights(indeces) - indeces.reverse() # need to reverse to match recent ComfyUI changes + if key == "input": + indeces.reverse() # need to reverse to match recent ComfyUI changes return indeces[idx] def get_control_advanced(self, x_noisy, t, cond, batched_number): diff --git a/adv_control/control_plusplus.py b/adv_control/control_plusplus.py index a6f5ca9..cb5c80b 100644 --- a/adv_control/control_plusplus.py +++ b/adv_control/control_plusplus.py @@ -237,9 +237,16 @@ class ControlNetPlusPlusAdvanced(ControlNet, AdvancedControlBase): self.single_control_type: str = None def get_universal_weights(self) -> ControlWeights: - # TODO: match actual layer count of model - raw_weights = [(self.weights.base_multiplier ** float(12 - i)) for i in range(13)] - return self.weights.copy_with_new_weights(raw_weights) + def cn_weights_func(idx: int, control: dict[str, list[Tensor]], key: str): + if key == "middle": + return 1.0 + c_len = len(control[key]) + raw_weights = [(self.weights.base_multiplier ** float((c_len) - i)) for i in range(c_len+1)] + raw_weights = raw_weights[:-1] + if key == "input": + raw_weights.reverse() + return raw_weights[idx] + return self.weights.copy_with_new_weights(new_weight_func=cn_weights_func) def verify_control_type(self, model_name: str, pp_group: PlusPlusInputGroup=None): if pp_group is not None: diff --git a/adv_control/nodes.py b/adv_control/nodes.py index 55c2db2..470149f 100644 --- a/adv_control/nodes.py +++ b/adv_control/nodes.py @@ -7,8 +7,8 @@ from comfy.model_patcher import ModelPatcher from .control import load_controlnet, convert_to_advanced, is_advanced_controlnet, is_sd3_advanced_controlnet from .utils import ControlWeights, LatentKeyframeGroup, TimestepKeyframeGroup, AbstractPreprocWrapper, BIGMAX -from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeights, SoftControlNetWeights, CustomControlNetWeights, - SoftT2IAdapterWeights, CustomT2IAdapterWeights) +from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeightsDeprecated, SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated, + SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated) from .nodes_keyframes import (LatentKeyframeGroupNode, LatentKeyframeInterpolationNode, LatentKeyframeBatchedGroupNode, LatentKeyframeNode, TimestepKeyframeNode, TimestepKeyframeInterpolationNode, TimestepKeyframeFromStrengthListNode) from .nodes_sparsectrl import SparseCtrlMergedLoaderAdvanced, SparseCtrlLoaderAdvanced, SparseIndexMethodNode, SparseSpreadMethodNode, RgbSparseCtrlPreprocessor, SparseWeightExtras @@ -200,12 +200,12 @@ NODE_CLASS_MAPPINGS = { "ControlNetLoaderAdvanced": ControlNetLoaderAdvanced, "DiffControlNetLoaderAdvanced": DiffControlNetLoaderAdvanced, # Weights - "ScaledSoftControlNetWeights": ScaledSoftUniversalWeights, + "ScaledSoftControlNetWeights": ScaledSoftUniversalWeightsDeprecated, "ScaledSoftMaskedUniversalWeights": ScaledSoftMaskedUniversalWeights, - "SoftControlNetWeights": SoftControlNetWeights, - "CustomControlNetWeights": CustomControlNetWeights, - "SoftT2IAdapterWeights": SoftT2IAdapterWeights, - "CustomT2IAdapterWeights": CustomT2IAdapterWeights, + "SoftControlNetWeights": SoftControlNetWeightsDeprecated, + "CustomControlNetWeights": CustomControlNetWeightsDeprecated, + "SoftT2IAdapterWeights": SoftT2IAdapterWeightsDeprecated, + "CustomT2IAdapterWeights": CustomT2IAdapterWeightsDeprecated, "ACN_DefaultUniversalWeights": DefaultWeights, # SparseCtrl "ACN_SparseCtrlRGBPreprocessor": RgbSparseCtrlPreprocessor, diff --git a/adv_control/nodes_weight.py b/adv_control/nodes_weight.py index 263c529..85f2af7 100644 --- a/adv_control/nodes_weight.py +++ b/adv_control/nodes_weight.py @@ -66,7 +66,7 @@ class ScaledSoftMaskedUniversalWeights: return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class ScaledSoftUniversalWeights: +class ScaledSoftUniversalWeightsDeprecated: @classmethod def INPUT_TYPES(s): return { @@ -88,11 +88,11 @@ class ScaledSoftUniversalWeights: CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights" def load_weights(self, base_multiplier, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights = ControlWeights.universal(base_multiplier=base_multiplier, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) - return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + weights = ControlWeights.universal(base_multiplier=base_multiplier, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class SoftControlNetWeights: +class SoftControlNetWeightsDeprecated: @classmethod def INPUT_TYPES(s): return { @@ -128,13 +128,14 @@ class SoftControlNetWeights: def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, - weight_07, weight_08, weight_09, weight_10, weight_11, weight_12] - weights = ControlWeights.controlnet(weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) + weights_output = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, + weight_07, weight_08, weight_09, weight_10, weight_11] + weights_middle = [weight_12] + weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class CustomControlNetWeights: +class CustomControlNetWeightsDeprecated: @classmethod def INPUT_TYPES(s): return { @@ -170,13 +171,14 @@ class CustomControlNetWeights: def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, - weight_07, weight_08, weight_09, weight_10, weight_11, weight_12] - weights = ControlWeights.controlnet(weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) + weights_output = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, + weight_07, weight_08, weight_09, weight_10, weight_11] + weights_middle = [weight_12] + weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class SoftT2IAdapterWeights: +class SoftT2IAdapterWeightsDeprecated: @classmethod def INPUT_TYPES(s): return { @@ -205,11 +207,11 @@ class SoftT2IAdapterWeights: weights = [weight_00, weight_01, weight_02, weight_03] weights = get_properly_arranged_t2i_weights(weights) weights.reverse() # to account for recent ComfyUI changes - weights = ControlWeights.t2iadapter(weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) + weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class CustomT2IAdapterWeights: +class CustomT2IAdapterWeightsDeprecated: @classmethod def INPUT_TYPES(s): return { @@ -238,5 +240,5 @@ class CustomT2IAdapterWeights: weights = [weight_00, weight_01, weight_02, weight_03] weights = get_properly_arranged_t2i_weights(weights) weights.reverse() # to account for recent ComfyUI changes - weights = ControlWeights.t2iadapter(weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) + weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) diff --git a/adv_control/utils.py b/adv_control/utils.py index df7a67e..e2d5a48 100644 --- a/adv_control/utils.py +++ b/adv_control/utils.py @@ -157,14 +157,16 @@ class ControlWeightType: class ControlWeights: - def __init__(self, weight_type: str, base_multiplier: float=1.0, flip_weights: bool=False, weights: list[float]=None, weight_mask: Tensor=None, + def __init__(self, weight_type: str, base_multiplier: float=1.0, + weights_input: list[float]=None, weights_middle: list[float]=None, weights_output: list[float]=None, + weight_func: Callable=None, weight_mask: Tensor=None, uncond_multiplier=1.0, uncond_mask: Tensor=None, extras: dict[str]={},): self.weight_type = weight_type self.base_multiplier = base_multiplier - self.flip_weights = flip_weights - self.weights = weights - if self.weights is not None and self.flip_weights: - self.weights.reverse() + self.weights_input = weights_input + self.weights_middle = weights_middle + self.weights_output = weights_output + self.weight_func = weight_func self.weight_mask = weight_mask self.uncond_multiplier = float(uncond_multiplier) self.has_uncond_multiplier = not math.isclose(self.uncond_multiplier, 1.0) @@ -173,66 +175,74 @@ class ControlWeights: self.extras = extras def get(self, idx: int, control: dict[str, list[Tensor]], key: str, default=1.0) -> Union[float, Tensor]: + # if weight_func present, use it + if self.weight_func is not None: + return self.weight_func(idx=idx, control=control, key=key) # if weights is not none, return index - if self.weights is not None: - # support live calculation - if callable(self.weights): - return self.weights(idx=idx, control=control, key=key) - # if middle weight, need to pretend index is actually after all the output weights (if applicable) - if key == "middle" and "output" in control: - idx += len(control["output"]) + relevant_weights = None + if key == "middle": + relevant_weights = self.weights_middle + elif key == "input": + relevant_weights = self.weights_input + else: + relevant_weights = self.weights_output + if relevant_weights is None: + return default + return relevant_weights[idx] - if key == "output": - # this implies weights list is not aligning with expectations - will need to adjust code - if idx >= len(self.weights)-1: - return default - else: - # this implies weights list is not aligning with expectations - will need to adjust code - if idx >= len(self.weights): - return default - return self.weights[idx] - return 1.0 - - def copy_with_new_weights(self, new_weights: list[float]): - return ControlWeights(weight_type=self.weight_type, base_multiplier=self.base_multiplier, flip_weights=self.flip_weights, - weights=new_weights, weight_mask=self.weight_mask, uncond_multiplier=self.uncond_multiplier, extras=self.extras) + def copy_with_new_weights(self, new_weights_input: list[float]=None, new_weights_middle: list[float]=None, new_weights_output: list[float]=None, + new_weight_func: Callable=None): + return ControlWeights(weight_type=self.weight_type, base_multiplier=self.base_multiplier, + weights_input=new_weights_input, weights_middle=new_weights_middle, weights_output=new_weights_output, + weight_func=new_weight_func, weight_mask=self.weight_mask, + uncond_multiplier=self.uncond_multiplier, extras=self.extras) @classmethod def default(cls, extras: dict[str]={}): return cls(ControlWeightType.DEFAULT, extras=extras) @classmethod - def universal(cls, base_multiplier: float, flip_weights: bool=False, uncond_multiplier: float=1.0, extras: dict[str]={}): - return cls(ControlWeightType.UNIVERSAL, base_multiplier=base_multiplier, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=extras) + def universal(cls, base_multiplier: float, uncond_multiplier: float=1.0, extras: dict[str]={}): + return cls(ControlWeightType.UNIVERSAL, base_multiplier=base_multiplier, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod def universal_mask(cls, weight_mask: Tensor, uncond_multiplier: float=1.0, extras: dict[str]={}): return cls(ControlWeightType.UNIVERSAL, weight_mask=weight_mask, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod - def t2iadapter(cls, weights: list[float]=None, flip_weights: bool=False, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights is None: - weights = [1.0]*12 - return cls(ControlWeightType.T2IADAPTER, weights=weights,flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=extras) + def t2iadapter(cls, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): + if weights_input is None: + weights_input = [1.0]*12 + return cls(ControlWeightType.T2IADAPTER, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod - def controlnet(cls, weights: list[float]=None, flip_weights: bool=False, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights is None: - weights = [1.0]*13 - return cls(ControlWeightType.CONTROLNET, weights=weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=extras) + def controlnet(cls, weights_output: list[float]=None, weights_middle: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): + if weights_output is None: + weights_output = [1.0]*12 + if weights_middle is None: + weights_middle = [1.0]*1 + return cls(ControlWeightType.CONTROLNET, weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod - def controllora(cls, weights: list[float]=None, flip_weights: bool=False, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights is None: - weights = [1.0]*10 - return cls(ControlWeightType.CONTROLLORA, weights=weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=extras) + def controllora(cls, weights_output: list[float]=None, weights_middle: list[float]=None, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): + if weights_output is None: + weights_output = [1.0]*10 + if weights_middle is None: + weights_middle = [1.0]*10 + if weights_input is None: + weights_input = [1.0]*10 + return cls(ControlWeightType.CONTROLLORA, weights_output=weights_output, weights_middle=weights_middle, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod - def controllllite(cls, weights: list[float]=None, flip_weights: bool=False, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights is None: - # TODO: make this have a real value - weights = [1.0]*200 - return cls(ControlWeightType.CONTROLLLLITE, weights=weights, flip_weights=flip_weights, uncond_multiplier=uncond_multiplier, extras=extras) + def controllllite(cls, weights_output: list[float]=None, weights_middle: list[float]=None, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): + # TODO: make the lenghts make sense + if weights_output is None: + weights_output = [1.0]*200 + if weights_middle is None: + weights_middle = [1.0]*200 + if weights_input is None: + weights_input = [1.0]*200 + return cls(ControlWeightType.CONTROLLLLITE, weights_output=weights_output, weights_middle=weights_middle, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) class StrengthInterpolation: @@ -778,11 +788,14 @@ class AdvancedControlBase: return self.weights.get(idx=idx, control=control, key=key) def get_calc_pow(self, idx: int, control: dict[str, list[Tensor]], key: str) -> int: - c_len = len(control[key])-1 - if key == "output": - if "middle" in control: - c_len += len(control["middle"]) - return c_len-idx + if key == "middle": + return 0 + else: + c_len = len(control[key]) + real_idx = c_len-idx + if key == "input": + real_idx = c_len - real_idx + 1 + return real_idx def calc_latent_keyframe_mults(self, x: Tensor, batched_number: int) -> Tensor: # apply strengths, and get batch indeces to null out @@ -916,7 +929,7 @@ class AdvancedControlBase: del out_mask # TODO: perform upscale on only the sub_idxs masks at a time instead of all to conserve RAM # resize mask and match batch count - out_mask = prepare_mask_batch(orig_mask, x_noisy.shape, multiplier=multiplier) + out_mask = prepare_mask_batch(orig_mask, x_noisy.shape, multiplier=multiplier, match_shape=True) actual_latent_length = x_noisy.shape[0] // batched_number out_mask = extend_to_batch_size(out_mask, actual_latent_length if self.sub_idxs is None else self.full_latent_length) if self.sub_idxs is not None: From d3ceadbabae2808ef729b5e1f16d19e3c7b61a07 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Thu, 29 Aug 2024 09:57:23 -0500 Subject: [PATCH 03/11] Attempted to add masking support for flux controlnet (not working yet, but logic is partway there --- adv_control/control.py | 21 ++++++++++++++++++--- adv_control/utils.py | 18 ++++++++++++------ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/adv_control/control.py b/adv_control/control.py index 4225a47..4e4c5d7 100644 --- a/adv_control/control.py +++ b/adv_control/control.py @@ -24,6 +24,8 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): def __init__(self, control_model, timestep_keyframes: TimestepKeyframeGroup, global_average_pooling=False, compression_ratio=8, latent_format=None, device=None, load_device=None, manual_cast_dtype=None, extra_conds=["y"], strength_type=StrengthType.CONSTANT): super().__init__(control_model=control_model, global_average_pooling=global_average_pooling, compression_ratio=compression_ratio, latent_format=latent_format, device=device, load_device=load_device, manual_cast_dtype=manual_cast_dtype) AdvancedControlBase.__init__(self, super(), timestep_keyframes=timestep_keyframes, weights_default=ControlWeights.controlnet()) + self.is_flux = False + self.x_noisy_shape = None def get_universal_weights(self) -> ControlWeights: def cn_weights_func(idx: int, control: dict[str, list[Tensor]], key: str): @@ -97,10 +99,19 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): timestep = self.model_sampling_current.timestep(t) x_noisy = self.model_sampling_current.calculate_input(t, x_noisy) - + self.x_noisy_shape = x_noisy.shape control = self.control_model(x=x_noisy.to(dtype), hint=self.cond_hint, timesteps=timestep.to(dtype), context=context.to(dtype), **extra) return self.control_merge(control, control_prev, output_dtype) + def pre_run_advanced(self, *args, **kwargs): + self.is_flux = "Flux" in str(type(self.control_model).__name__) + return super().pre_run_advanced(*args, **kwargs) + + def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int, is_flux=False): + if self.is_flux: + flux_shape = self.x_noisy_shape + return super().apply_advanced_strengths_and_masks(x, batched_number, flux_shape) + def copy(self): c = ControlNetAdvanced(self.control_model, self.timestep_keyframes, global_average_pooling=self.global_average_pooling, load_device=self.load_device, manual_cast_dtype=self.manual_cast_dtype) c.control_model = self.control_model @@ -109,6 +120,10 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): self.copy_to_advanced(c) return c + def cleanup_advanced(self): + self.x_noisy_shape = None + return super().cleanup_advanced() + @staticmethod def from_vanilla(v: ControlNet, timestep_keyframe: TimestepKeyframeGroup=None) -> 'ControlNetAdvanced': to_return = ControlNetAdvanced(control_model=v.control_model, timestep_keyframes=timestep_keyframe, @@ -405,11 +420,11 @@ class SparseCtrlAdvanced(ControlNetAdvanced): control = self.control_model(x=x_noisy.to(dtype), hint=self.cond_hint, timesteps=timestep.float(), context=context.to(dtype), y=y) return self.control_merge(control, control_prev, output_dtype) - def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int): + def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int, *args, **kwargs): # apply mults to indexes with and without a direct condhint x[self.local_sparse_idxs] *= self.sparse_settings.sparse_hint_mult * self.weights.extras.get(SparseConst.HINT_MULT, 1.0) x[self.local_sparse_idxs_inverse] *= self.sparse_settings.sparse_nonhint_mult * self.weights.extras.get(SparseConst.NONHINT_MULT, 1.0) - return super().apply_advanced_strengths_and_masks(x, batched_number) + return super().apply_advanced_strengths_and_masks(x, batched_number, *args, **kwargs) def pre_run_advanced(self, model, percent_to_timestep_function): super().pre_run_advanced(model, percent_to_timestep_function) diff --git a/adv_control/utils.py b/adv_control/utils.py index e2d5a48..300df73 100644 --- a/adv_control/utils.py +++ b/adv_control/utils.py @@ -3,6 +3,7 @@ from typing import Callable, Union import torch from torch import Tensor import torch.nn.functional +from einops import rearrange import numpy as np import math @@ -447,14 +448,19 @@ class manual_cast_clean_groupnorm(comfy.ops.manual_cast): # adapted from comfy/sample.py -def prepare_mask_batch(mask: Tensor, shape: Tensor, multiplier: int=1, match_dim1=False, match_shape=False): +def prepare_mask_batch(mask: Tensor, shape: Tensor, multiplier: int=1, match_dim1=False, match_shape=False, flux_shape=None): mask = mask.clone() - mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(shape[-2]*multiplier, shape[-1]*multiplier), mode="bilinear") + if flux_shape is not None: + multiplier = multiplier * 0.5 + mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(round(flux_shape[-2]*multiplier), round(flux_shape[-1]*multiplier)), mode="bilinear") + mask = rearrange(mask, "b c h w -> b (h w) c") + else: + mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(round(shape[-2]*multiplier), round(shape[-1]*multiplier)), mode="bilinear") if match_dim1: if match_shape and len(shape) < 4: raise Exception(f"match_dim1 cannot be True if shape is under 4 dims; was {len(shape)}.") mask = torch.cat([mask] * shape[1], dim=1) - if match_shape and len(shape) == 3: + if match_shape and len(shape) == 3 and len(mask.shape) != 3: mask = mask.squeeze(1) return mask @@ -845,7 +851,7 @@ class AdvancedControlBase: final_tensor = final_tensor.unsqueeze(-1) return final_tensor - def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int): + def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int, flux_shape: tuple=None): # handle weight's uncond_multiplier, if applicable if self.weights.has_uncond_multiplier: cond_or_uncond = self.batched_number.cond_or_uncond @@ -861,10 +867,10 @@ class AdvancedControlBase: x[:] = x[:] * self.calc_latent_keyframe_mults(x=x, batched_number=batched_number) # apply masks, resizing mask to required dims if self.mask_cond_hint is not None: - masks = prepare_mask_batch(self.mask_cond_hint, x.shape, match_shape=True) + masks = prepare_mask_batch(self.mask_cond_hint, x.shape, match_shape=True, flux_shape=flux_shape) x[:] = x[:] * masks if self.tk_mask_cond_hint is not None: - masks = prepare_mask_batch(self.tk_mask_cond_hint, x.shape, match_shape=True) + masks = prepare_mask_batch(self.tk_mask_cond_hint, x.shape, match_shape=True, flux_shape=flux_shape) x[:] = x[:] * masks # apply timestep keyframe strengths if self._current_timestep_keyframe.strength != 1.0: From a9e9ec7b929aa769761565a1021c0312580f95d1 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 03:28:01 -0500 Subject: [PATCH 04/11] Fix inconsistent variable name causing reference before assignment error --- adv_control/control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adv_control/control.py b/adv_control/control.py index 4e4c5d7..5922e45 100644 --- a/adv_control/control.py +++ b/adv_control/control.py @@ -107,7 +107,7 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): self.is_flux = "Flux" in str(type(self.control_model).__name__) return super().pre_run_advanced(*args, **kwargs) - def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int, is_flux=False): + def apply_advanced_strengths_and_masks(self, x: Tensor, batched_number: int, flux_shape=None): if self.is_flux: flux_shape = self.x_noisy_shape return super().apply_advanced_strengths_and_masks(x, batched_number, flux_shape) From ce72ce674f7ea8cebaff239db89a33a97bfcb1a7 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 05:04:17 -0500 Subject: [PATCH 05/11] Add single cond version of Apply Advanced ControlNet node --- adv_control/nodes.py | 146 ++++++++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 51 deletions(-) diff --git a/adv_control/nodes.py b/adv_control/nodes.py index 470149f..d335d42 100644 --- a/adv_control/nodes.py +++ b/adv_control/nodes.py @@ -104,7 +104,7 @@ class AdvancedControlNetApply: "weights_override": ("CONTROL_NET_WEIGHTS", ), "model_optional": ("MODEL",), "vae_optional": ("VAE",), - "autosize": ("ACNAUTOSIZE", {"padding": 40}), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), } } @@ -117,7 +117,7 @@ class AdvancedControlNetApply: def apply_controlnet(self, positive, negative, control_net, image, strength, start_percent, end_percent, mask_optional: Tensor=None, model_optional: ModelPatcher=None, vae_optional=None, timestep_kf: TimestepKeyframeGroup=None, latent_kf_override: LatentKeyframeGroup=None, - weights_override: ControlWeights=None): + weights_override: ControlWeights=None, control_apply_to_uncond=False): if strength == 0: return (positive, negative, model_optional) if model_optional: @@ -129,59 +129,101 @@ class AdvancedControlNetApply: out = [] for conditioning in [positive, negative]: c = [] - for t in conditioning: - d = t[1].copy() + if conditioning is not None: + for t in conditioning: + d = t[1].copy() - prev_cnet = d.get('control', None) - if prev_cnet in cnets: - c_net = cnets[prev_cnet] - else: - # copy, convert to advanced if needed, and set cond - c_net = convert_to_advanced(control_net.copy()).set_cond_hint(control_hint, strength, (start_percent, end_percent), vae_optional) - if is_advanced_controlnet(c_net): - # disarm node check - c_net.disarm() - # if model required, verify model is passed in, and if so patch it - if c_net.require_model: - if not model_optional: - raise Exception(f"Type '{type(c_net).__name__}' requires model_optional input, but got None.") - c_net.patch_model(model=model_optional) - # if vae required, verify vae is passed in - if c_net.require_vae: - # if controlnet can accept preprocced condhint latents and is the case, ignore vae requirement - if c_net.allow_condhint_latents and isinstance(control_hint, AbstractPreprocWrapper): - pass - elif not vae_optional: - # make sure SD3 ControlNet will get a special message instead of generic type mention - if is_sd3_advanced_controlnet: - raise Exception(f"SD3 ControlNet requires vae_optional input, but got None.") - else: - raise Exception(f"Type '{type(c_net).__name__}' requires vae_optional input, but got None.") - # apply optional parameters and overrides, if provided - if timestep_kf is not None: - c_net.set_timestep_keyframes(timestep_kf) - if latent_kf_override is not None: - c_net.latent_keyframe_override = latent_kf_override - if weights_override is not None: - c_net.weights_override = weights_override - # verify weights are compatible - c_net.verify_all_weights() - # set cond hint mask - if mask_optional is not None: - mask_optional = mask_optional.clone() - # if not in the form of a batch, make it so - if len(mask_optional.shape) < 3: - mask_optional = mask_optional.unsqueeze(0) - c_net.set_cond_hint_mask(mask_optional) - c_net.set_previous_controlnet(prev_cnet) - cnets[prev_cnet] = c_net + prev_cnet = d.get('control', None) + if prev_cnet in cnets: + c_net = cnets[prev_cnet] + else: + # copy, convert to advanced if needed, and set cond + c_net = convert_to_advanced(control_net.copy()).set_cond_hint(control_hint, strength, (start_percent, end_percent), vae_optional) + if is_advanced_controlnet(c_net): + # disarm node check + c_net.disarm() + # if model required, verify model is passed in, and if so patch it + if c_net.require_model: + if not model_optional: + raise Exception(f"Type '{type(c_net).__name__}' requires model_optional input, but got None.") + c_net.patch_model(model=model_optional) + # if vae required, verify vae is passed in + if c_net.require_vae: + # if controlnet can accept preprocced condhint latents and is the case, ignore vae requirement + if c_net.allow_condhint_latents and isinstance(control_hint, AbstractPreprocWrapper): + pass + elif not vae_optional: + # make sure SD3 ControlNet will get a special message instead of generic type mention + if is_sd3_advanced_controlnet: + raise Exception(f"SD3 ControlNet requires vae_optional input, but got None.") + else: + raise Exception(f"Type '{type(c_net).__name__}' requires vae_optional input, but got None.") + # apply optional parameters and overrides, if provided + if timestep_kf is not None: + c_net.set_timestep_keyframes(timestep_kf) + if latent_kf_override is not None: + c_net.latent_keyframe_override = latent_kf_override + if weights_override is not None: + c_net.weights_override = weights_override + # verify weights are compatible + c_net.verify_all_weights() + # set cond hint mask + if mask_optional is not None: + mask_optional = mask_optional.clone() + # if not in the form of a batch, make it so + if len(mask_optional.shape) < 3: + mask_optional = mask_optional.unsqueeze(0) + c_net.set_cond_hint_mask(mask_optional) + c_net.set_previous_controlnet(prev_cnet) + cnets[prev_cnet] = c_net - d['control'] = c_net - d['control_apply_to_uncond'] = False - n = [t[0], d] - c.append(n) + d['control'] = c_net + d['control_apply_to_uncond'] = control_apply_to_uncond + n = [t[0], d] + c.append(n) out.append(c) return (out[0], out[1], model_optional) + + +class AdvancedControlNetApplySingle: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "conditioning": ("CONDITIONING", ), + "control_net": ("CONTROL_NET", ), + "image": ("IMAGE", ), + "strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}), + "start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}), + "end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}) + }, + "optional": { + "mask_optional": ("MASK", ), + "timestep_kf": ("TIMESTEP_KEYFRAME", ), + "latent_kf_override": ("LATENT_KEYFRAME", ), + "weights_override": ("CONTROL_NET_WEIGHTS", ), + "model_optional": ("MODEL",), + "vae_optional": ("VAE",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + RETURN_TYPES = ("CONDITIONING","MODEL",) + RETURN_NAMES = ("CONDITIONING", "model_opt") + FUNCTION = "apply_controlnet" + + CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝" + + def apply_controlnet(self, conditioning, control_net, image, strength, start_percent, end_percent, + mask_optional: Tensor=None, model_optional: ModelPatcher=None, vae_optional=None, + timestep_kf: TimestepKeyframeGroup=None, latent_kf_override: LatentKeyframeGroup=None, + weights_override: ControlWeights=None): + values = AdvancedControlNetApply.apply_controlnet(self, positive=conditioning, negative=None, control_net=control_net, image=image, + strength=strength, start_percent=start_percent, end_percent=end_percent, + mask_optional=mask_optional, model_optional=model_optional, vae_optional=vae_optional, + timestep_kf=timestep_kf, latent_kf_override=latent_kf_override, weights_override=weights_override, + control_apply_to_uncond=True) + return (values[0], values[2]) # NODE MAPPING @@ -196,6 +238,7 @@ NODE_CLASS_MAPPINGS = { "LatentKeyframeGroup": LatentKeyframeGroupNode, # Conditioning "ACN_AdvancedControlNetApply": AdvancedControlNetApply, + "ACN_AdvancedControlNetApplySingle": AdvancedControlNetApplySingle, # Loaders "ControlNetLoaderAdvanced": ControlNetLoaderAdvanced, "DiffControlNetLoaderAdvanced": DiffControlNetLoaderAdvanced, @@ -239,6 +282,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { "LatentKeyframeGroup": "Latent Keyframe Group 🛂🅐🅒🅝", # Conditioning "ACN_AdvancedControlNetApply": "Apply Advanced ControlNet 🛂🅐🅒🅝", + "ACN_AdvancedControlNetApplySingle": "Apply Advanced ControlNet(1) 🛂🅐🅒🅝", # Loaders "ControlNetLoaderAdvanced": "Load Advanced ControlNet Model 🛂🅐🅒🅝", "DiffControlNetLoaderAdvanced": "Load Advanced ControlNet Model (diff) 🛂🅐🅒🅝", From 9c00ec00ea6d090a8502260f7a7a0a53fe4b124e Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 05:59:05 -0500 Subject: [PATCH 06/11] Clarified Soft/Custom ControlNet SD1.5/T2I Adapter Weights nodes, deprecated old versions --- adv_control/nodes.py | 31 ++++--- adv_control/nodes_deprecated.py | 157 +++++++++++++++++++++++++++++++- adv_control/nodes_weight.py | 110 +++++++++++----------- adv_control/utils.py | 2 +- 4 files changed, 229 insertions(+), 71 deletions(-) diff --git a/adv_control/nodes.py b/adv_control/nodes.py index d335d42..30a58f0 100644 --- a/adv_control/nodes.py +++ b/adv_control/nodes.py @@ -7,15 +7,16 @@ from comfy.model_patcher import ModelPatcher from .control import load_controlnet, convert_to_advanced, is_advanced_controlnet, is_sd3_advanced_controlnet from .utils import ControlWeights, LatentKeyframeGroup, TimestepKeyframeGroup, AbstractPreprocWrapper, BIGMAX -from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeightsDeprecated, SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated, - SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated) +from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeightsDeprecated, + SoftControlNetWeightsSD15, CustomControlNetWeightsSD15, SoftT2IAdapterWeights, CustomT2IAdapterWeights) from .nodes_keyframes import (LatentKeyframeGroupNode, LatentKeyframeInterpolationNode, LatentKeyframeBatchedGroupNode, LatentKeyframeNode, TimestepKeyframeNode, TimestepKeyframeInterpolationNode, TimestepKeyframeFromStrengthListNode) from .nodes_sparsectrl import SparseCtrlMergedLoaderAdvanced, SparseCtrlLoaderAdvanced, SparseIndexMethodNode, SparseSpreadMethodNode, RgbSparseCtrlPreprocessor, SparseWeightExtras from .nodes_reference import ReferenceControlNetNode, ReferenceControlFinetune, ReferencePreprocessorNode from .nodes_plusplus import PlusPlusLoaderAdvanced, PlusPlusLoaderSingle, PlusPlusInputNode from .nodes_loosecontrol import ControlNetLoaderWithLoraAdvanced -from .nodes_deprecated import LoadImagesFromDirectory +from .nodes_deprecated import (LoadImagesFromDirectory, SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated, + SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated) from .logger import logger from .sampling import acn_sample_factory @@ -245,10 +246,10 @@ NODE_CLASS_MAPPINGS = { # Weights "ScaledSoftControlNetWeights": ScaledSoftUniversalWeightsDeprecated, "ScaledSoftMaskedUniversalWeights": ScaledSoftMaskedUniversalWeights, - "SoftControlNetWeights": SoftControlNetWeightsDeprecated, - "CustomControlNetWeights": CustomControlNetWeightsDeprecated, - "SoftT2IAdapterWeights": SoftT2IAdapterWeightsDeprecated, - "CustomT2IAdapterWeights": CustomT2IAdapterWeightsDeprecated, + "ACN_SoftControlNetWeightsSD15": SoftControlNetWeightsSD15, + "ACN_CustomControlNetWeightsSD15": CustomControlNetWeightsSD15, + "ACN_SoftT2IAdapterWeights": SoftT2IAdapterWeights, + "ACN_CustomT2IAdapterWeights": CustomT2IAdapterWeights, "ACN_DefaultUniversalWeights": DefaultWeights, # SparseCtrl "ACN_SparseCtrlRGBPreprocessor": RgbSparseCtrlPreprocessor, @@ -269,6 +270,10 @@ NODE_CLASS_MAPPINGS = { #"ACN_ControlNetLoaderWithLoraAdvanced": ControlNetLoaderWithLoraAdvanced, # Deprecated "LoadImagesFromDirectory": LoadImagesFromDirectory, + "SoftControlNetWeights": SoftControlNetWeightsDeprecated, + "CustomControlNetWeights": CustomControlNetWeightsDeprecated, + "SoftT2IAdapterWeights": SoftT2IAdapterWeightsDeprecated, + "CustomT2IAdapterWeights": CustomT2IAdapterWeightsDeprecated, } NODE_DISPLAY_NAME_MAPPINGS = { @@ -289,10 +294,10 @@ NODE_DISPLAY_NAME_MAPPINGS = { # Weights "ScaledSoftControlNetWeights": "Scaled Soft Weights 🛂🅐🅒🅝", "ScaledSoftMaskedUniversalWeights": "Scaled Soft Masked Weights 🛂🅐🅒🅝", - "SoftControlNetWeights": "ControlNet Soft Weights 🛂🅐🅒🅝", - "CustomControlNetWeights": "ControlNet Custom Weights 🛂🅐🅒🅝", - "SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝", - "CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝", + "ACN_SoftControlNetWeightsSD15": "ControlNet Soft Weights [SD1.5] 🛂🅐🅒🅝", + "ACN_CustomControlNetWeightsSD15": "ControlNet Custom Weights [SD1.5] 🛂🅐🅒🅝", + "ACN_SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝", + "ACN_CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝", "ACN_DefaultUniversalWeights": "Default Weights 🛂🅐🅒🅝", # SparseCtrl "ACN_SparseCtrlRGBPreprocessor": "RGB SparseCtrl 🛂🅐🅒🅝", @@ -313,4 +318,8 @@ NODE_DISPLAY_NAME_MAPPINGS = { #"ACN_ControlNetLoaderWithLoraAdvanced": "Load Adv. ControlNet Model w/ LoRA 🛂🅐🅒🅝", # Deprecated "LoadImagesFromDirectory": "🚫Load Images [DEPRECATED] 🛂🅐🅒🅝", + "SoftControlNetWeights": "ControlNet Soft Weights 🛂🅐🅒🅝", + "CustomControlNetWeights": "ControlNet Custom Weights 🛂🅐🅒🅝", + "SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝", + "CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝", } diff --git a/adv_control/nodes_deprecated.py b/adv_control/nodes_deprecated.py index bd98607..64b7675 100644 --- a/adv_control/nodes_deprecated.py +++ b/adv_control/nodes_deprecated.py @@ -4,7 +4,7 @@ import torch import numpy as np from PIL import Image, ImageOps -from .utils import BIGMAX +from .utils import BIGMAX, ControlWeights, TimestepKeyframeGroup, TimestepKeyframe, get_properly_arranged_t2i_weights from .logger import logger @@ -69,3 +69,158 @@ class LoadImagesFromDirectory: raise FileNotFoundError(f"No images could be loaded from directory '{directory}'.") return (torch.cat(images, dim=0), torch.stack(masks, dim=0), image_count) + + +class SoftControlNetWeightsDeprecated: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "weight_00": ("FLOAT", {"default": 0.09941396206337118, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_01": ("FLOAT", {"default": 0.12050177219802567, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_02": ("FLOAT", {"default": 0.14606275417942507, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_03": ("FLOAT", {"default": 0.17704576264172736, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_04": ("FLOAT", {"default": 0.214600924414215, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_05": ("FLOAT", {"default": 0.26012233262329093, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_06": ("FLOAT", {"default": 0.3152997971191405, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_07": ("FLOAT", {"default": 0.3821815722656249, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_08": ("FLOAT", {"default": 0.4632503906249999, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_09": ("FLOAT", {"default": 0.561515625, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_10": ("FLOAT", {"default": 0.6806249999999999, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_11": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_12": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "flip_weights": ("BOOLEAN", {"default": False}), + }, + "optional": { + "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), + "cn_extras": ("CN_WEIGHTS_EXTRAS",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + DEPRECATED = True + RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",) + RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") + FUNCTION = "load_weights" + + CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" + + def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, + weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, + uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + weights_output = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, + weight_07, weight_08, weight_09, weight_10, weight_11] + weights_middle = [weight_12] + weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + + +class CustomControlNetWeightsDeprecated: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "weight_00": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_01": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_02": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_03": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_04": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_05": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_06": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_07": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_08": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_09": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_10": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_11": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_12": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "flip_weights": ("BOOLEAN", {"default": False}), + }, + "optional": { + "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), + "cn_extras": ("CN_WEIGHTS_EXTRAS",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + DEPRECATED = True + RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",) + RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") + FUNCTION = "load_weights" + + CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" + + def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, + weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, + uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + weights_output = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, + weight_07, weight_08, weight_09, weight_10, weight_11] + weights_middle = [weight_12] + weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + + + +class SoftT2IAdapterWeightsDeprecated: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "weight_00": ("FLOAT", {"default": 0.25, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_01": ("FLOAT", {"default": 0.62, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_02": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_03": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "flip_weights": ("BOOLEAN", {"default": False}), + }, + "optional": { + "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), + "cn_extras": ("CN_WEIGHTS_EXTRAS",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + DEPRECATED = True + RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",) + RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") + FUNCTION = "load_weights" + + CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter" + + def load_weights(self, weight_00, weight_01, weight_02, weight_03, flip_weights, + uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + weights = [weight_00, weight_01, weight_02, weight_03] + weights = get_properly_arranged_t2i_weights(weights) + weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + + +class CustomT2IAdapterWeightsDeprecated: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "weight_00": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_01": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_02": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "weight_03": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "flip_weights": ("BOOLEAN", {"default": False}), + }, + "optional": { + "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), + "cn_extras": ("CN_WEIGHTS_EXTRAS",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + DEPRECATED = True + RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",) + RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") + FUNCTION = "load_weights" + + CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter" + + def load_weights(self, weight_00, weight_01, weight_02, weight_03, flip_weights, + uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + weights = [weight_00, weight_01, weight_02, weight_03] + weights = get_properly_arranged_t2i_weights(weights) + weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) diff --git a/adv_control/nodes_weight.py b/adv_control/nodes_weight.py index 85f2af7..1f74cdc 100644 --- a/adv_control/nodes_weight.py +++ b/adv_control/nodes_weight.py @@ -92,25 +92,24 @@ class ScaledSoftUniversalWeightsDeprecated: return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class SoftControlNetWeightsDeprecated: +class SoftControlNetWeightsSD15: @classmethod def INPUT_TYPES(s): return { "required": { - "weight_00": ("FLOAT", {"default": 0.09941396206337118, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_01": ("FLOAT", {"default": 0.12050177219802567, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_02": ("FLOAT", {"default": 0.14606275417942507, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_03": ("FLOAT", {"default": 0.17704576264172736, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_04": ("FLOAT", {"default": 0.214600924414215, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_05": ("FLOAT", {"default": 0.26012233262329093, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_06": ("FLOAT", {"default": 0.3152997971191405, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_07": ("FLOAT", {"default": 0.3821815722656249, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_08": ("FLOAT", {"default": 0.4632503906249999, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_09": ("FLOAT", {"default": 0.561515625, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_10": ("FLOAT", {"default": 0.6806249999999999, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_11": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_12": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "flip_weights": ("BOOLEAN", {"default": False}), + "output_0": ("FLOAT", {"default": 0.09941396206337118, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_1": ("FLOAT", {"default": 0.12050177219802567, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_2": ("FLOAT", {"default": 0.14606275417942507, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_3": ("FLOAT", {"default": 0.17704576264172736, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_4": ("FLOAT", {"default": 0.214600924414215, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_5": ("FLOAT", {"default": 0.26012233262329093, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_6": ("FLOAT", {"default": 0.3152997971191405, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_7": ("FLOAT", {"default": 0.3821815722656249, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_8": ("FLOAT", {"default": 0.4632503906249999, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_9": ("FLOAT", {"default": 0.561515625, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_10": ("FLOAT", {"default": 0.6806249999999999, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_11": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "middle_0": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), }, "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), @@ -125,35 +124,34 @@ class SoftControlNetWeightsDeprecated: CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" - def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, - weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, + def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6, + output_7, output_8, output_9, output_10, output_11, middle_0, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights_output = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, - weight_07, weight_08, weight_09, weight_10, weight_11] - weights_middle = [weight_12] + weights_output = [output_0, output_1, output_2, output_3, output_4, output_5, output_6, + output_7, output_8, output_9, output_10, output_11] + weights_middle = [middle_0] weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class CustomControlNetWeightsDeprecated: +class CustomControlNetWeightsSD15: @classmethod def INPUT_TYPES(s): return { "required": { - "weight_00": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_01": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_02": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_03": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_04": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_05": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_06": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_07": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_08": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_09": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_10": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_11": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_12": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "flip_weights": ("BOOLEAN", {"default": False}), + "output_0": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_1": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_2": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_3": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_4": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_5": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_6": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_7": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_8": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_9": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_10": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "output_11": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "middle_0": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), }, "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), @@ -168,26 +166,25 @@ class CustomControlNetWeightsDeprecated: CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" - def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, - weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, + def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6, + output_7, output_8, output_9, output_10, output_11, middle_0, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights_output = [weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, - weight_07, weight_08, weight_09, weight_10, weight_11] - weights_middle = [weight_12] + weights_output = [output_0, output_1, output_2, output_3, output_4, output_5, output_6, + output_7, output_8, output_9, output_10, output_11] + weights_middle = [middle_0] weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class SoftT2IAdapterWeightsDeprecated: +class SoftT2IAdapterWeights: @classmethod def INPUT_TYPES(s): return { "required": { - "weight_00": ("FLOAT", {"default": 0.25, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_01": ("FLOAT", {"default": 0.62, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_02": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_03": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "flip_weights": ("BOOLEAN", {"default": False}), + "input_0": ("FLOAT", {"default": 0.25, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_1": ("FLOAT", {"default": 0.62, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_2": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_3": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), }, "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), @@ -202,25 +199,23 @@ class SoftT2IAdapterWeightsDeprecated: CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter" - def load_weights(self, weight_00, weight_01, weight_02, weight_03, flip_weights, + def load_weights(self, input_0, input_1, input_2, input_3, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights = [weight_00, weight_01, weight_02, weight_03] + weights = [input_0, input_1, input_2, input_3] weights = get_properly_arranged_t2i_weights(weights) - weights.reverse() # to account for recent ComfyUI changes weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class CustomT2IAdapterWeightsDeprecated: +class CustomT2IAdapterWeights: @classmethod def INPUT_TYPES(s): return { "required": { - "weight_00": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_01": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_02": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "weight_03": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), - "flip_weights": ("BOOLEAN", {"default": False}), + "input_0": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_1": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_2": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_3": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), }, "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), @@ -235,10 +230,9 @@ class CustomT2IAdapterWeightsDeprecated: CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter" - def load_weights(self, weight_00, weight_01, weight_02, weight_03, flip_weights, + def load_weights(self, input_0, input_1, input_2, input_3, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights = [weight_00, weight_01, weight_02, weight_03] + weights = [input_0, input_1, input_2, input_3] weights = get_properly_arranged_t2i_weights(weights) - weights.reverse() # to account for recent ComfyUI changes weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) diff --git a/adv_control/utils.py b/adv_control/utils.py index 300df73..6d252ce 100644 --- a/adv_control/utils.py +++ b/adv_control/utils.py @@ -184,7 +184,7 @@ class ControlWeights: if key == "middle": relevant_weights = self.weights_middle elif key == "input": - relevant_weights = self.weights_input + relevant_weights = list(reversed(self.weights_input)) else: relevant_weights = self.weights_output if relevant_weights is None: From 4b3a65fa32933bce5767946ab7fd2d7a1e874a2f Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 06:05:00 -0500 Subject: [PATCH 07/11] Refactored Soft ControlNet SD1.5/T2I Weights node code to reuse code from Custom version --- adv_control/nodes_weight.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/adv_control/nodes_weight.py b/adv_control/nodes_weight.py index 1f74cdc..72a9491 100644 --- a/adv_control/nodes_weight.py +++ b/adv_control/nodes_weight.py @@ -127,11 +127,12 @@ class SoftControlNetWeightsSD15: def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6, output_7, output_8, output_9, output_10, output_11, middle_0, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights_output = [output_0, output_1, output_2, output_3, output_4, output_5, output_6, - output_7, output_8, output_9, output_10, output_11] - weights_middle = [middle_0] - weights = ControlWeights.controlnet(weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=cn_extras) - return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + return CustomControlNetWeightsSD15.load_weights(self, + output_0=output_0, output_1=output_1, output_2=output_2, output_3=output_3, + output_4=output_4, output_5=output_5, output_6=output_6, output_7=output_7, + output_8=output_8, output_9=output_9, output_10=output_10, output_11=output_11, + middle_0=middle_0, + uncond_multiplier=uncond_multiplier, cn_extras=cn_extras) class CustomControlNetWeightsSD15: @@ -201,10 +202,8 @@ class SoftT2IAdapterWeights: def load_weights(self, input_0, input_1, input_2, input_3, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): - weights = [input_0, input_1, input_2, input_3] - weights = get_properly_arranged_t2i_weights(weights) - weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras) - return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + return CustomT2IAdapterWeights.load_weights(self, input_0=input_0, input_1=input_1, input_2=input_2, input_3=input_3, + uncond_multiplier=uncond_multiplier, cn_extras=cn_extras) class CustomT2IAdapterWeights: From 299c6d95066262bf43030cd5e70e7c17b14f1d00 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 06:37:30 -0500 Subject: [PATCH 08/11] Fixed flux cns not working if no soft weights attached, added ControlNet Custom Weights [Flux] node --- adv_control/nodes.py | 5 +++- adv_control/nodes_deprecated.py | 8 +++--- adv_control/nodes_weight.py | 49 +++++++++++++++++++++++++++++++++ adv_control/utils.py | 29 +++++-------------- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/adv_control/nodes.py b/adv_control/nodes.py index 30a58f0..bf258a8 100644 --- a/adv_control/nodes.py +++ b/adv_control/nodes.py @@ -8,7 +8,8 @@ from comfy.model_patcher import ModelPatcher from .control import load_controlnet, convert_to_advanced, is_advanced_controlnet, is_sd3_advanced_controlnet from .utils import ControlWeights, LatentKeyframeGroup, TimestepKeyframeGroup, AbstractPreprocWrapper, BIGMAX from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeightsDeprecated, - SoftControlNetWeightsSD15, CustomControlNetWeightsSD15, SoftT2IAdapterWeights, CustomT2IAdapterWeights) + SoftControlNetWeightsSD15, CustomControlNetWeightsSD15, CustomControlNetWeightsFlux, + SoftT2IAdapterWeights, CustomT2IAdapterWeights) from .nodes_keyframes import (LatentKeyframeGroupNode, LatentKeyframeInterpolationNode, LatentKeyframeBatchedGroupNode, LatentKeyframeNode, TimestepKeyframeNode, TimestepKeyframeInterpolationNode, TimestepKeyframeFromStrengthListNode) from .nodes_sparsectrl import SparseCtrlMergedLoaderAdvanced, SparseCtrlLoaderAdvanced, SparseIndexMethodNode, SparseSpreadMethodNode, RgbSparseCtrlPreprocessor, SparseWeightExtras @@ -248,6 +249,7 @@ NODE_CLASS_MAPPINGS = { "ScaledSoftMaskedUniversalWeights": ScaledSoftMaskedUniversalWeights, "ACN_SoftControlNetWeightsSD15": SoftControlNetWeightsSD15, "ACN_CustomControlNetWeightsSD15": CustomControlNetWeightsSD15, + "ACN_CustomControlNetWeightsFlux": CustomControlNetWeightsFlux, "ACN_SoftT2IAdapterWeights": SoftT2IAdapterWeights, "ACN_CustomT2IAdapterWeights": CustomT2IAdapterWeights, "ACN_DefaultUniversalWeights": DefaultWeights, @@ -296,6 +298,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { "ScaledSoftMaskedUniversalWeights": "Scaled Soft Masked Weights 🛂🅐🅒🅝", "ACN_SoftControlNetWeightsSD15": "ControlNet Soft Weights [SD1.5] 🛂🅐🅒🅝", "ACN_CustomControlNetWeightsSD15": "ControlNet Custom Weights [SD1.5] 🛂🅐🅒🅝", + "ACN_CustomControlNetWeightsFlux": "ControlNet Custom Weights [Flux] 🛂🅐🅒🅝", "ACN_SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝", "ACN_CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝", "ACN_DefaultUniversalWeights": "Default Weights 🛂🅐🅒🅝", diff --git a/adv_control/nodes_deprecated.py b/adv_control/nodes_deprecated.py index 64b7675..334a646 100644 --- a/adv_control/nodes_deprecated.py +++ b/adv_control/nodes_deprecated.py @@ -103,7 +103,7 @@ class SoftControlNetWeightsDeprecated: RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") FUNCTION = "load_weights" - CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" + CATEGORY = "" def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, @@ -147,7 +147,7 @@ class CustomControlNetWeightsDeprecated: RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") FUNCTION = "load_weights" - CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" + CATEGORY = "" def load_weights(self, weight_00, weight_01, weight_02, weight_03, weight_04, weight_05, weight_06, weight_07, weight_08, weight_09, weight_10, weight_11, weight_12, flip_weights, @@ -183,7 +183,7 @@ class SoftT2IAdapterWeightsDeprecated: RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") FUNCTION = "load_weights" - CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter" + CATEGORY = "" def load_weights(self, weight_00, weight_01, weight_02, weight_03, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): @@ -216,7 +216,7 @@ class CustomT2IAdapterWeightsDeprecated: RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") FUNCTION = "load_weights" - CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter" + CATEGORY = "" def load_weights(self, weight_00, weight_01, weight_02, weight_03, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): diff --git a/adv_control/nodes_weight.py b/adv_control/nodes_weight.py index 72a9491..83e10bd 100644 --- a/adv_control/nodes_weight.py +++ b/adv_control/nodes_weight.py @@ -177,6 +177,55 @@ class CustomControlNetWeightsSD15: return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) +class CustomControlNetWeightsFlux: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "input_0": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_1": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_2": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_3": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_4": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_5": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_6": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_7": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_8": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_9": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_10": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_11": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_12": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_13": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_14": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_15": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_16": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_17": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + "input_18": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ), + }, + "optional": { + "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), + "cn_extras": ("CN_WEIGHTS_EXTRAS",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",) + RETURN_NAMES = WEIGHTS_RETURN_NAMES + FUNCTION = "load_weights" + + CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet" + + def load_weights(self, input_0, input_1, input_2, input_3, input_4, input_5, input_6, + input_7, input_8, input_9, input_10, input_11, input_12, input_13, + input_14, input_15, input_16, input_17, input_18, + uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + weights_input = [input_0, input_1, input_2, input_3, input_4, input_5, + input_6, input_7, input_8, input_9, input_10, input_11, + input_12, input_13, input_14, input_15, input_16, input_17, input_18] + weights = ControlWeights.controlnet(weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + + class SoftT2IAdapterWeights: @classmethod def INPUT_TYPES(s): diff --git a/adv_control/utils.py b/adv_control/utils.py index 6d252ce..39453a5 100644 --- a/adv_control/utils.py +++ b/adv_control/utils.py @@ -184,11 +184,15 @@ class ControlWeights: if key == "middle": relevant_weights = self.weights_middle elif key == "input": - relevant_weights = list(reversed(self.weights_input)) + relevant_weights = self.weights_input + if relevant_weights is not None: + relevant_weights = list(reversed(relevant_weights)) else: relevant_weights = self.weights_output if relevant_weights is None: return default + elif idx >= len(relevant_weights): + return default return relevant_weights[idx] def copy_with_new_weights(self, new_weights_input: list[float]=None, new_weights_middle: list[float]=None, new_weights_output: list[float]=None, @@ -212,37 +216,18 @@ class ControlWeights: @classmethod def t2iadapter(cls, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights_input is None: - weights_input = [1.0]*12 return cls(ControlWeightType.T2IADAPTER, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod - def controlnet(cls, weights_output: list[float]=None, weights_middle: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights_output is None: - weights_output = [1.0]*12 - if weights_middle is None: - weights_middle = [1.0]*1 - return cls(ControlWeightType.CONTROLNET, weights_output=weights_output, weights_middle=weights_middle, uncond_multiplier=uncond_multiplier, extras=extras) + def controlnet(cls, weights_output: list[float]=None, weights_middle: list[float]=None, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): + return cls(ControlWeightType.CONTROLNET, weights_output=weights_output, weights_middle=weights_middle, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod def controllora(cls, weights_output: list[float]=None, weights_middle: list[float]=None, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): - if weights_output is None: - weights_output = [1.0]*10 - if weights_middle is None: - weights_middle = [1.0]*10 - if weights_input is None: - weights_input = [1.0]*10 return cls(ControlWeightType.CONTROLLORA, weights_output=weights_output, weights_middle=weights_middle, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) @classmethod def controllllite(cls, weights_output: list[float]=None, weights_middle: list[float]=None, weights_input: list[float]=None, uncond_multiplier: float=1.0, extras: dict[str]={}): - # TODO: make the lenghts make sense - if weights_output is None: - weights_output = [1.0]*200 - if weights_middle is None: - weights_middle = [1.0]*200 - if weights_input is None: - weights_input = [1.0]*200 return cls(ControlWeightType.CONTROLLLLITE, weights_output=weights_output, weights_middle=weights_middle, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras) From 476da0e724487cdef98671f22193bb2a8c1fb88a Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 07:09:26 -0500 Subject: [PATCH 09/11] Implemented changes from ComfyUI's InstantX depth flux support commit --- adv_control/control.py | 3 +-- adv_control/utils.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/adv_control/control.py b/adv_control/control.py index 5922e45..715d725 100644 --- a/adv_control/control.py +++ b/adv_control/control.py @@ -59,7 +59,6 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): if self.manual_cast_dtype is not None: dtype = self.manual_cast_dtype - output_dtype = x_noisy.dtype # make cond_hint appropriate dimensions # TODO: change this to not require cond_hint upscaling every step when self.sub_idxs are present if self.sub_idxs is not None or self.cond_hint is None or x_noisy.shape[2] * self.compression_ratio != self.cond_hint.shape[2] or x_noisy.shape[3] * self.compression_ratio != self.cond_hint.shape[3]: @@ -101,7 +100,7 @@ class ControlNetAdvanced(ControlNet, AdvancedControlBase): x_noisy = self.model_sampling_current.calculate_input(t, x_noisy) self.x_noisy_shape = x_noisy.shape control = self.control_model(x=x_noisy.to(dtype), hint=self.cond_hint, timesteps=timestep.to(dtype), context=context.to(dtype), **extra) - return self.control_merge(control, control_prev, output_dtype) + return self.control_merge(control, control_prev, output_dtype=None) def pre_run_advanced(self, *args, **kwargs): self.is_flux = "Flux" in str(type(self.control_model).__name__) diff --git a/adv_control/utils.py b/adv_control/utils.py index 39453a5..9c7c1bb 100644 --- a/adv_control/utils.py +++ b/adv_control/utils.py @@ -878,7 +878,7 @@ class AdvancedControlBase: self.apply_advanced_strengths_and_masks(x, self.batched_number) x *= self.strength * self.calc_weight(i, x, control, key) - if x.dtype != output_dtype: + if output_dtype is not None and x.dtype != output_dtype: x = x.to(output_dtype) out[key].append(x) From 60ac29b4ae23c54f8f5fac355296fcf61abff7b0 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 07:42:18 -0500 Subject: [PATCH 10/11] version bump --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9d1085a..f8eba83 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-advanced-controlnet" description = "Nodes for scheduling ControlNet strength across timesteps and batched latents, as well as applying custom weights and attention masks." -version = "1.2.1" +version = "1.2.2" license = { file = "LICENSE" } dependencies = [] From ef16e3c6be236a79dff09ab8a49057f232de6c92 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 30 Aug 2024 07:47:38 -0500 Subject: [PATCH 11/11] Refactored Scaled Soft Weights node to remove flip_weights param --- adv_control/nodes.py | 11 +++++++---- adv_control/nodes_deprecated.py | 27 ++++++++++++++++++++++++++- adv_control/nodes_weight.py | 5 ++--- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/adv_control/nodes.py b/adv_control/nodes.py index bf258a8..9846f93 100644 --- a/adv_control/nodes.py +++ b/adv_control/nodes.py @@ -7,7 +7,7 @@ from comfy.model_patcher import ModelPatcher from .control import load_controlnet, convert_to_advanced, is_advanced_controlnet, is_sd3_advanced_controlnet from .utils import ControlWeights, LatentKeyframeGroup, TimestepKeyframeGroup, AbstractPreprocWrapper, BIGMAX -from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeightsDeprecated, +from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeights, SoftControlNetWeightsSD15, CustomControlNetWeightsSD15, CustomControlNetWeightsFlux, SoftT2IAdapterWeights, CustomT2IAdapterWeights) from .nodes_keyframes import (LatentKeyframeGroupNode, LatentKeyframeInterpolationNode, LatentKeyframeBatchedGroupNode, LatentKeyframeNode, @@ -16,7 +16,8 @@ from .nodes_sparsectrl import SparseCtrlMergedLoaderAdvanced, SparseCtrlLoaderAd from .nodes_reference import ReferenceControlNetNode, ReferenceControlFinetune, ReferencePreprocessorNode from .nodes_plusplus import PlusPlusLoaderAdvanced, PlusPlusLoaderSingle, PlusPlusInputNode from .nodes_loosecontrol import ControlNetLoaderWithLoraAdvanced -from .nodes_deprecated import (LoadImagesFromDirectory, SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated, +from .nodes_deprecated import (LoadImagesFromDirectory, ScaledSoftUniversalWeightsDeprecated, + SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated, SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated) from .logger import logger @@ -245,7 +246,7 @@ NODE_CLASS_MAPPINGS = { "ControlNetLoaderAdvanced": ControlNetLoaderAdvanced, "DiffControlNetLoaderAdvanced": DiffControlNetLoaderAdvanced, # Weights - "ScaledSoftControlNetWeights": ScaledSoftUniversalWeightsDeprecated, + "ACN_ScaledSoftControlNetWeights": ScaledSoftUniversalWeights, "ScaledSoftMaskedUniversalWeights": ScaledSoftMaskedUniversalWeights, "ACN_SoftControlNetWeightsSD15": SoftControlNetWeightsSD15, "ACN_CustomControlNetWeightsSD15": CustomControlNetWeightsSD15, @@ -272,6 +273,7 @@ NODE_CLASS_MAPPINGS = { #"ACN_ControlNetLoaderWithLoraAdvanced": ControlNetLoaderWithLoraAdvanced, # Deprecated "LoadImagesFromDirectory": LoadImagesFromDirectory, + "ScaledSoftControlNetWeights": ScaledSoftUniversalWeightsDeprecated, "SoftControlNetWeights": SoftControlNetWeightsDeprecated, "CustomControlNetWeights": CustomControlNetWeightsDeprecated, "SoftT2IAdapterWeights": SoftT2IAdapterWeightsDeprecated, @@ -294,7 +296,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { "ControlNetLoaderAdvanced": "Load Advanced ControlNet Model 🛂🅐🅒🅝", "DiffControlNetLoaderAdvanced": "Load Advanced ControlNet Model (diff) 🛂🅐🅒🅝", # Weights - "ScaledSoftControlNetWeights": "Scaled Soft Weights 🛂🅐🅒🅝", + "ACN_ScaledSoftControlNetWeights": "Scaled Soft Weights 🛂🅐🅒🅝", "ScaledSoftMaskedUniversalWeights": "Scaled Soft Masked Weights 🛂🅐🅒🅝", "ACN_SoftControlNetWeightsSD15": "ControlNet Soft Weights [SD1.5] 🛂🅐🅒🅝", "ACN_CustomControlNetWeightsSD15": "ControlNet Custom Weights [SD1.5] 🛂🅐🅒🅝", @@ -321,6 +323,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { #"ACN_ControlNetLoaderWithLoraAdvanced": "Load Adv. ControlNet Model w/ LoRA 🛂🅐🅒🅝", # Deprecated "LoadImagesFromDirectory": "🚫Load Images [DEPRECATED] 🛂🅐🅒🅝", + "ScaledSoftControlNetWeights": "Scaled Soft Weights 🛂🅐🅒🅝", "SoftControlNetWeights": "ControlNet Soft Weights 🛂🅐🅒🅝", "CustomControlNetWeights": "ControlNet Custom Weights 🛂🅐🅒🅝", "SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝", diff --git a/adv_control/nodes_deprecated.py b/adv_control/nodes_deprecated.py index 334a646..bd1d2f0 100644 --- a/adv_control/nodes_deprecated.py +++ b/adv_control/nodes_deprecated.py @@ -71,6 +71,32 @@ class LoadImagesFromDirectory: return (torch.cat(images, dim=0), torch.stack(masks, dim=0), image_count) +class ScaledSoftUniversalWeightsDeprecated: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "base_multiplier": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 1.0, "step": 0.001}, ), + "flip_weights": ("BOOLEAN", {"default": False}), + }, + "optional": { + "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), + "cn_extras": ("CN_WEIGHTS_EXTRAS",), + "autosize": ("ACNAUTOSIZE", {"padding": 0}), + } + } + + RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",) + RETURN_NAMES = ("CN_WEIGHTS", "TK_SHORTCUT") + FUNCTION = "load_weights" + + CATEGORY = "" + + def load_weights(self, base_multiplier, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + weights = ControlWeights.universal(base_multiplier=base_multiplier, uncond_multiplier=uncond_multiplier, extras=cn_extras) + return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) + + class SoftControlNetWeightsDeprecated: @classmethod def INPUT_TYPES(s): @@ -159,7 +185,6 @@ class CustomControlNetWeightsDeprecated: return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) - class SoftT2IAdapterWeightsDeprecated: @classmethod def INPUT_TYPES(s): diff --git a/adv_control/nodes_weight.py b/adv_control/nodes_weight.py index 83e10bd..09c3dee 100644 --- a/adv_control/nodes_weight.py +++ b/adv_control/nodes_weight.py @@ -66,13 +66,12 @@ class ScaledSoftMaskedUniversalWeights: return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights))) -class ScaledSoftUniversalWeightsDeprecated: +class ScaledSoftUniversalWeights: @classmethod def INPUT_TYPES(s): return { "required": { "base_multiplier": ("FLOAT", {"default": 0.825, "min": 0.0, "max": 1.0, "step": 0.001}, ), - "flip_weights": ("BOOLEAN", {"default": False}), }, "optional": { "uncond_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}, ), @@ -87,7 +86,7 @@ class ScaledSoftUniversalWeightsDeprecated: CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights" - def load_weights(self, base_multiplier, flip_weights, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): + def load_weights(self, base_multiplier, uncond_multiplier: float=1.0, cn_extras: dict[str]={}): weights = ControlWeights.universal(base_multiplier=base_multiplier, uncond_multiplier=uncond_multiplier, extras=cn_extras) return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights)))