Merge PR #169 from Kosinkadink/develop - initial flux support
Initial flux support, refactoring weight control
This commit is contained in:
+61
-23
@@ -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,13 +21,23 @@ 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())
|
||||
self.is_flux = False
|
||||
self.x_noisy_shape = None
|
||||
|
||||
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
|
||||
@@ -49,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]:
|
||||
@@ -64,9 +73,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,25 +90,44 @@ 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)
|
||||
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=None)
|
||||
|
||||
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 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, 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)
|
||||
|
||||
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
|
||||
|
||||
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,
|
||||
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
|
||||
|
||||
@@ -121,18 +149,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):
|
||||
@@ -381,11 +419,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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
+123
-64
@@ -7,15 +7,18 @@ 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, ScaledSoftUniversalWeights,
|
||||
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
|
||||
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, ScaledSoftUniversalWeightsDeprecated,
|
||||
SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated,
|
||||
SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated)
|
||||
from .logger import logger
|
||||
|
||||
from .sampling import acn_sample_factory
|
||||
@@ -104,7 +107,7 @@ class AdvancedControlNetApply:
|
||||
"weights_override": ("CONTROL_NET_WEIGHTS", ),
|
||||
"model_optional": ("MODEL",),
|
||||
"vae_optional": ("VAE",),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 40}),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +120,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 +132,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,16 +241,18 @@ NODE_CLASS_MAPPINGS = {
|
||||
"LatentKeyframeGroup": LatentKeyframeGroupNode,
|
||||
# Conditioning
|
||||
"ACN_AdvancedControlNetApply": AdvancedControlNetApply,
|
||||
"ACN_AdvancedControlNetApplySingle": AdvancedControlNetApplySingle,
|
||||
# Loaders
|
||||
"ControlNetLoaderAdvanced": ControlNetLoaderAdvanced,
|
||||
"DiffControlNetLoaderAdvanced": DiffControlNetLoaderAdvanced,
|
||||
# Weights
|
||||
"ScaledSoftControlNetWeights": ScaledSoftUniversalWeights,
|
||||
"ACN_ScaledSoftControlNetWeights": ScaledSoftUniversalWeights,
|
||||
"ScaledSoftMaskedUniversalWeights": ScaledSoftMaskedUniversalWeights,
|
||||
"SoftControlNetWeights": SoftControlNetWeights,
|
||||
"CustomControlNetWeights": CustomControlNetWeights,
|
||||
"SoftT2IAdapterWeights": SoftT2IAdapterWeights,
|
||||
"CustomT2IAdapterWeights": CustomT2IAdapterWeights,
|
||||
"ACN_SoftControlNetWeightsSD15": SoftControlNetWeightsSD15,
|
||||
"ACN_CustomControlNetWeightsSD15": CustomControlNetWeightsSD15,
|
||||
"ACN_CustomControlNetWeightsFlux": CustomControlNetWeightsFlux,
|
||||
"ACN_SoftT2IAdapterWeights": SoftT2IAdapterWeights,
|
||||
"ACN_CustomT2IAdapterWeights": CustomT2IAdapterWeights,
|
||||
"ACN_DefaultUniversalWeights": DefaultWeights,
|
||||
# SparseCtrl
|
||||
"ACN_SparseCtrlRGBPreprocessor": RgbSparseCtrlPreprocessor,
|
||||
@@ -226,6 +273,11 @@ NODE_CLASS_MAPPINGS = {
|
||||
#"ACN_ControlNetLoaderWithLoraAdvanced": ControlNetLoaderWithLoraAdvanced,
|
||||
# Deprecated
|
||||
"LoadImagesFromDirectory": LoadImagesFromDirectory,
|
||||
"ScaledSoftControlNetWeights": ScaledSoftUniversalWeightsDeprecated,
|
||||
"SoftControlNetWeights": SoftControlNetWeightsDeprecated,
|
||||
"CustomControlNetWeights": CustomControlNetWeightsDeprecated,
|
||||
"SoftT2IAdapterWeights": SoftT2IAdapterWeightsDeprecated,
|
||||
"CustomT2IAdapterWeights": CustomT2IAdapterWeightsDeprecated,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
@@ -239,16 +291,18 @@ 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) 🛂🅐🅒🅝",
|
||||
# Weights
|
||||
"ScaledSoftControlNetWeights": "Scaled Soft Weights 🛂🅐🅒🅝",
|
||||
"ACN_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_CustomControlNetWeightsFlux": "ControlNet Custom Weights [Flux] 🛂🅐🅒🅝",
|
||||
"ACN_SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝",
|
||||
"ACN_CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝",
|
||||
"ACN_DefaultUniversalWeights": "Default Weights 🛂🅐🅒🅝",
|
||||
# SparseCtrl
|
||||
"ACN_SparseCtrlRGBPreprocessor": "RGB SparseCtrl 🛂🅐🅒🅝",
|
||||
@@ -269,4 +323,9 @@ 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 🛂🅐🅒🅝",
|
||||
"CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝",
|
||||
}
|
||||
|
||||
@@ -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,183 @@ 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 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):
|
||||
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 = ""
|
||||
|
||||
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 = ""
|
||||
|
||||
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 = ""
|
||||
|
||||
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 = ""
|
||||
|
||||
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)))
|
||||
|
||||
+133
-90
@@ -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}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,12 +72,11 @@ class ScaledSoftUniversalWeights:
|
||||
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": 20}),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,77 +86,34 @@ 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)))
|
||||
|
||||
|
||||
class SoftControlNetWeights:
|
||||
@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": 50}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("CONTROL_NET_WEIGHTS", "TIMESTEP_KEYFRAME",)
|
||||
RETURN_NAMES = WEIGHTS_RETURN_NAMES
|
||||
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 = [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)
|
||||
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)))
|
||||
|
||||
|
||||
class CustomControlNetWeights:
|
||||
class SoftControlNetWeightsSD15:
|
||||
@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": 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}, ),
|
||||
"cn_extras": ("CN_WEIGHTS_EXTRAS",),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 65}),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,12 +123,105 @@ class CustomControlNetWeights:
|
||||
|
||||
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 = [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)
|
||||
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:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"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}, ),
|
||||
"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, 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)))
|
||||
|
||||
|
||||
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)))
|
||||
|
||||
|
||||
@@ -181,16 +230,15 @@ class SoftT2IAdapterWeights:
|
||||
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}, ),
|
||||
"cn_extras": ("CN_WEIGHTS_EXTRAS",),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 55}),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,13 +248,10 @@ class SoftT2IAdapterWeights:
|
||||
|
||||
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 = 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)
|
||||
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:
|
||||
@@ -214,16 +259,15 @@ class CustomT2IAdapterWeights:
|
||||
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}, ),
|
||||
"cn_extras": ("CN_WEIGHTS_EXTRAS",),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 65}),
|
||||
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,10 +277,9 @@ class CustomT2IAdapterWeights:
|
||||
|
||||
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, 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)))
|
||||
|
||||
+62
-55
@@ -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
|
||||
|
||||
@@ -157,14 +158,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,63 +176,59 @@ 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:
|
||||
# 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
|
||||
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]
|
||||
|
||||
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]={}):
|
||||
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, 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: 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]={}):
|
||||
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]={}):
|
||||
return cls(ControlWeightType.CONTROLLLLITE, weights_output=weights_output, weights_middle=weights_middle, weights_input=weights_input, uncond_multiplier=uncond_multiplier, extras=extras)
|
||||
|
||||
|
||||
class StrengthInterpolation:
|
||||
@@ -434,14 +433,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
|
||||
|
||||
@@ -775,11 +779,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
|
||||
@@ -829,7 +836,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
|
||||
@@ -845,10 +852,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:
|
||||
@@ -871,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)
|
||||
@@ -913,7 +920,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:
|
||||
|
||||
+1
-1
@@ -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 = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user