Metaphysix2's picture
Upload folder using huggingface_hub
3e5f61c
from pathlib import Path
import torch
import comfy.sample as comfy_sample
from comfy.model_patcher import ModelPatcher
from .context import ContextOptions, ContextSchedules, UniformContextOptions
from .logger import logger
from .model_utils import BetaSchedules, get_available_motion_loras, get_available_motion_models, get_motion_lora_path
from .motion_utils import NoiseType
from .motion_lora import MotionLoraInfo, MotionLoraList
from .model_injection import InjectionParams, ModelPatcherAndInjector, MotionModelSettings, load_motion_module
from .sampling import motion_sample_factory
from .nodes_extras import AnimateDiffUnload, EmptyLatentImageLarge, CheckpointLoaderSimpleWithNoiseSelect
from .nodes_experimental import AnimateDiffModelSettingsSimple, AnimateDiffModelSettingsAdvanced, AnimateDiffModelSettingsAdvancedAttnStrengths
from .nodes_deprecated import AnimateDiffLoader_Deprecated, AnimateDiffLoaderAdvanced_Deprecated, AnimateDiffCombine_Deprecated
# override comfy_sample.sample with animatediff-support version
comfy_sample.sample = motion_sample_factory(comfy_sample.sample)
comfy_sample.sample_custom = motion_sample_factory(comfy_sample.sample_custom)
class AnimateDiffModelSettings:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"min_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
"max_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
},
"optional": {
"mask_motion_scale": ("MASK",),
}
}
RETURN_TYPES = ("MOTION_MODEL_SETTINGS",)
CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/motion settings"
FUNCTION = "get_motion_model_settings"
def get_motion_model_settings(self, mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
motion_model_settings = MotionModelSettings(
mask_attn_scale=mask_motion_scale,
mask_attn_scale_min=min_motion_scale,
mask_attn_scale_max=max_motion_scale,
)
return (motion_model_settings,)
class AnimateDiffLoraLoader:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"lora_name": (get_available_motion_loras(),),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}),
},
"optional": {
"prev_motion_lora": ("MOTION_LORA",),
}
}
RETURN_TYPES = ("MOTION_LORA",)
CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“"
FUNCTION = "load_motion_lora"
def load_motion_lora(self, lora_name: str, strength: float, prev_motion_lora: MotionLoraList=None):
if prev_motion_lora is None:
prev_motion_lora = MotionLoraList()
else:
prev_motion_lora = prev_motion_lora.clone()
# check if motion lora with name exists
lora_path = get_motion_lora_path(lora_name)
if not Path(lora_path).is_file():
raise FileNotFoundError(f"Motion lora with name '{lora_name}' not found.")
# create motion lora info to be loaded in AnimateDiff Loader
lora_info = MotionLoraInfo(name=lora_name, strength=strength)
prev_motion_lora.add_lora(lora_info)
return (prev_motion_lora,)
class AnimateDiffLoaderWithContext:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": ("MODEL",),
"model_name": (get_available_motion_models(),),
"beta_schedule": (BetaSchedules.ALIAS_LIST, {"default": BetaSchedules.SQRT_LINEAR}),
#"apply_mm_groupnorm_hack": ("BOOLEAN", {"default": True}),
},
"optional": {
"context_options": ("CONTEXT_OPTIONS",),
"motion_lora": ("MOTION_LORA",),
"motion_model_settings": ("MOTION_MODEL_SETTINGS",),
"motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
"apply_v2_models_properly": ("BOOLEAN", {"default": True}),
}
}
RETURN_TYPES = ("MODEL",)
CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“"
FUNCTION = "load_mm_and_inject_params"
def load_mm_and_inject_params(self,
model: ModelPatcher,
model_name: str, beta_schedule: str,# apply_mm_groupnorm_hack: bool,
context_options: ContextOptions=None, motion_lora: MotionLoraList=None, motion_model_settings: MotionModelSettings=None,
motion_scale: float=1.0, apply_v2_models_properly: bool=False,
):
# load motion module
motion_model = load_motion_module(model_name, model, motion_lora=motion_lora, motion_model_settings=motion_model_settings)
# set injection params
params = InjectionParams(
video_length=None,
unlimited_area_hack=False,
apply_mm_groupnorm_hack=True,
beta_schedule=beta_schedule,
model_name=model_name,
apply_v2_models_properly=apply_v2_models_properly,
)
if context_options:
# set context settings TODO: make this dynamic for future purposes
if type(context_options) == UniformContextOptions:
params.set_context(
context_length=context_options.context_length,
context_stride=context_options.context_stride,
context_overlap=context_options.context_overlap,
context_schedule=context_options.context_schedule,
closed_loop=context_options.closed_loop,
sync_context_to_pe=context_options.sync_context_to_pe,
)
params.noise_type = context_options.noise_type
if motion_lora:
params.set_loras(motion_lora)
# set motion_scale and motion_model_settings
if not motion_model_settings:
motion_model_settings = MotionModelSettings()
motion_model_settings.attn_scale = motion_scale
params.set_motion_model_settings(motion_model_settings)
# apply scale multiplier, if needed
motion_model.model.set_scale_multiplier(params.motion_model_settings.attn_scale)
# apply scale mask, if needed
motion_model.model.set_masks(
masks=params.motion_model_settings.mask_attn_scale,
min_val=params.motion_model_settings.mask_attn_scale_min,
max_val=params.motion_model_settings.mask_attn_scale_max
)
model = ModelPatcherAndInjector(model)
model.motion_model = motion_model
model.motion_injection_params = params
# save model sampling from BetaSchedule as object patch
new_model_sampling = BetaSchedules.to_model_sampling(params.beta_schedule, model)
if new_model_sampling is not None:
model.add_object_patch("model_sampling", new_model_sampling)
del motion_model
return (model,)
class AnimateDiffUniformContextOptions:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"context_length": ("INT", {"default": 16, "min": 1, "max": 32}), # keep an eye on these max values
"context_stride": ("INT", {"default": 1, "min": 1, "max": 32}), # would need to be updated
"context_overlap": ("INT", {"default": 4, "min": 0, "max": 32}), # if new motion modules come out
"context_schedule": (ContextSchedules.CONTEXT_SCHEDULE_LIST,),
"closed_loop": ("BOOLEAN", {"default": False},),
#"sync_context_to_pe": ("BOOLEAN", {"default": False},),
},
}
RETURN_TYPES = ("CONTEXT_OPTIONS",)
CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“"
FUNCTION = "create_options"
def create_options(self, context_length: int, context_stride: int, context_overlap: int, context_schedule: int, closed_loop: bool):
context_options = UniformContextOptions(
context_length=context_length,
context_stride=context_stride,
context_overlap=context_overlap,
context_schedule=context_schedule,
closed_loop=closed_loop
)
#context_options.set_sync_context_to_pe(sync_context_to_pe)
return (context_options,)
class AnimateDiffUniformContextOptionsExperimental:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"context_length": ("INT", {"default": 16, "min": 1, "max": 32}), # keep an eye on these max values
"context_stride": ("INT", {"default": 1, "min": 1, "max": 32}), # would need to be updated
"context_overlap": ("INT", {"default": 0, "min": 0, "max": 32}), # if new motion modules come out
"context_schedule": (ContextSchedules.CONTEXT_SCHEDULE_LIST,),
"closed_loop": ("BOOLEAN", {"default": False},),
"noise_override": (NoiseType.LIST,)
#"sync_context_to_pe": ("BOOLEAN", {"default": False},),
},
}
RETURN_TYPES = ("CONTEXT_OPTIONS",)
CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“"
FUNCTION = "create_options"
def create_options(self, context_length: int, context_stride: int, context_overlap: int, context_schedule: int, closed_loop: bool,
noise_override: str):
context_options = UniformContextOptions(
context_length=context_length,
context_stride=context_stride,
context_overlap=context_overlap,
context_schedule=context_schedule,
closed_loop=closed_loop,
)
context_options.set_noise_type(noise_override)
#context_options.set_sync_context_to_pe(sync_context_to_pe)
return (context_options,)
NODE_CLASS_MAPPINGS = {
"ADE_AnimateDiffUniformContextOptions": AnimateDiffUniformContextOptions,
#"ADE_AnimateDiffUniformContextOptionsExperimental": AnimateDiffUniformContextOptionsExperimental,
"ADE_AnimateDiffLoaderWithContext": AnimateDiffLoaderWithContext,
"ADE_AnimateDiffLoRALoader": AnimateDiffLoraLoader,
"ADE_AnimateDiffModelSettings_Release": AnimateDiffModelSettings,
# Experimental Nodes
"ADE_AnimateDiffModelSettingsSimple": AnimateDiffModelSettingsSimple,
"ADE_AnimateDiffModelSettings": AnimateDiffModelSettingsAdvanced,
"ADE_AnimateDiffModelSettingsAdvancedAttnStrengths": AnimateDiffModelSettingsAdvancedAttnStrengths,
# Extras Nodes
"ADE_AnimateDiffUnload": AnimateDiffUnload,
"ADE_EmptyLatentImageLarge": EmptyLatentImageLarge,
"CheckpointLoaderSimpleWithNoiseSelect": CheckpointLoaderSimpleWithNoiseSelect,
# Deprecated Nodes
"AnimateDiffLoaderV1": AnimateDiffLoader_Deprecated,
"ADE_AnimateDiffLoaderV1Advanced": AnimateDiffLoaderAdvanced_Deprecated,
"ADE_AnimateDiffCombine": AnimateDiffCombine_Deprecated,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"ADE_AnimateDiffUniformContextOptions": "Uniform Context Options πŸŽ­πŸ…πŸ…“",
#"ADE_AnimateDiffUniformContextOptionsExperimental": "EXPERIMENTAL Uniform Context Options πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffLoaderWithContext": "AnimateDiff Loader πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffLoRALoader": "AnimateDiff LoRA Loader πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffModelSettings_Release": "Motion Model Settings πŸŽ­πŸ…πŸ…“",
# Experimental Nodes
"ADE_AnimateDiffModelSettingsSimple": "EXP Motion Model Settings (Simple) πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffModelSettings": "EXP Motion Model Settings (Advanced) πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffModelSettingsAdvancedAttnStrengths": "EXP Motion Model Settings (Adv. Attn) πŸŽ­πŸ…πŸ…“",
# Extras Nodes
"ADE_AnimateDiffUnload": "AnimateDiff Unload πŸŽ­πŸ…πŸ…“",
"ADE_EmptyLatentImageLarge": "Empty Latent Image (Big Batch) πŸŽ­πŸ…πŸ…“",
"CheckpointLoaderSimpleWithNoiseSelect": "Load Checkpoint w/ Noise Select πŸŽ­πŸ…πŸ…“",
# Deprecated Nodes
"AnimateDiffLoaderV1": "AnimateDiff Loader [DEPRECATED] πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffLoaderV1Advanced": "AnimateDiff Loader (Advanced) [DEPRECATED] πŸŽ­πŸ…πŸ…“",
"ADE_AnimateDiffCombine": "DO NOT USE, USE VideoCombine from ComfyUI-VideoHelperSuite instead! AnimateDiff Combine [DEPRECATED, DO NOT USE] πŸŽ­πŸ…πŸ…“",
}