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:
TenserTensor
2026-02-13 18:19:27 +03:00
parent 3a0b6bd856
commit ee88f9be6c
13 changed files with 387 additions and 0 deletions
+3
View File
@@ -1,2 +1,5 @@
__pycache__/
_tmp/
.idea/
*.pyc
*.pyo
+14
View File
@@ -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)",
+29
View File
@@ -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),)
+34
View File
@@ -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),)
+44
View File
@@ -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)
+55
View File
@@ -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
+63
View File
@@ -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),)
+34
View File
@@ -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)
+40
View File
@@ -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)
+29
View File
@@ -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)
+38
View File
@@ -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)
+2
View File
@@ -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
+2
View File
@@ -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