mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-07-29 09:16:48 +00:00
restore nodes order as it in the V1 version for smaller git diff (1)
This commit is contained in:
parent
675e9fd788
commit
918ca7f2ea
@ -52,6 +52,6 @@ class EmptyAceStepLatentAudio(io.ComfyNode):
|
|||||||
|
|
||||||
|
|
||||||
NODES_LIST: list[type[io.ComfyNode]] = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
TextEncodeAceStepAudio,
|
|
||||||
EmptyAceStepLatentAudio,
|
EmptyAceStepLatentAudio,
|
||||||
|
TextEncodeAceStepAudio,
|
||||||
]
|
]
|
||||||
|
@ -122,7 +122,7 @@ class SamplerEulerCFGpp(io.ComfyNode):
|
|||||||
return io.NodeOutput(sampler)
|
return io.NodeOutput(sampler)
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
SamplerLCMUpscale,
|
|
||||||
SamplerEulerCFGpp,
|
SamplerEulerCFGpp,
|
||||||
|
SamplerLCMUpscale,
|
||||||
]
|
]
|
||||||
|
@ -5,6 +5,18 @@ import torch
|
|||||||
|
|
||||||
from comfy_api.latest import io
|
from comfy_api.latest import io
|
||||||
|
|
||||||
|
|
||||||
|
def loglinear_interp(t_steps, num_steps):
|
||||||
|
"""Performs log-linear interpolation of a given array of decreasing numbers."""
|
||||||
|
xs = np.linspace(0, 1, len(t_steps))
|
||||||
|
ys = np.log(t_steps[::-1])
|
||||||
|
|
||||||
|
new_xs = np.linspace(0, 1, num_steps)
|
||||||
|
new_ys = np.interp(new_xs, xs, ys)
|
||||||
|
|
||||||
|
return np.exp(new_ys)[::-1].copy()
|
||||||
|
|
||||||
|
|
||||||
NOISE_LEVELS = {
|
NOISE_LEVELS = {
|
||||||
"SD1": [
|
"SD1": [
|
||||||
14.6146412293,
|
14.6146412293,
|
||||||
@ -36,17 +48,6 @@ NOISE_LEVELS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def loglinear_interp(t_steps, num_steps):
|
|
||||||
"""Performs log-linear interpolation of a given array of decreasing numbers."""
|
|
||||||
xs = np.linspace(0, 1, len(t_steps))
|
|
||||||
ys = np.log(t_steps[::-1])
|
|
||||||
|
|
||||||
new_xs = np.linspace(0, 1, num_steps)
|
|
||||||
new_ys = np.interp(new_xs, xs, ys)
|
|
||||||
|
|
||||||
return np.exp(new_ys)[::-1].copy()
|
|
||||||
|
|
||||||
|
|
||||||
class AlignYourStepsScheduler(io.ComfyNode):
|
class AlignYourStepsScheduler(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls) -> io.Schema:
|
def define_schema(cls) -> io.Schema:
|
||||||
@ -78,6 +79,6 @@ class AlignYourStepsScheduler(io.ComfyNode):
|
|||||||
return io.NodeOutput(torch.FloatTensor(sigmas))
|
return io.NodeOutput(torch.FloatTensor(sigmas))
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
AlignYourStepsScheduler,
|
AlignYourStepsScheduler,
|
||||||
]
|
]
|
||||||
|
@ -93,6 +93,6 @@ class APG(io.ComfyNode):
|
|||||||
return io.NodeOutput(m)
|
return io.NodeOutput(m)
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
APG,
|
APG,
|
||||||
]
|
]
|
||||||
|
@ -131,9 +131,9 @@ class UNetTemporalAttentionMultiply(io.ComfyNode):
|
|||||||
return io.NodeOutput(m)
|
return io.NodeOutput(m)
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
UNetSelfAttentionMultiply,
|
|
||||||
UNetCrossAttentionMultiply,
|
|
||||||
CLIPAttentionMultiply,
|
CLIPAttentionMultiply,
|
||||||
|
UNetCrossAttentionMultiply,
|
||||||
|
UNetSelfAttentionMultiply,
|
||||||
UNetTemporalAttentionMultiply,
|
UNetTemporalAttentionMultiply,
|
||||||
]
|
]
|
||||||
|
@ -13,6 +13,28 @@ import node_helpers
|
|||||||
from comfy_api.latest import io, ui
|
from comfy_api.latest import io, ui
|
||||||
|
|
||||||
|
|
||||||
|
class EmptyLatentAudio(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="EmptyLatentAudio_V3",
|
||||||
|
category="latent/audio",
|
||||||
|
inputs=[
|
||||||
|
io.Float.Input("seconds", default=47.6, min=1.0, max=1000.0, step=0.1),
|
||||||
|
io.Int.Input(
|
||||||
|
"batch_size", default=1, min=1, max=4096, tooltip="The number of latent images in the batch."
|
||||||
|
),
|
||||||
|
],
|
||||||
|
outputs=[io.Latent.Output()],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, seconds, batch_size) -> io.NodeOutput:
|
||||||
|
length = round((seconds * 44100 / 2048) / 2) * 2
|
||||||
|
latent = torch.zeros([batch_size, 64, length], device=comfy.model_management.intermediate_device())
|
||||||
|
return io.NodeOutput({"samples": latent, "type": "audio"})
|
||||||
|
|
||||||
|
|
||||||
class ConditioningStableAudio(io.ComfyNode):
|
class ConditioningStableAudio(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
@ -43,26 +65,140 @@ class ConditioningStableAudio(io.ComfyNode):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class EmptyLatentAudio(io.ComfyNode):
|
class VAEEncodeAudio(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return io.Schema(
|
return io.Schema(
|
||||||
node_id="EmptyLatentAudio_V3",
|
node_id="VAEEncodeAudio_V3",
|
||||||
category="latent/audio",
|
category="latent/audio",
|
||||||
inputs=[
|
inputs=[
|
||||||
io.Float.Input("seconds", default=47.6, min=1.0, max=1000.0, step=0.1),
|
io.Audio.Input("audio"),
|
||||||
io.Int.Input(
|
io.Vae.Input("vae"),
|
||||||
"batch_size", default=1, min=1, max=4096, tooltip="The number of latent images in the batch."
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
outputs=[io.Latent.Output()],
|
outputs=[io.Latent.Output()],
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute(cls, seconds, batch_size) -> io.NodeOutput:
|
def execute(cls, vae, audio) -> io.NodeOutput:
|
||||||
length = round((seconds * 44100 / 2048) / 2) * 2
|
sample_rate = audio["sample_rate"]
|
||||||
latent = torch.zeros([batch_size, 64, length], device=comfy.model_management.intermediate_device())
|
if 44100 != sample_rate:
|
||||||
return io.NodeOutput({"samples": latent, "type": "audio"})
|
waveform = torchaudio.functional.resample(audio["waveform"], sample_rate, 44100)
|
||||||
|
else:
|
||||||
|
waveform = audio["waveform"]
|
||||||
|
return io.NodeOutput({"samples": vae.encode(waveform.movedim(1, -1))})
|
||||||
|
|
||||||
|
|
||||||
|
class VAEDecodeAudio(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="VAEDecodeAudio_V3",
|
||||||
|
category="latent/audio",
|
||||||
|
inputs=[
|
||||||
|
io.Latent.Input("samples"),
|
||||||
|
io.Vae.Input("vae"),
|
||||||
|
],
|
||||||
|
outputs=[io.Audio.Output()],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, vae, samples) -> io.NodeOutput:
|
||||||
|
audio = vae.decode(samples["samples"]).movedim(-1, 1)
|
||||||
|
std = torch.std(audio, dim=[1, 2], keepdim=True) * 5.0
|
||||||
|
std[std < 1.0] = 1.0
|
||||||
|
audio /= std
|
||||||
|
return io.NodeOutput({"waveform": audio, "sample_rate": 44100})
|
||||||
|
|
||||||
|
|
||||||
|
class SaveAudio(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="SaveAudio_V3", # frontend expects "SaveAudio" to work
|
||||||
|
display_name="Save Audio _V3", # frontend ignores "display_name" for this node
|
||||||
|
category="audio",
|
||||||
|
inputs=[
|
||||||
|
io.Audio.Input("audio"),
|
||||||
|
io.String.Input("filename_prefix", default="audio/ComfyUI"),
|
||||||
|
],
|
||||||
|
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
||||||
|
is_output_node=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, audio, filename_prefix="ComfyUI", format="flac") -> io.NodeOutput:
|
||||||
|
return io.NodeOutput(
|
||||||
|
ui=ui.AudioSaveHelper.get_save_audio_ui(audio, filename_prefix=filename_prefix, cls=cls, format=format)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SaveAudioMP3(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="SaveAudioMP3_V3", # frontend expects "SaveAudioMP3" to work
|
||||||
|
display_name="Save Audio(MP3) _V3", # frontend ignores "display_name" for this node
|
||||||
|
category="audio",
|
||||||
|
inputs=[
|
||||||
|
io.Audio.Input("audio"),
|
||||||
|
io.String.Input("filename_prefix", default="audio/ComfyUI"),
|
||||||
|
io.Combo.Input("quality", options=["V0", "128k", "320k"], default="V0"),
|
||||||
|
],
|
||||||
|
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
||||||
|
is_output_node=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, audio, filename_prefix="ComfyUI", format="mp3", quality="V0") -> io.NodeOutput:
|
||||||
|
return io.NodeOutput(
|
||||||
|
ui=ui.AudioSaveHelper.get_save_audio_ui(
|
||||||
|
audio, filename_prefix=filename_prefix, cls=cls, format=format, quality=quality
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SaveAudioOpus(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="SaveAudioOpus_V3", # frontend expects "SaveAudioOpus" to work
|
||||||
|
display_name="Save Audio(Opus) _V3", # frontend ignores "display_name" for this node
|
||||||
|
category="audio",
|
||||||
|
inputs=[
|
||||||
|
io.Audio.Input("audio"),
|
||||||
|
io.String.Input("filename_prefix", default="audio/ComfyUI"),
|
||||||
|
io.Combo.Input("quality", options=["64k", "96k", "128k", "192k", "320k"], default="128k"),
|
||||||
|
],
|
||||||
|
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
||||||
|
is_output_node=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, audio, filename_prefix="ComfyUI", format="opus", quality="128k") -> io.NodeOutput:
|
||||||
|
return io.NodeOutput(
|
||||||
|
ui=ui.AudioSaveHelper.get_save_audio_ui(
|
||||||
|
audio, filename_prefix=filename_prefix, cls=cls, format=format, quality=quality
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PreviewAudio(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="PreviewAudio_V3", # frontend expects "PreviewAudio" to work
|
||||||
|
display_name="Preview Audio _V3", # frontend ignores "display_name" for this node
|
||||||
|
category="audio",
|
||||||
|
inputs=[
|
||||||
|
io.Audio.Input("audio"),
|
||||||
|
],
|
||||||
|
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
||||||
|
is_output_node=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, audio) -> io.NodeOutput:
|
||||||
|
return io.NodeOutput(ui=ui.PreviewAudio(audio, cls=cls))
|
||||||
|
|
||||||
|
|
||||||
class LoadAudio(io.ComfyNode):
|
class LoadAudio(io.ComfyNode):
|
||||||
@ -141,150 +277,14 @@ class LoadAudio(io.ComfyNode):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class PreviewAudio(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="PreviewAudio_V3", # frontend expects "PreviewAudio" to work
|
|
||||||
display_name="Preview Audio _V3", # frontend ignores "display_name" for this node
|
|
||||||
category="audio",
|
|
||||||
inputs=[
|
|
||||||
io.Audio.Input("audio"),
|
|
||||||
],
|
|
||||||
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
|
||||||
is_output_node=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, audio) -> io.NodeOutput:
|
|
||||||
return io.NodeOutput(ui=ui.PreviewAudio(audio, cls=cls))
|
|
||||||
|
|
||||||
|
|
||||||
class SaveAudioMP3(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="SaveAudioMP3_V3", # frontend expects "SaveAudioMP3" to work
|
|
||||||
display_name="Save Audio(MP3) _V3", # frontend ignores "display_name" for this node
|
|
||||||
category="audio",
|
|
||||||
inputs=[
|
|
||||||
io.Audio.Input("audio"),
|
|
||||||
io.String.Input("filename_prefix", default="audio/ComfyUI"),
|
|
||||||
io.Combo.Input("quality", options=["V0", "128k", "320k"], default="V0"),
|
|
||||||
],
|
|
||||||
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
|
||||||
is_output_node=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, audio, filename_prefix="ComfyUI", format="mp3", quality="V0") -> io.NodeOutput:
|
|
||||||
return io.NodeOutput(
|
|
||||||
ui=ui.AudioSaveHelper.get_save_audio_ui(
|
|
||||||
audio, filename_prefix=filename_prefix, cls=cls, format=format, quality=quality
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SaveAudioOpus(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="SaveAudioOpus_V3", # frontend expects "SaveAudioOpus" to work
|
|
||||||
display_name="Save Audio(Opus) _V3", # frontend ignores "display_name" for this node
|
|
||||||
category="audio",
|
|
||||||
inputs=[
|
|
||||||
io.Audio.Input("audio"),
|
|
||||||
io.String.Input("filename_prefix", default="audio/ComfyUI"),
|
|
||||||
io.Combo.Input("quality", options=["64k", "96k", "128k", "192k", "320k"], default="128k"),
|
|
||||||
],
|
|
||||||
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
|
||||||
is_output_node=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, audio, filename_prefix="ComfyUI", format="opus", quality="128k") -> io.NodeOutput:
|
|
||||||
return io.NodeOutput(
|
|
||||||
ui=ui.AudioSaveHelper.get_save_audio_ui(
|
|
||||||
audio, filename_prefix=filename_prefix, cls=cls, format=format, quality=quality
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SaveAudio(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="SaveAudio_V3", # frontend expects "SaveAudio" to work
|
|
||||||
display_name="Save Audio _V3", # frontend ignores "display_name" for this node
|
|
||||||
category="audio",
|
|
||||||
inputs=[
|
|
||||||
io.Audio.Input("audio"),
|
|
||||||
io.String.Input("filename_prefix", default="audio/ComfyUI"),
|
|
||||||
],
|
|
||||||
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
|
|
||||||
is_output_node=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, audio, filename_prefix="ComfyUI", format="flac") -> io.NodeOutput:
|
|
||||||
return io.NodeOutput(
|
|
||||||
ui=ui.AudioSaveHelper.get_save_audio_ui(audio, filename_prefix=filename_prefix, cls=cls, format=format)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class VAEDecodeAudio(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="VAEDecodeAudio_V3",
|
|
||||||
category="latent/audio",
|
|
||||||
inputs=[
|
|
||||||
io.Latent.Input("samples"),
|
|
||||||
io.Vae.Input("vae"),
|
|
||||||
],
|
|
||||||
outputs=[io.Audio.Output()],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, vae, samples) -> io.NodeOutput:
|
|
||||||
audio = vae.decode(samples["samples"]).movedim(-1, 1)
|
|
||||||
std = torch.std(audio, dim=[1, 2], keepdim=True) * 5.0
|
|
||||||
std[std < 1.0] = 1.0
|
|
||||||
audio /= std
|
|
||||||
return io.NodeOutput({"waveform": audio, "sample_rate": 44100})
|
|
||||||
|
|
||||||
|
|
||||||
class VAEEncodeAudio(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="VAEEncodeAudio_V3",
|
|
||||||
category="latent/audio",
|
|
||||||
inputs=[
|
|
||||||
io.Audio.Input("audio"),
|
|
||||||
io.Vae.Input("vae"),
|
|
||||||
],
|
|
||||||
outputs=[io.Latent.Output()],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, vae, audio) -> io.NodeOutput:
|
|
||||||
sample_rate = audio["sample_rate"]
|
|
||||||
if 44100 != sample_rate:
|
|
||||||
waveform = torchaudio.functional.resample(audio["waveform"], sample_rate, 44100)
|
|
||||||
else:
|
|
||||||
waveform = audio["waveform"]
|
|
||||||
return io.NodeOutput({"samples": vae.encode(waveform.movedim(1, -1))})
|
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST: list[type[io.ComfyNode]] = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
ConditioningStableAudio,
|
ConditioningStableAudio,
|
||||||
EmptyLatentAudio,
|
EmptyLatentAudio,
|
||||||
LoadAudio,
|
LoadAudio,
|
||||||
PreviewAudio,
|
PreviewAudio,
|
||||||
|
SaveAudio,
|
||||||
SaveAudioMP3,
|
SaveAudioMP3,
|
||||||
SaveAudioOpus,
|
SaveAudioOpus,
|
||||||
SaveAudio,
|
|
||||||
VAEDecodeAudio,
|
VAEDecodeAudio,
|
||||||
VAEEncodeAudio,
|
VAEEncodeAudio,
|
||||||
]
|
]
|
||||||
|
@ -212,6 +212,6 @@ class WanCameraEmbedding(io.ComfyNode):
|
|||||||
return io.NodeOutput(control_camera_video, width, height, length)
|
return io.NodeOutput(control_camera_video, width, height, length)
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
WanCameraEmbedding,
|
WanCameraEmbedding,
|
||||||
]
|
]
|
||||||
|
@ -27,6 +27,6 @@ class Canny(io.ComfyNode):
|
|||||||
return io.NodeOutput(img_out)
|
return io.NodeOutput(img_out)
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
Canny,
|
Canny,
|
||||||
]
|
]
|
||||||
|
@ -5,6 +5,7 @@ import torch
|
|||||||
from comfy_api.latest import io
|
from comfy_api.latest import io
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/WeichenFan/CFG-Zero-star
|
||||||
def optimized_scale(positive, negative):
|
def optimized_scale(positive, negative):
|
||||||
positive_flat = positive.reshape(positive.shape[0], -1)
|
positive_flat = positive.reshape(positive.shape[0], -1)
|
||||||
negative_flat = negative.reshape(negative.shape[0], -1)
|
negative_flat = negative.reshape(negative.shape[0], -1)
|
||||||
@ -21,6 +22,36 @@ def optimized_scale(positive, negative):
|
|||||||
return st_star.reshape([positive.shape[0]] + [1] * (positive.ndim - 1))
|
return st_star.reshape([positive.shape[0]] + [1] * (positive.ndim - 1))
|
||||||
|
|
||||||
|
|
||||||
|
class CFGZeroStar(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id="CFGZeroStar_V3",
|
||||||
|
category="advanced/guidance",
|
||||||
|
inputs=[
|
||||||
|
io.Model.Input("model"),
|
||||||
|
],
|
||||||
|
outputs=[io.Model.Output(display_name="patched_model")],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model) -> io.NodeOutput:
|
||||||
|
m = model.clone()
|
||||||
|
|
||||||
|
def cfg_zero_star(args):
|
||||||
|
guidance_scale = args['cond_scale']
|
||||||
|
x = args['input']
|
||||||
|
cond_p = args['cond_denoised']
|
||||||
|
uncond_p = args['uncond_denoised']
|
||||||
|
out = args["denoised"]
|
||||||
|
alpha = optimized_scale(x - cond_p, x - uncond_p)
|
||||||
|
|
||||||
|
return out + uncond_p * (alpha - 1.0) + guidance_scale * uncond_p * (1.0 - alpha)
|
||||||
|
|
||||||
|
m.set_model_sampler_post_cfg_function(cfg_zero_star)
|
||||||
|
return io.NodeOutput(m)
|
||||||
|
|
||||||
|
|
||||||
class CFGNorm(io.ComfyNode):
|
class CFGNorm(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls) -> io.Schema:
|
def define_schema(cls) -> io.Schema:
|
||||||
@ -52,37 +83,7 @@ class CFGNorm(io.ComfyNode):
|
|||||||
return io.NodeOutput(m)
|
return io.NodeOutput(m)
|
||||||
|
|
||||||
|
|
||||||
class CFGZeroStar(io.ComfyNode):
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
@classmethod
|
|
||||||
def define_schema(cls) -> io.Schema:
|
|
||||||
return io.Schema(
|
|
||||||
node_id="CFGZeroStar_V3",
|
|
||||||
category="advanced/guidance",
|
|
||||||
inputs=[
|
|
||||||
io.Model.Input("model"),
|
|
||||||
],
|
|
||||||
outputs=[io.Model.Output(display_name="patched_model")],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, model) -> io.NodeOutput:
|
|
||||||
m = model.clone()
|
|
||||||
|
|
||||||
def cfg_zero_star(args):
|
|
||||||
guidance_scale = args['cond_scale']
|
|
||||||
x = args['input']
|
|
||||||
cond_p = args['cond_denoised']
|
|
||||||
uncond_p = args['uncond_denoised']
|
|
||||||
out = args["denoised"]
|
|
||||||
alpha = optimized_scale(x - cond_p, x - uncond_p)
|
|
||||||
|
|
||||||
return out + uncond_p * (alpha - 1.0) + guidance_scale * uncond_p * (1.0 - alpha)
|
|
||||||
|
|
||||||
m.set_model_sampler_post_cfg_function(cfg_zero_star)
|
|
||||||
return io.NodeOutput(m)
|
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
|
||||||
CFGNorm,
|
CFGNorm,
|
||||||
CFGZeroStar,
|
CFGZeroStar,
|
||||||
]
|
]
|
||||||
|
@ -4,6 +4,31 @@ import nodes
|
|||||||
from comfy_api.latest import io
|
from comfy_api.latest import io
|
||||||
|
|
||||||
|
|
||||||
|
class CLIPTextEncodeSDXLRefiner(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="CLIPTextEncodeSDXLRefiner_V3",
|
||||||
|
category="advanced/conditioning",
|
||||||
|
inputs=[
|
||||||
|
io.Float.Input("ascore", default=6.0, min=0.0, max=1000.0, step=0.01),
|
||||||
|
io.Int.Input("width", default=1024, min=0, max=nodes.MAX_RESOLUTION),
|
||||||
|
io.Int.Input("height", default=1024, min=0, max=nodes.MAX_RESOLUTION),
|
||||||
|
io.String.Input("text", multiline=True, dynamic_prompts=True),
|
||||||
|
io.Clip.Input("clip"),
|
||||||
|
],
|
||||||
|
outputs=[io.Conditioning.Output()],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, ascore, width, height, text, clip) -> io.NodeOutput:
|
||||||
|
tokens = clip.tokenize(text)
|
||||||
|
conditioning = clip.encode_from_tokens_scheduled(
|
||||||
|
tokens, add_dict={"aesthetic_score": ascore, "width": width, "height": height}
|
||||||
|
)
|
||||||
|
return io.NodeOutput(conditioning)
|
||||||
|
|
||||||
|
|
||||||
class CLIPTextEncodeSDXL(io.ComfyNode):
|
class CLIPTextEncodeSDXL(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
@ -48,32 +73,7 @@ class CLIPTextEncodeSDXL(io.ComfyNode):
|
|||||||
return io.NodeOutput(conditioning)
|
return io.NodeOutput(conditioning)
|
||||||
|
|
||||||
|
|
||||||
class CLIPTextEncodeSDXLRefiner(io.ComfyNode):
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="CLIPTextEncodeSDXLRefiner_V3",
|
|
||||||
category="advanced/conditioning",
|
|
||||||
inputs=[
|
|
||||||
io.Float.Input("ascore", default=6.0, min=0.0, max=1000.0, step=0.01),
|
|
||||||
io.Int.Input("width", default=1024, min=0, max=nodes.MAX_RESOLUTION),
|
|
||||||
io.Int.Input("height", default=1024, min=0, max=nodes.MAX_RESOLUTION),
|
|
||||||
io.String.Input("text", multiline=True, dynamic_prompts=True),
|
|
||||||
io.Clip.Input("clip"),
|
|
||||||
],
|
|
||||||
outputs=[io.Conditioning.Output()],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, ascore, width, height, text, clip) -> io.NodeOutput:
|
|
||||||
tokens = clip.tokenize(text)
|
|
||||||
conditioning = clip.encode_from_tokens_scheduled(
|
|
||||||
tokens, add_dict={"aesthetic_score": ascore, "width": width, "height": height}
|
|
||||||
)
|
|
||||||
return io.NodeOutput(conditioning)
|
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
|
||||||
CLIPTextEncodeSDXL,
|
CLIPTextEncodeSDXL,
|
||||||
CLIPTextEncodeSDXLRefiner,
|
CLIPTextEncodeSDXLRefiner,
|
||||||
]
|
]
|
||||||
|
@ -112,32 +112,6 @@ def porter_duff_composite(
|
|||||||
return out_image, out_alpha
|
return out_image, out_alpha
|
||||||
|
|
||||||
|
|
||||||
class JoinImageWithAlpha(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="JoinImageWithAlpha_V3",
|
|
||||||
display_name="Join Image with Alpha _V3",
|
|
||||||
category="mask/compositing",
|
|
||||||
inputs=[
|
|
||||||
io.Image.Input("image"),
|
|
||||||
io.Mask.Input("alpha"),
|
|
||||||
],
|
|
||||||
outputs=[io.Image.Output()],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, image: torch.Tensor, alpha: torch.Tensor) -> io.NodeOutput:
|
|
||||||
batch_size = min(len(image), len(alpha))
|
|
||||||
out_images = []
|
|
||||||
|
|
||||||
alpha = 1.0 - resize_mask(alpha, image.shape[1:])
|
|
||||||
for i in range(batch_size):
|
|
||||||
out_images.append(torch.cat((image[i][:, :, :3], alpha[i].unsqueeze(2)), dim=2))
|
|
||||||
|
|
||||||
return io.NodeOutput(torch.stack(out_images))
|
|
||||||
|
|
||||||
|
|
||||||
class PorterDuffImageComposite(io.ComfyNode):
|
class PorterDuffImageComposite(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
@ -219,7 +193,33 @@ class SplitImageWithAlpha(io.ComfyNode):
|
|||||||
return io.NodeOutput(torch.stack(out_images), 1.0 - torch.stack(out_alphas))
|
return io.NodeOutput(torch.stack(out_images), 1.0 - torch.stack(out_alphas))
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
class JoinImageWithAlpha(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="JoinImageWithAlpha_V3",
|
||||||
|
display_name="Join Image with Alpha _V3",
|
||||||
|
category="mask/compositing",
|
||||||
|
inputs=[
|
||||||
|
io.Image.Input("image"),
|
||||||
|
io.Mask.Input("alpha"),
|
||||||
|
],
|
||||||
|
outputs=[io.Image.Output()],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, image: torch.Tensor, alpha: torch.Tensor) -> io.NodeOutput:
|
||||||
|
batch_size = min(len(image), len(alpha))
|
||||||
|
out_images = []
|
||||||
|
|
||||||
|
alpha = 1.0 - resize_mask(alpha, image.shape[1:])
|
||||||
|
for i in range(batch_size):
|
||||||
|
out_images.append(torch.cat((image[i][:, :, :3], alpha[i].unsqueeze(2)), dim=2))
|
||||||
|
|
||||||
|
return io.NodeOutput(torch.stack(out_images))
|
||||||
|
|
||||||
|
|
||||||
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
JoinImageWithAlpha,
|
JoinImageWithAlpha,
|
||||||
PorterDuffImageComposite,
|
PorterDuffImageComposite,
|
||||||
SplitImageWithAlpha,
|
SplitImageWithAlpha,
|
||||||
|
@ -3,6 +3,33 @@ from comfy.cldm.control_types import UNION_CONTROLNET_TYPES
|
|||||||
from comfy_api.latest import io
|
from comfy_api.latest import io
|
||||||
|
|
||||||
|
|
||||||
|
class SetUnionControlNetType(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(
|
||||||
|
node_id="SetUnionControlNetType_V3",
|
||||||
|
category="conditioning/controlnet",
|
||||||
|
inputs=[
|
||||||
|
io.ControlNet.Input("control_net"),
|
||||||
|
io.Combo.Input("type", options=["auto"] + list(UNION_CONTROLNET_TYPES.keys())),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.ControlNet.Output(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, control_net, type) -> io.NodeOutput:
|
||||||
|
control_net = control_net.copy()
|
||||||
|
type_number = UNION_CONTROLNET_TYPES.get(type, -1)
|
||||||
|
if type_number >= 0:
|
||||||
|
control_net.set_extra_arg("control_type", [type_number])
|
||||||
|
else:
|
||||||
|
control_net.set_extra_arg("control_type", [])
|
||||||
|
|
||||||
|
return io.NodeOutput(control_net)
|
||||||
|
|
||||||
|
|
||||||
class ControlNetApplyAdvanced(io.ComfyNode):
|
class ControlNetApplyAdvanced(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
@ -60,33 +87,6 @@ class ControlNetApplyAdvanced(io.ComfyNode):
|
|||||||
return io.NodeOutput(out[0], out[1])
|
return io.NodeOutput(out[0], out[1])
|
||||||
|
|
||||||
|
|
||||||
class SetUnionControlNetType(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="SetUnionControlNetType_V3",
|
|
||||||
category="conditioning/controlnet",
|
|
||||||
inputs=[
|
|
||||||
io.ControlNet.Input("control_net"),
|
|
||||||
io.Combo.Input("type", options=["auto"] + list(UNION_CONTROLNET_TYPES.keys())),
|
|
||||||
],
|
|
||||||
outputs=[
|
|
||||||
io.ControlNet.Output(),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, control_net, type) -> io.NodeOutput:
|
|
||||||
control_net = control_net.copy()
|
|
||||||
type_number = UNION_CONTROLNET_TYPES.get(type, -1)
|
|
||||||
if type_number >= 0:
|
|
||||||
control_net.set_extra_arg("control_type", [type_number])
|
|
||||||
else:
|
|
||||||
control_net.set_extra_arg("control_type", [])
|
|
||||||
|
|
||||||
return io.NodeOutput(control_net)
|
|
||||||
|
|
||||||
|
|
||||||
class ControlNetInpaintingAliMamaApply(ControlNetApplyAdvanced):
|
class ControlNetInpaintingAliMamaApply(ControlNetApplyAdvanced):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
|
@ -9,6 +9,29 @@ import nodes
|
|||||||
from comfy_api.latest import io
|
from comfy_api.latest import io
|
||||||
|
|
||||||
|
|
||||||
|
class EmptyCosmosLatentVideo(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id="EmptyCosmosLatentVideo_V3",
|
||||||
|
category="latent/video",
|
||||||
|
inputs=[
|
||||||
|
io.Int.Input("width", default=1280, min=16, max=nodes.MAX_RESOLUTION, step=16),
|
||||||
|
io.Int.Input("height", default=704, min=16, max=nodes.MAX_RESOLUTION, step=16),
|
||||||
|
io.Int.Input("length", default=121, min=1, max=nodes.MAX_RESOLUTION, step=8),
|
||||||
|
io.Int.Input("batch_size", default=1, min=1, max=4096),
|
||||||
|
],
|
||||||
|
outputs=[io.Latent.Output()],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, width, height, length, batch_size) -> io.NodeOutput:
|
||||||
|
latent = torch.zeros(
|
||||||
|
[batch_size, 16, ((length - 1) // 8) + 1, height // 8, width // 8], device=comfy.model_management.intermediate_device()
|
||||||
|
)
|
||||||
|
return io.NodeOutput({"samples": latent})
|
||||||
|
|
||||||
|
|
||||||
def vae_encode_with_padding(vae, image, width, height, length, padding=0):
|
def vae_encode_with_padding(vae, image, width, height, length, padding=0):
|
||||||
pixels = comfy.utils.common_upscale(image[..., :3].movedim(-1, 1), width, height, "bilinear", "center").movedim(1, -1)
|
pixels = comfy.utils.common_upscale(image[..., :3].movedim(-1, 1), width, height, "bilinear", "center").movedim(1, -1)
|
||||||
pixel_len = min(pixels.shape[0], length)
|
pixel_len = min(pixels.shape[0], length)
|
||||||
@ -116,30 +139,7 @@ class CosmosPredict2ImageToVideoLatent(io.ComfyNode):
|
|||||||
return io.NodeOutput(out_latent)
|
return io.NodeOutput(out_latent)
|
||||||
|
|
||||||
|
|
||||||
class EmptyCosmosLatentVideo(io.ComfyNode):
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
||||||
@classmethod
|
|
||||||
def define_schema(cls) -> io.Schema:
|
|
||||||
return io.Schema(
|
|
||||||
node_id="EmptyCosmosLatentVideo_V3",
|
|
||||||
category="latent/video",
|
|
||||||
inputs=[
|
|
||||||
io.Int.Input("width", default=1280, min=16, max=nodes.MAX_RESOLUTION, step=16),
|
|
||||||
io.Int.Input("height", default=704, min=16, max=nodes.MAX_RESOLUTION, step=16),
|
|
||||||
io.Int.Input("length", default=121, min=1, max=nodes.MAX_RESOLUTION, step=8),
|
|
||||||
io.Int.Input("batch_size", default=1, min=1, max=4096),
|
|
||||||
],
|
|
||||||
outputs=[io.Latent.Output()],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, width, height, length, batch_size) -> io.NodeOutput:
|
|
||||||
latent = torch.zeros(
|
|
||||||
[batch_size, 16, ((length - 1) // 8) + 1, height // 8, width // 8], device=comfy.model_management.intermediate_device()
|
|
||||||
)
|
|
||||||
return io.NodeOutput({"samples": latent})
|
|
||||||
|
|
||||||
|
|
||||||
NODES_LIST = [
|
|
||||||
CosmosImageToVideoLatent,
|
CosmosImageToVideoLatent,
|
||||||
CosmosPredict2ImageToVideoLatent,
|
CosmosPredict2ImageToVideoLatent,
|
||||||
EmptyCosmosLatentVideo,
|
EmptyCosmosLatentVideo,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user