Add sampler nodes with documentation
Implement sampling nodes: - ksampler.py: standard sampler with basic parameters - ksampler_advanced.py: advanced sampler with step control and noise settings - ksampler_context.py: context-based sampler extracting parameters from workflow context - ksampler_two_stage.py: automated two-stage sampling (draft + refinement) Add markdown documentation for all sampler nodes
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
__pycache__/
|
||||
_tmp/
|
||||
.idea/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
+14
@@ -7,6 +7,10 @@ from .nodes.context.large_context_sdxl import TT_LargeContextSdxl
|
||||
from .nodes.latent.latent_factory import TT_LatentFactory
|
||||
from .nodes.loaders.sdxl_models_loader import TT_SdxlModelsLoader
|
||||
from .nodes.loaders.sdxl_models_loader_advanced import TT_SdxlModelsLoaderAdvanced
|
||||
from .nodes.sampling.ksampler import TT_KSampler
|
||||
from .nodes.sampling.ksampler_advanced import TT_KSamplerAdvanced
|
||||
from .nodes.sampling.ksampler_context import TT_KSamplerContext
|
||||
from .nodes.sampling.ksampler_two_stage import TT_KSamplerTwoStage
|
||||
from .nodes.workflow.flux_workfow_settings import TT_FluxWorkflowSettings
|
||||
from .nodes.workflow.flux_workfow_settings_advanced import TT_FluxWorkflowSettingsAdvanced
|
||||
from .nodes.workflow.sdxl_workfow_settings import TT_SdxlWorkflowSettings
|
||||
@@ -26,6 +30,11 @@ NODE_CLASS_MAPPINGS = {
|
||||
# Loaders
|
||||
"TT_SdxlModelsLoader": TT_SdxlModelsLoader,
|
||||
"TT_SdxlModelsLoaderAdvanced": TT_SdxlModelsLoaderAdvanced,
|
||||
# Samplers
|
||||
"TT_KSampler": TT_KSampler,
|
||||
"TT_KSamplerAdvanced": TT_KSamplerAdvanced,
|
||||
"TT_KSamplerContext": TT_KSamplerContext,
|
||||
"TT_KSamplerTwoStage": TT_KSamplerTwoStage,
|
||||
# Workflow
|
||||
"TT_FluxWorkflowSettings": TT_FluxWorkflowSettings,
|
||||
"TT_FluxWorkflowSettingsAdvanced": TT_FluxWorkflowSettingsAdvanced,
|
||||
@@ -47,6 +56,11 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
# Loaders
|
||||
"TT_SdxlModelsLoader": "TT SDXL Models Loader",
|
||||
"TT_SdxlModelsLoaderAdvanced": "TT SDXL Models Loader (Advanced)",
|
||||
# Samplers
|
||||
"TT_KSampler": "TT KSampler",
|
||||
"TT_KSamplerAdvanced": "TT KSampler (Advanced)",
|
||||
"TT_KSamplerContext": "TT KSampler (Context)",
|
||||
"TT_KSamplerTwoStage": "TT KSampler (Two Stages)",
|
||||
# Workflow
|
||||
"TT_FluxWorkflowSettings": "TT FLUX Workflow Settings",
|
||||
"TT_FluxWorkflowSettingsAdvanced": "TT FLUX Workflow Settings (Advanced)",
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import comfy.samplers
|
||||
|
||||
from .ksampler_helpers import sample_latents
|
||||
|
||||
|
||||
class TT_KSampler():
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"positive": ("CONDITIONING",),
|
||||
"negative": ("CONDITIONING",),
|
||||
"latent": ("LATENT",),
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||
"steps": ("INT", {"default": 25, "min": 1, "max": 10000}),
|
||||
"cfg": ("FLOAT", {"default": 1.5, "min": 0.0, "max": 100.0, "step": 0.1}),
|
||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
|
||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("LATENT",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
|
||||
def execute_sampling(self, **kwargs):
|
||||
return (sample_latents(**kwargs),)
|
||||
@@ -0,0 +1,34 @@
|
||||
import comfy.samplers
|
||||
|
||||
from .ksampler_helpers import sample_latents
|
||||
|
||||
|
||||
class TT_KSamplerAdvanced():
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"positive": ("CONDITIONING",),
|
||||
"negative": ("CONDITIONING",),
|
||||
"latent": ("LATENT",),
|
||||
"add_noise": ("BOOLEAN", {"default": True, "label_on": "Enabled", "label_off": "Disabled"}),
|
||||
"full_denoise": ("BOOLEAN", {"default": False, "label_on": "Enabled", "label_off": "Disabled"}),
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||
"steps": ("INT", {"default": 25, "min": 1, "max": 10000}),
|
||||
"start_step": ("INT", {"default": 0, "min": 0, "max": 10000}),
|
||||
"last_step": ("INT", {"default": 10000, "min": 0, "max": 10000}),
|
||||
"cfg": ("FLOAT", {"default": 1.5, "min": 0.0, "max": 100.0, "step": 0.1}),
|
||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
|
||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
|
||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("LATENT",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
|
||||
def execute_sampling(self, **kwargs):
|
||||
return (sample_latents(**kwargs),)
|
||||
@@ -0,0 +1,44 @@
|
||||
from .ksampler_helpers import sample_latents
|
||||
|
||||
|
||||
class TT_KSamplerContext():
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"context": ("TT_CONTEXT",)
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("TT_CONTEXT", "LATENT",)
|
||||
RETURN_NAMES = ("CONTEXT", "LATENT",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
|
||||
def execute_sampling(self, context):
|
||||
model = context.get("model", None)
|
||||
latent = context.get("latent", None)
|
||||
config = context.get("workflow_config", None)
|
||||
|
||||
if model is None:
|
||||
raise ValueError("Model is required for sampling")
|
||||
if latent is None:
|
||||
raise ValueError("Latent image is required for sampling")
|
||||
if config is None:
|
||||
raise ValueError("Workflow Config is required for sampling")
|
||||
|
||||
args = {
|
||||
"model": model,
|
||||
"positive": context.get("positive", None),
|
||||
"negative": context.get("negative", None),
|
||||
"latent": latent,
|
||||
"seed": config.get("seed", 0),
|
||||
"steps": config.get("steps", 0),
|
||||
"cfg": config.get("cfg", 0),
|
||||
"sampler_name": config.get("sampler_name", None),
|
||||
"scheduler": config.get("scheduler", None),
|
||||
}
|
||||
|
||||
samples = sample_latents(**args)
|
||||
|
||||
return (context, samples)
|
||||
@@ -0,0 +1,55 @@
|
||||
import comfy
|
||||
import latent_preview
|
||||
import torch
|
||||
|
||||
|
||||
def sample_latents(**kwargs):
|
||||
model = kwargs.get("model", None)
|
||||
latent = kwargs.get("latent", None)
|
||||
|
||||
if model is None:
|
||||
raise ValueError("Model is required for sampling")
|
||||
if latent is None:
|
||||
raise ValueError("Latent image is required for sampling")
|
||||
|
||||
steps = kwargs.get("steps", 0)
|
||||
seed = kwargs.get("seed", 0)
|
||||
|
||||
latent_img = comfy.sample.fix_empty_latent_channels(model, latent["samples"])
|
||||
|
||||
add_noise = kwargs.get("add_noise", True)
|
||||
if add_noise:
|
||||
bat_idx = latent.get("batch_index", None)
|
||||
noise = comfy.sample.prepare_noise(latent_img, seed, bat_idx)
|
||||
else:
|
||||
noise = torch.zeros(latent_img.size(), dtype=latent_img.dtype, layout=latent_img.layout, device="cpu")
|
||||
|
||||
callback = latent_preview.prepare_callback(model, steps)
|
||||
|
||||
args = {
|
||||
"model": model,
|
||||
"noise": noise,
|
||||
"steps": steps,
|
||||
"cfg": kwargs.get("cfg", 0),
|
||||
"sampler_name": kwargs.get("sampler_name", None),
|
||||
"scheduler": kwargs.get("scheduler", None),
|
||||
"positive": kwargs.get("positive", None),
|
||||
"negative": kwargs.get("negative", None),
|
||||
"latent_image": latent_img,
|
||||
"denoise": kwargs.get("denoise", 1.0),
|
||||
"disable_noise": not add_noise,
|
||||
"start_step": kwargs.get("start_step", 0),
|
||||
"last_step": kwargs.get("last_step", 10000),
|
||||
"force_full_denoise": kwargs.get("full_denoise", True),
|
||||
"noise_mask": latent.get("noise_mask", None),
|
||||
"disable_pbar": not comfy.utils.PROGRESS_BAR_ENABLED,
|
||||
"callback": callback,
|
||||
"seed": seed,
|
||||
}
|
||||
|
||||
samples = comfy.sample.sample(**args)
|
||||
|
||||
retval = latent.copy()
|
||||
retval["samples"] = samples
|
||||
|
||||
return retval
|
||||
@@ -0,0 +1,63 @@
|
||||
import comfy.samplers
|
||||
|
||||
from .ksampler_helpers import sample_latents
|
||||
|
||||
|
||||
class TT_KSamplerTwoStage():
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"positive": ("CONDITIONING",),
|
||||
"negative": ("CONDITIONING",),
|
||||
"latent": ("LATENT",),
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||
"cfg": ("FLOAT", {"default": 1.5, "min": 0.0, "max": 100.0, "step": 0.1}),
|
||||
"draft_steps": ("INT", {"default": 25, "min": 1, "max": 10000}),
|
||||
"refiner_steps": ("INT", {"default": 25, "min": 1, "max": 10000}),
|
||||
"draft_sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
|
||||
"draft_scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
|
||||
"refiner_sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
|
||||
"refiner_scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
|
||||
"draft_denoise": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"refiner_denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("LATENT",)
|
||||
FUNCTION = "execute_sampling"
|
||||
CATEGORY = "TenserTensor/Sampling"
|
||||
|
||||
def execute_sampling(self, **kwargs):
|
||||
draft_steps = kwargs["draft_steps"]
|
||||
refiner_steps = kwargs["refiner_steps"]
|
||||
|
||||
args = {
|
||||
"model": kwargs["model"],
|
||||
"positive": kwargs["positive"],
|
||||
"negative": kwargs["negative"],
|
||||
"latent": kwargs["latent"],
|
||||
"seed": kwargs["seed"],
|
||||
"steps": draft_steps,
|
||||
"start_step": 0,
|
||||
"cfg": kwargs["cfg"],
|
||||
"sampler_name": kwargs["draft_sampler_name"],
|
||||
"scheduler": kwargs["draft_scheduler"],
|
||||
"add_noise": True,
|
||||
"full_denoise": False,
|
||||
"denoise": kwargs["refiner_denoise"],
|
||||
}
|
||||
|
||||
samples = sample_latents(**args)
|
||||
|
||||
args["latent"] = samples
|
||||
args["steps"] = draft_steps + refiner_steps
|
||||
args["start_step"] = draft_steps
|
||||
args["denoise"] = kwargs["draft_denoise"]
|
||||
args["sampler_name"] = kwargs["refiner_sampler_name"]
|
||||
args["scheduler"] = kwargs["refiner_scheduler"]
|
||||
args["full_denoise"] = True
|
||||
|
||||
return (sample_latents(**args),)
|
||||
@@ -0,0 +1,34 @@
|
||||
## TT_KSampler
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Standard sampler node for generating images from latents.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|----------------|--------------|----------|-----------------------------------------------------------|
|
||||
| `model` | MODEL | Yes | The diffusion model to use for sampling |
|
||||
| `positive` | CONDITIONING | Yes | Positive conditioning (what to generate) |
|
||||
| `negative` | CONDITIONING | Yes | Negative conditioning (what to avoid) |
|
||||
| `latent` | LATENT | Yes | Latent image to denoise |
|
||||
| `seed` | INT | Yes | Random seed for reproducibility (0 to 2^64-1, default: 0) |
|
||||
| `steps` | INT | Yes | Number of sampling steps (1-10000, default: 25) |
|
||||
| `cfg` | FLOAT | Yes | Classifier-free guidance scale (0.0-100.0, default: 1.5) |
|
||||
| `sampler_name` | SAMPLER | Yes | Sampler algorithm to use |
|
||||
| `scheduler` | SCHEDULER | Yes | Noise schedule to use |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|-----------------------|
|
||||
| `LATENT` | LATENT | Denoised latent image |
|
||||
|
||||
### Usage
|
||||
|
||||
Standard KSampler for generating images. Accepts all common sampling parameters and returns a denoised latent ready for
|
||||
VAE decoding.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -0,0 +1,40 @@
|
||||
## TT_KSamplerAdvanced
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Advanced sampler with fine-grained control over denoising steps and noise addition.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|----------------|--------------|----------|-----------------------------------------------------------|
|
||||
| `model` | MODEL | Yes | The diffusion model to use for sampling |
|
||||
| `positive` | CONDITIONING | Yes | Positive conditioning (what to generate) |
|
||||
| `negative` | CONDITIONING | Yes | Negative conditioning (what to avoid) |
|
||||
| `latent` | LATENT | Yes | Latent image to denoise |
|
||||
| `add_noise` | BOOLEAN | Yes | Add noise before sampling (default: True) |
|
||||
| `full_denoise` | BOOLEAN | Yes | Complete full denoising (default: False) |
|
||||
| `seed` | INT | Yes | Random seed for reproducibility (0 to 2^64-1, default: 0) |
|
||||
| `steps` | INT | Yes | Total number of sampling steps (1-10000, default: 25) |
|
||||
| `start_step` | INT | Yes | Step to start sampling from (0-10000, default: 0) |
|
||||
| `last_step` | INT | Yes | Step to end sampling at (0-10000, default: 10000) |
|
||||
| `cfg` | FLOAT | Yes | Classifier-free guidance scale (0.0-100.0, default: 1.5) |
|
||||
| `sampler_name` | SAMPLER | Yes | Sampler algorithm to use |
|
||||
| `scheduler` | SCHEDULER | Yes | Noise schedule to use |
|
||||
| `denoise` | FLOAT | Yes | Denoising strength (0.0-1.0, default: 1.0) |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|-----------------------|
|
||||
| `LATENT` | LATENT | Denoised latent image |
|
||||
|
||||
### Usage
|
||||
|
||||
Advanced sampler for multi-stage workflows and fine control. Use start_step/last_step for partial denoising, add_noise
|
||||
to control noise injection, and denoise for strength control. Useful for img2img, refinement passes, and complex
|
||||
sampling workflows.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -0,0 +1,29 @@
|
||||
## TT_KSamplerContext
|
||||
|
||||
Context-based sampler that extracts parameters from workflow context.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------------|----------|---------------------------------------------------------------------|
|
||||
| `context` | TT_CONTEXT | Yes | Context containing model, latent, conditioning, and workflow config |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------------|-----------------------|
|
||||
| `CONTEXT` | TT_CONTEXT | Pass-through context |
|
||||
| `LATENT` | LATENT | Denoised latent image |
|
||||
|
||||
### Usage
|
||||
|
||||
Simplified sampler for context-based workflows. Automatically extracts all sampling parameters from the context object:
|
||||
|
||||
- Model, positive/negative conditioning, and latent from context
|
||||
- Seed, steps, cfg, sampler_name, and scheduler from workflow_config
|
||||
|
||||
Requires context to contain: model, latent, and workflow_config. Raises error if any required component is missing.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -0,0 +1,38 @@
|
||||
## TT_KSamplerTwoStage
|
||||
|
||||
Two-stage sampler with separate draft and refinement passes.
|
||||
|
||||
### Inputs
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|------------------------|--------------|----------|------------------------------------------------------------|
|
||||
| `model` | MODEL | Yes | The diffusion model to use for sampling |
|
||||
| `positive` | CONDITIONING | Yes | Positive conditioning (what to generate) |
|
||||
| `negative` | CONDITIONING | Yes | Negative conditioning (what to avoid) |
|
||||
| `latent` | LATENT | Yes | Latent image to denoise |
|
||||
| `seed` | INT | Yes | Random seed for reproducibility (0 to 2^64-1, default: 0) |
|
||||
| `cfg` | FLOAT | Yes | Classifier-free guidance scale (0.0-100.0, default: 1.5) |
|
||||
| `draft_steps` | INT | Yes | Number of steps for draft pass (1-10000, default: 25) |
|
||||
| `refiner_steps` | INT | Yes | Number of steps for refinement pass (1-10000, default: 25) |
|
||||
| `draft_sampler_name` | SAMPLER | Yes | Sampler algorithm for draft pass |
|
||||
| `draft_scheduler` | SCHEDULER | Yes | Noise schedule for draft pass |
|
||||
| `refiner_sampler_name` | SAMPLER | Yes | Sampler algorithm for refinement pass |
|
||||
| `refiner_scheduler` | SCHEDULER | Yes | Noise schedule for refinement pass |
|
||||
| `draft_denoise` | FLOAT | Yes | Denoising strength for draft (0.0-1.0, default: 0.7) |
|
||||
| `refiner_denoise` | FLOAT | Yes | Denoising strength for refinement (0.0-1.0, default: 1.0) |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|-----------------------------------------|
|
||||
| `LATENT` | LATENT | Fully denoised latent after both passes |
|
||||
|
||||
### Usage
|
||||
|
||||
Automated two-stage sampling workflow. First performs a draft pass with partial denoising, then refines the result with
|
||||
a second pass. Each stage can use different samplers, schedulers, and step counts. Useful for quick previews followed by
|
||||
quality refinement, or combining different sampling strategies.
|
||||
|
||||
---
|
||||
|
||||
[View on GitHub](https://github.com/tenser-tensor/ComfyUI-TenserTensor)
|
||||
@@ -1,5 +1,7 @@
|
||||
## TT_SdxlModelsLoader
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
All-in-one model loader for SDXL workflows with checkpoint merging support.
|
||||
|
||||
### Inputs
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
## TT_SdxlModelsLoaderAdvanced
|
||||
|
||||
*This description was generated with AI assistance. If you spot any errors, please create an issue on GitHub.*
|
||||
|
||||
Extended all-in-one model loader for SDXL with checkpoint merging and LoRA support.
|
||||
|
||||
### Inputs
|
||||
|
||||
Reference in New Issue
Block a user