Migrated 4 nodes in "TenserTensor/Sampling" category to API V3 w/docs
This commit is contained in:
+10
-4
@@ -183,7 +183,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"TT_GgufModelsLoaderNode": TT_Flux2GgufModelsLoaderNode,
|
||||
"TT_GgufModelsLoaderAdvancedNode": TT_Flux2GgufModelsLoaderAdvancedNode,
|
||||
"TT_Sd35GgufModelsLoaderNode": TT_Sd35GgufModelsLoaderNode,
|
||||
# "TT_Sd35GgufModelsLoaderAdvancedNode": TT_Sd35GgufModelsLoaderAdvancedNode,
|
||||
"TT_Sd35GgufModelsLoaderAdvancedNode": TT_Sd35GgufModelsLoaderAdvancedNode,
|
||||
# Postproduction
|
||||
"TT_ApplyLut": TT_ApplyLut,
|
||||
"TT_AddFilmGrain": TT_AddFilmGrain,
|
||||
@@ -198,9 +198,12 @@ NODE_CLASS_MAPPINGS = {
|
||||
"TT_KSamplerTwoStage": TT_KSamplerTwoStage,
|
||||
"TT_KSamplerGuided": TT_KSamplerGuided,
|
||||
# Samplers V3 Nodes
|
||||
"TT_KSamplerNode": TT_KSamplerNode,
|
||||
"TT_KSamplerAdvancedNode": TT_KSamplerAdvancedNode,
|
||||
"TT_KSamplerContextNode": TT_KSamplerContextNode,
|
||||
"TT_KSamplerTwoStageNode": TT_KSamplerTwoStageNode,
|
||||
"TT_GuidedKSamplerNode": TT_GuidedKSamplerNode,
|
||||
"TT_GuidedUpscaleKSamplerNode": TT_GuidedUpscaleKSamplerNode,
|
||||
"TT_GuidedKSamplerWithPreviewNode": TT_GuidedKSamplerWithPreviewNode,
|
||||
# Text Encoder
|
||||
"TT_ClipTextEncodeFlux": TT_ClipTextEncodeFlux,
|
||||
"TT_ClipTextEncodeFluxContext": TT_ClipTextEncodeFluxContext,
|
||||
@@ -296,7 +299,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"TT_GgufModelsLoaderNode": "TT GGUF Models Loader",
|
||||
"TT_GgufModelsLoaderAdvancedNode": "TT GGUF Models Loader (Advanced)",
|
||||
"TT_Sd35GgufModelsLoaderNode": "TT SD3.5 GGUF Models Loader",
|
||||
# "TT_Sd35ModelsLoaderAdvancedNode": "TT SD3.5 GGUF Models Loader (Advanced)",
|
||||
"TT_Sd35ModelsLoaderAdvancedNode": "TT SD3.5 GGUF Models Loader (Advanced)",
|
||||
# Postproduction
|
||||
"TT_ApplyLut": "TT Apply LUT",
|
||||
"TT_AddFilmGrain": "TT Add Film Grain",
|
||||
@@ -311,9 +314,12 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"TT_KSamplerTwoStage": "TT KSampler (Two Stages)",
|
||||
"TT_KSamplerGuided": "TT KSampler (Guided)",
|
||||
# Samplers V3 Nodes
|
||||
"TT_KSamplerNode": "TT KSampler",
|
||||
"TT_KSamplerAdvancedNode": "TT KSampler (Advanced)",
|
||||
"TT_KSamplerContextNode": "TT KSampler (Context)",
|
||||
"TT_KSamplerTwoStageNode": "TT KSampler (Two Stage)",
|
||||
"TT_GuidedKSamplerNode": "TT Guided KSampler",
|
||||
"TT_GuidedUpscaleKSamplerNode": "TT Guided Upscale KSampler",
|
||||
"TT_GuidedKSamplerWithPreviewNode": "TT Guided KSampler (With Preview)",
|
||||
# Text Encoder
|
||||
"TT_ClipTextEncodeFlux": "TT CLIP Text Encode FLUX",
|
||||
"TT_ClipTextEncodeFluxContext": "TT CLIP Text Encode FLUX (Context)",
|
||||
|
||||
@@ -25,7 +25,7 @@ class TT_KSampler():
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("SAMPLES",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
CATEGORY = "TenserTensor/Deprecated/Sampling"
|
||||
|
||||
def execute_sampling(self, **kwargs):
|
||||
return (sample_latents(**kwargs),)
|
||||
|
||||
@@ -30,7 +30,7 @@ class TT_KSamplerAdvanced():
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("SAMPLES",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
CATEGORY = "TenserTensor/Deprecated/Sampling"
|
||||
|
||||
def execute_sampling(self, **kwargs):
|
||||
return (sample_latents(**kwargs),)
|
||||
|
||||
@@ -15,7 +15,7 @@ class TT_KSamplerContext():
|
||||
RETURN_TYPES = ("TT_CONTEXT", "LATENT",)
|
||||
RETURN_NAMES = ("CONTEXT", "SAMPLES",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
CATEGORY = "TenserTensor/Deprecated/Sampling"
|
||||
|
||||
def execute_sampling(self, context):
|
||||
model = context.get("model", None)
|
||||
|
||||
@@ -30,7 +30,7 @@ class TT_KSamplerTwoStage():
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("SAMPLES",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
CATEGORY = "TenserTensor/Deprecated/Sampling"
|
||||
|
||||
def execute_sampling(self, **kwargs):
|
||||
draft_steps = kwargs["draft_steps"]
|
||||
|
||||
+2
-2
@@ -786,7 +786,7 @@ class LoaderNodesExtension(ComfyExtension):
|
||||
TT_Flux2GgufModelsLoaderNode,
|
||||
TT_Flux2GgufModelsLoaderAdvancedNode,
|
||||
TT_Sd35GgufModelsLoaderNode,
|
||||
# TT_Sd35GgufModelsLoaderAdvancedNode,
|
||||
TT_Sd35GgufModelsLoaderAdvancedNode,
|
||||
]
|
||||
|
||||
|
||||
@@ -806,5 +806,5 @@ __all__ = [
|
||||
"TT_Flux2GgufModelsLoaderNode",
|
||||
"TT_Flux2GgufModelsLoaderAdvancedNode",
|
||||
"TT_Sd35GgufModelsLoaderNode",
|
||||
# "TT_Sd35GgufModelsLoaderAdvancedNode",
|
||||
"TT_Sd35GgufModelsLoaderAdvancedNode",
|
||||
]
|
||||
|
||||
+130
-2
@@ -2,7 +2,135 @@
|
||||
|
||||
from typing import override
|
||||
|
||||
from comfy_api.latest import ComfyExtension, IO
|
||||
from comfy_api.latest import ComfyExtension, io
|
||||
|
||||
CATEGORY = "TenserTensor/Postproduction"
|
||||
|
||||
|
||||
class TT_AddFilmGrainNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_AddFilmGrainNode",
|
||||
display_name="TT Add Film Grain",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_ApplyLutNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_ApplyLutNode",
|
||||
display_name="TT Apply LUT",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_ImageEnhancerNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_ImageEnhancerNode",
|
||||
display_name="TT Image Enhancer",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_QuickImageUpscalerNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_QuickImageUpscalerNode",
|
||||
display_name="TT Quick Image Upscaler",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_PostproductionNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_PostproductionNode",
|
||||
display_name="TT Postproduction",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_PostproductionAdvancedNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_PostproductionAdvancedNode",
|
||||
display_name="TT Postproduction (Advanced)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
@@ -11,7 +139,7 @@ from comfy_api.latest import ComfyExtension, IO
|
||||
|
||||
class PostproductionNodesExtension(ComfyExtension):
|
||||
@override
|
||||
async def get_node_list(self) -> list[type[IO.ComfyNode]]:
|
||||
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
||||
return [
|
||||
# TT_Node,
|
||||
]
|
||||
|
||||
+254
-31
@@ -2,15 +2,258 @@
|
||||
|
||||
from typing import override
|
||||
|
||||
import torch
|
||||
|
||||
import latent_preview
|
||||
from comfy import sample, model_management
|
||||
from comfy import sample, model_management, samplers
|
||||
from comfy_api.latest import ComfyExtension, io
|
||||
from .nodes_context import Context
|
||||
from .nodes_latent import SCALE_FACTORS, SCALE_METHODS, scale_latent
|
||||
from .nodes_text_encoder import SingleCondCFGGuider
|
||||
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
|
||||
|
||||
def do_sample(**kwargs):
|
||||
model = kwargs.get("model", None)
|
||||
if model is None:
|
||||
raise ValueError("Model is required for sampling")
|
||||
|
||||
latent = kwargs.get("latent", None)
|
||||
if latent is None:
|
||||
raise ValueError("Latent image is required for sampling")
|
||||
|
||||
latent_dict = latent.copy()
|
||||
samples, add_noise, seed, steps, device = (
|
||||
latent_dict["samples"],
|
||||
kwargs.get("add_noise", True),
|
||||
kwargs.get("seed", 0),
|
||||
kwargs.get("steps", 0),
|
||||
kwargs.get("device", "cpu")
|
||||
)
|
||||
latent_tensor = sample.fix_empty_latent_channels(model, samples, latent.get("downscale_ratio_spacial", None))
|
||||
|
||||
if add_noise:
|
||||
batch_idx = latent.get("batch_index", None)
|
||||
noise = sample.prepare_noise(samples, seed, batch_idx)
|
||||
else:
|
||||
noise = torch.zeros(samples.size(), dtype=samples.dtype, layout=samples.layout, device="cpu")
|
||||
|
||||
interim_buffer = {}
|
||||
if kwargs.get("preview_latent"):
|
||||
latent_preview.set_preview_method("latent2rgb")
|
||||
callback = latent_preview.prepare_callback(model, steps - 1, interim_buffer)
|
||||
else:
|
||||
callback = None
|
||||
|
||||
args = {
|
||||
"model": model,
|
||||
"noise": noise,
|
||||
"steps": steps,
|
||||
"cfg": kwargs.get("cfg"),
|
||||
"sampler_name": kwargs.get("sampler_name"),
|
||||
"scheduler": kwargs.get("scheduler"),
|
||||
"positive": kwargs.get("positive"),
|
||||
"negative": kwargs.get("negative"),
|
||||
"latent_image": latent_tensor,
|
||||
"denoise": kwargs.get("denoise", 1.0),
|
||||
"disable_noise": not add_noise,
|
||||
"start_step": kwargs.get("start_step"),
|
||||
"last_step": kwargs.get("last_step"),
|
||||
"force_full_denoise": kwargs.get("full_denoise", True),
|
||||
"noise_mask": latent.get("noise_mask"),
|
||||
"callback": callback,
|
||||
"seed": seed,
|
||||
}
|
||||
|
||||
samples = sample.sample(**args)
|
||||
sampled_latent = latent_dict.copy()
|
||||
sampled_latent.pop("downscale_ratio_spacial", None)
|
||||
sampled_latent["samples"] = samples
|
||||
|
||||
return sampled_latent
|
||||
|
||||
|
||||
class TT_KSamplerNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerNode",
|
||||
display_name="TT KSampler",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
io.Model.Input("model"),
|
||||
io.Conditioning.Input("positive"),
|
||||
io.Conditioning.Input("negative"),
|
||||
io.Latent.Input("latent"),
|
||||
io.Int.Input("seed", default=0, min=0, max=0xffffffffffffffff),
|
||||
io.Int.Input("steps", default=30, min=1, max=10_000),
|
||||
io.Float.Input("cfg", default=3.0, min=0.0, max=100.0, step=0.1),
|
||||
io.Combo.Input("sampler_name", options=samplers.KSampler.SAMPLERS),
|
||||
io.Combo.Input("scheduler", options=samplers.KSampler.SCHEDULERS),
|
||||
io.Boolean.Input("preview_latent", default=False, label_on="Show Preview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
io.Latent.Output("LATENT"),
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
latent = do_sample(**kwargs)
|
||||
|
||||
return io.NodeOutput(latent)
|
||||
|
||||
|
||||
class TT_KSamplerAdvancedNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerAdvancedNode",
|
||||
display_name="TT KSampler (Advanced)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
io.Model.Input("model"),
|
||||
io.Conditioning.Input("positive"),
|
||||
io.Conditioning.Input("negative"),
|
||||
io.Latent.Input("latent"),
|
||||
io.Boolean.Input("add_noise", default=False, label_on="Random Noise", label_off="Zero Noise"),
|
||||
io.Boolean.Input("full_denoise", default=False, label_on="Complete", label_off="Partial"),
|
||||
io.Float.Input("denoise", default=1.0, min=0.0, max=1.0, step=0.01),
|
||||
io.Int.Input("seed", default=0, min=0, max=0xffffffffffffffff),
|
||||
io.Int.Input("steps", default=30, min=1, max=10_000),
|
||||
io.Float.Input("cfg", default=3.0, min=0.0, max=100.0, step=0.1),
|
||||
io.Int.Input("start_step", default=0, min=0, max=10_000),
|
||||
io.Int.Input("last_step", default=10_000, min=0, max=10_000),
|
||||
io.Combo.Input("sampler_name", options=samplers.KSampler.SAMPLERS),
|
||||
io.Combo.Input("scheduler", options=samplers.KSampler.SCHEDULERS),
|
||||
io.Boolean.Input("preview_latent", default=False, label_on="Show Preview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
io.Latent.Output("LATENT"),
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
latent = do_sample(**kwargs)
|
||||
|
||||
return io.NodeOutput(latent)
|
||||
|
||||
|
||||
class TT_KSamplerContextNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerContextNode",
|
||||
display_name="TT KSampler (Context)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
Context.Input("context"),
|
||||
io.Boolean.Input("preview_latent", default=False, label_on="Show Preview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
Context.Output("CONTEXT"),
|
||||
io.Latent.Output("LATENT"),
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, context) -> io.NodeOutput:
|
||||
model = context.get("model")
|
||||
if model is None:
|
||||
raise ValueError("Model is required for sampling")
|
||||
|
||||
latent = context.get("latent")
|
||||
if latent is None:
|
||||
raise ValueError("Latent image is required for sampling")
|
||||
|
||||
config = context.get("workflow_config")
|
||||
if config is None:
|
||||
raise ValueError("Workflow Config is required for sampling")
|
||||
|
||||
args = {
|
||||
"model": model,
|
||||
"positive": context.get_attr("positive"),
|
||||
"negative": context.get_attr("negative"),
|
||||
"latent": latent,
|
||||
"seed": config.get_attr("seed"),
|
||||
"steps": config.get_attr("steps"),
|
||||
"cfg": config.get_attr("cfg"),
|
||||
"sampler_name": config.get_attr("sampler_name"),
|
||||
"scheduler": config.get_attr("scheduler"),
|
||||
}
|
||||
latent = do_sample(**args)
|
||||
context.set_attr("latent", latent)
|
||||
|
||||
return io.NodeOutput(context, latent)
|
||||
|
||||
|
||||
class TT_KSamplerTwoStageNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerTwoStageNode",
|
||||
display_name="TT KSampler (Two Stage)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
io.Model.Input("model"),
|
||||
io.Conditioning.Input("positive"),
|
||||
io.Conditioning.Input("negative"),
|
||||
io.Latent.Input("latent"),
|
||||
io.Int.Input("seed", default=0, min=0, max=0xffffffffffffffff),
|
||||
io.Float.Input("cfg", default=3.0, min=0.0, max=100.0, step=0.1),
|
||||
io.Int.Input("draft_steps", default=25, min=1, max=10_000),
|
||||
io.Int.Input("refiner_steps", default=25, min=1, max=10_000),
|
||||
io.Combo.Input("draft_sampler_name", options=samplers.KSampler.SAMPLERS),
|
||||
io.Combo.Input("draft_scheduler", options=samplers.KSampler.SCHEDULERS),
|
||||
io.Combo.Input("refiner_sampler_name", options=samplers.KSampler.SAMPLERS),
|
||||
io.Combo.Input("refiner_scheduler", options=samplers.KSampler.SCHEDULERS),
|
||||
io.Float.Input("draft_denoise", default=1.0, min=0.0, max=1.0, step=0.01),
|
||||
io.Float.Input("refiner_denoise", default=1.0, min=0.0, max=1.0, step=0.01),
|
||||
io.Boolean.Input("preview_latent", default=False, label_on="Show Preview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
io.Latent.Output("LATENT"),
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
draft_steps = kwargs["draft_steps"]
|
||||
refiner_steps = kwargs["refiner_steps"]
|
||||
|
||||
args = kwargs.copy()
|
||||
args.update({
|
||||
"steps": draft_steps,
|
||||
"start_step": 0,
|
||||
"add_noise": True,
|
||||
"sampler_name": kwargs["draft_sampler_name"],
|
||||
"scheduler": kwargs["draft_scheduler"],
|
||||
"full_denoise": False,
|
||||
"denoise": kwargs["draft_denoise"],
|
||||
})
|
||||
latent = do_sample(**args)
|
||||
|
||||
args.update({
|
||||
"latent": latent,
|
||||
"steps": draft_steps + refiner_steps,
|
||||
"start_step": draft_steps,
|
||||
"add_noise": True,
|
||||
"sampler_name": kwargs["refiner_sampler_name"],
|
||||
"scheduler": kwargs["refiner_scheduler"],
|
||||
"full_denoise": True,
|
||||
"denoise": kwargs["refiner_denoise"],
|
||||
})
|
||||
latent = do_sample(**args)
|
||||
|
||||
return io.NodeOutput(latent)
|
||||
|
||||
|
||||
def execute_guided_sampling(**kwargs):
|
||||
guider, latent, sigmas, random_noise, sampler, preview_latent = (
|
||||
kwargs.get("guider"),
|
||||
@@ -73,6 +316,7 @@ class TT_GuidedKSamplerNode(io.ComfyNode):
|
||||
io.Sigmas.Input("sigmas"),
|
||||
io.Sampler.Input("sampler"),
|
||||
io.Noise.Input("random_noise"),
|
||||
io.Boolean.Input("preview_latent", default=False, label_on="Show Preview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
io.Latent.Output("SAMPLES")
|
||||
@@ -103,6 +347,7 @@ class TT_GuidedUpscaleKSamplerNode(io.ComfyNode):
|
||||
io.Boolean.Input("scale_latent", default=False, label_on="Scale", label_off="Skip"),
|
||||
io.Combo.Input("scale_factor", options=SCALE_FACTORS, default="1x", advanced=True),
|
||||
io.Combo.Input("scale_method", options=SCALE_METHODS, default="bicubic", advanced=True),
|
||||
io.Boolean.Input("preview_latent", default=False, label_on="Show Preview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
io.Latent.Output("SAMPLES")
|
||||
@@ -119,34 +364,6 @@ class TT_GuidedUpscaleKSamplerNode(io.ComfyNode):
|
||||
return io.NodeOutput(samples)
|
||||
|
||||
|
||||
class TT_GuidedKSamplerWithPreviewNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_GuidedKSamplerWithPreviewNode",
|
||||
display_name="TT Guided KSampler (With Preview)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
io.Latent.Input("latent"),
|
||||
io.Guider.Input("guider"),
|
||||
io.Sigmas.Input("sigmas"),
|
||||
io.Sampler.Input("sampler"),
|
||||
io.Noise.Input("random_noise"),
|
||||
io.Boolean.Input("preview_latent", default=True, label_on="Show Peview", label_off="Only Sample"),
|
||||
],
|
||||
outputs=[
|
||||
io.Latent.Output("SAMPLES")
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
samples = execute_guided_sampling(**kwargs)
|
||||
|
||||
return io.NodeOutput(samples)
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# V3 entrypoint — registers context nodes with ComfyUI
|
||||
# ==============================================================================
|
||||
@@ -155,9 +372,12 @@ class SamplingNodesExtension(ComfyExtension):
|
||||
@override
|
||||
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
||||
return [
|
||||
TT_KSamplerNode,
|
||||
TT_KSamplerAdvancedNode,
|
||||
TT_KSamplerContextNode,
|
||||
TT_KSamplerTwoStageNode,
|
||||
TT_GuidedKSamplerNode,
|
||||
TT_GuidedUpscaleKSamplerNode,
|
||||
TT_GuidedKSamplerWithPreviewNode,
|
||||
]
|
||||
|
||||
|
||||
@@ -170,7 +390,10 @@ async def comfy_entrypoint() -> SamplingNodesExtension:
|
||||
# ==============================================================================
|
||||
|
||||
__all__ = [
|
||||
"TT_KSamplerNode",
|
||||
"TT_KSamplerAdvancedNode",
|
||||
"TT_KSamplerContextNode",
|
||||
"TT_KSamplerTwoStageNode",
|
||||
"TT_GuidedKSamplerNode",
|
||||
"TT_GuidedUpscaleKSamplerNode",
|
||||
"TT_GuidedKSamplerWithPreviewNode",
|
||||
]
|
||||
|
||||
+87
-1
@@ -4,7 +4,9 @@ from typing import override
|
||||
|
||||
import torch
|
||||
|
||||
from comfy_api.latest import IO, ComfyExtension
|
||||
from comfy_api.latest import io, ComfyExtension
|
||||
|
||||
CATEGORY="TenserTensor/VAE"
|
||||
|
||||
TILE_SIZE, OVERLAP = 512, 64
|
||||
|
||||
@@ -34,6 +36,90 @@ def vae_decode(latent, vae, tile_width=TILE_SIZE, tile_height=TILE_SIZE, overlap
|
||||
return images
|
||||
|
||||
|
||||
class TT_KSamplerNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerNode",
|
||||
display_name="TT_KSampler",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_KSamplerAdvancedNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerAdvancedNode",
|
||||
display_name="TT_KSampler (Advanced)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_KSamplerContextNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerContextNode",
|
||||
display_name="TT_KSampler (Context)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TT_KSamplerTwoStageNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="TT_KSamplerTwoStageNode",
|
||||
display_name="TT_KSampler (Two Stage)",
|
||||
category=CATEGORY,
|
||||
description="",
|
||||
inputs=[
|
||||
|
||||
],
|
||||
outputs=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs) -> io.NodeOutput:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# V3 entrypoint — registers context nodes with ComfyUI
|
||||
# ==============================================================================
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
## TT KSampler (Advanced) *TT_KSamplerAdvancedNode*
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Extended KSampler with fine-grained control over noise, denoising range, and step boundaries. Useful for multi-stage workflows and img2img.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|------------------|--------------|----------|---------------------------------------------------------|
|
||||
| `model` | MODEL | Yes | Diffusion model |
|
||||
| `positive` | CONDITIONING | Yes | Positive conditioning |
|
||||
| `negative` | CONDITIONING | Yes | Negative conditioning |
|
||||
| `latent` | LATENT | Yes | Input latent tensor |
|
||||
| `add_noise` | BOOLEAN | Yes | Random Noise — use random noise; Zero Noise — use zeros |
|
||||
| `full_denoise` | BOOLEAN | Yes | Complete — force full denoise; Partial — stop early |
|
||||
| `denoise` | FLOAT | Yes | Denoising strength, default 1.0 |
|
||||
| `seed` | INT | Yes | Generation seed |
|
||||
| `steps` | INT | Yes | Total number of sampling steps, default 30 |
|
||||
| `cfg` | FLOAT | Yes | Guidance scale, default 3.0 |
|
||||
| `start_step` | INT | No | Step to start sampling from, default 0 |
|
||||
| `last_step` | INT | No | Step to stop sampling at, default 10000 |
|
||||
| `sampler_name` | COMBO | Yes | Sampler algorithm |
|
||||
| `scheduler` | COMBO | Yes | Noise schedule |
|
||||
| `preview_latent` | BOOLEAN | No | Show step-by-step latent preview during sampling |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|-----------------------|
|
||||
| `LATENT` | LATENT | Sampled latent tensor |
|
||||
|
||||
### Usage
|
||||
|
||||
Use `start_step` and `last_step` to run only a portion of the schedule — useful for chaining two samplers in a draft/refine workflow. Set `add_noise`
|
||||
to Zero Noise when passing a pre-noised latent from a previous stage.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -0,0 +1,29 @@
|
||||
## TT KSampler (Context) *TT_KSamplerContextNode*
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Context-based KSampler that reads all sampling parameters from a connected context object. Designed for use in context-driven pipelines where model,
|
||||
latent, and workflow config are passed as a single object.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|------------------|---------|----------|----------------------------------------------------------|
|
||||
| `context` | CONTEXT | Yes | Pipeline context with model, latent, and workflow config |
|
||||
| `preview_latent` | BOOLEAN | No | Show step-by-step latent preview during sampling |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|---------|-------------------------------------|
|
||||
| `CONTEXT` | CONTEXT | Updated context with sampled latent |
|
||||
| `LATENT` | LATENT | Sampled latent tensor |
|
||||
|
||||
### Usage
|
||||
|
||||
Connect a context output from a workflow settings or text encoder node. The node reads `model`, `latent`, `seed`, `steps`, `cfg`, `sampler_name`, and
|
||||
`scheduler` from the context automatically. Sampled latent is written back into the context for downstream nodes.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -0,0 +1,35 @@
|
||||
## TT KSampler *TT_KSamplerNode*
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Standard KSampler node with built-in latent preview support. Accepts model, conditioning, and latent as separate inputs.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|------------------|--------------|----------|--------------------------------------------------|
|
||||
| `model` | MODEL | Yes | Diffusion model |
|
||||
| `positive` | CONDITIONING | Yes | Positive conditioning |
|
||||
| `negative` | CONDITIONING | Yes | Negative conditioning |
|
||||
| `latent` | LATENT | Yes | Input latent tensor |
|
||||
| `seed` | INT | Yes | Generation seed |
|
||||
| `steps` | INT | Yes | Number of sampling steps, default 30 |
|
||||
| `cfg` | FLOAT | Yes | Guidance scale, default 3.0 |
|
||||
| `sampler_name` | COMBO | Yes | Sampler algorithm |
|
||||
| `scheduler` | COMBO | Yes | Noise schedule |
|
||||
| `preview_latent` | BOOLEAN | No | Show step-by-step latent preview during sampling |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|-----------------------|
|
||||
| `LATENT` | LATENT | Sampled latent tensor |
|
||||
|
||||
### Usage
|
||||
|
||||
Connect `MODEL`, `CONDITIONING`, and `LATENT` outputs from loader and encoder nodes. Enable `preview_latent` to see intermediate results during
|
||||
sampling.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -0,0 +1,41 @@
|
||||
## TT KSampler (Two Stage) *TT_KSamplerTwoStageNode*
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Runs sampling in two sequential stages — draft and refine — in a single node. Draft stage generates a rough result, refine stage continues from where
|
||||
draft stopped with different sampler settings.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|------------------------|--------------|----------|--------------------------------------------------|
|
||||
| `model` | MODEL | Yes | Diffusion model |
|
||||
| `positive` | CONDITIONING | Yes | Positive conditioning |
|
||||
| `negative` | CONDITIONING | Yes | Negative conditioning |
|
||||
| `latent` | LATENT | Yes | Input latent tensor |
|
||||
| `seed` | INT | Yes | Generation seed |
|
||||
| `cfg` | FLOAT | Yes | Guidance scale, default 3.0 |
|
||||
| `draft_steps` | INT | Yes | Number of draft stage steps, default 25 |
|
||||
| `refiner_steps` | INT | Yes | Number of refine stage steps, default 25 |
|
||||
| `draft_sampler_name` | COMBO | Yes | Sampler algorithm for draft stage |
|
||||
| `draft_scheduler` | COMBO | Yes | Noise schedule for draft stage |
|
||||
| `refiner_sampler_name` | COMBO | Yes | Sampler algorithm for refine stage |
|
||||
| `refiner_scheduler` | COMBO | Yes | Noise schedule for refine stage |
|
||||
| `draft_denoise` | FLOAT | No | Denoising strength for draft stage, default 1.0 |
|
||||
| `refiner_denoise` | FLOAT | No | Denoising strength for refine stage, default 1.0 |
|
||||
| `preview_latent` | BOOLEAN | No | Show step-by-step latent preview during sampling |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|-----------------------|
|
||||
| `LATENT` | LATENT | Sampled latent tensor |
|
||||
|
||||
### Usage
|
||||
|
||||
Use different samplers and schedulers for each stage — for example, `dpmpp_2m` with `karras` for draft and `euler` with `normal` for refine. Total
|
||||
steps equal `draft_steps + refiner_steps`.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
Reference in New Issue
Block a user