# ComfyUI Sampler Configuration and Scheduling: A Complete Technical Guide

> Master ComfyUI sampler configuration and scheduling. This technical guide details how ComfyUI's KSampler orchestrates ODE/SDE integrators and noise schedules for efficient image generation.

- Repository: [Comfy Org/ComfyUI](https://github.com/Comfy-Org/ComfyUI)
- Tags: deep-dive
- Published: 2026-02-26

---

**ComfyUI separates the sampler algorithm (the ODE/SDE integrator) from the noise schedule (sigma values), with the `KSampler` class in [`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py) orchestrating both components at runtime.**

ComfyUI's sampling pipeline is a two-layer architecture that decouples the numerical integration method from the noise schedule generation. Understanding how **sampler configuration and scheduling** interact is essential for customizing diffusion workflows in the Comfy-Org/ComfyUI repository. The system uses modular handlers and factory functions to assemble these components dynamically based on UI selections.

## Sampler Selection: Mapping Names to Algorithms

The **sampler** determines the numerical method used to solve the diffusion ODE or SDE. ComfyUI implements a factory pattern to resolve sampler names into executable functions.

**`sampler_object(name)`** serves as the primary factory function in [`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py) (lines 100-112). It accepts a string identifier such as `"euler"`, `"dpm_fast"`, or `"uni_pc"` and returns a **`KSAMPLER`** instance. This object wraps the low-level sampling function imported from `k_diffusion.sampling` and stores any extra options or inpaint-specific configurations.

The **`KSAMPLER`** class (lines 28-55 in [`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py)) inherits from the base `Sampler` class and holds the concrete `sampler_function` attribute. Its `sample()` method prepares the model wrapper, initializes noise tensors, and invokes the wrapped function. Supported identifiers are maintained in the **`SAMPLER_NAMES`** list (lines 22-27), which acts as a whitelist for the UI dropdown.

## Scheduler Configuration: Generating Sigma Schedules

While the sampler defines **how** to step through the diffusion process, the **scheduler** defines **when** by producing the sigma (σ) values that control noise levels.

**`SCHEDULER_HANDLERS`** (lines 78-90 in [`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py)) maps human-readable names like `"simple"`, `"karras"`, and `"ddim_uniform"` to `SchedulerHandler` objects. Each handler encapsulates a scheduling function and a flag indicating whether it requires the full `model_sampling` object (`use_ms=True`) or raw `(n, sigma_min, sigma_max)` arguments.

Concrete implementations include:

- **`simple_scheduler`** (lines 5-12): Linear interpolation between sigma max and min
- **`ddim_scheduler`** (lines 84-88): Uniform steps compatible with DDIM sampling  
- **`normal_scheduler`** (lines 131-151): Standard log-normal spacing used by many legacy models

The **`calculate_sigmas`** function (lines 92-100) looks up the appropriate handler and returns a `torch.FloatTensor` of sigma values. The **`KSampler.calculate_sigmas`** method extends this with logic to discard penultimate sigmas for specific samplers (like `dpm_2` and `uni_pc`) and applies user-defined `denoise` factors that truncate the schedule.

## End-to-End Sampling Execution

When a workflow node executes, the system follows this precise pipeline:

1. **Configuration**: The `KSampler` class stores the selected `sampler` and `scheduler` names during initialization.
2. **Sigma Generation**: `KSampler.calculate_sigmas` builds the sigma tensor by querying `SCHEDULER_HANDLERS` and invokes the scheduling function.
3. **Sampler Instantiation**: `sampler_object()` creates the `KSAMPLER` wrapper around the low-level function (e.g., `k_diffusion_sampling.sample_euler`).
4. **Conditioning Preparation**: The `sampling_function` in [`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py) merges positive and negative conditionings and applies classifier-free guidance via `cfg_function`.
5. **Iteration**: The low-level sampler in **[`comfy/k_diffusion/sampling.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/k_diffusion/sampling.py)** iterates over the sigma list, computing denoised predictions and advancing the latent state using the appropriate ODE/SDE step.

## Practical Code Examples

### Creating a KSampler Programmatically

```python
import torch
from comfy.samplers import KSampler, sampler_object

device = torch.device("cuda")
steps = 20
sampler_name = "euler"
scheduler_name = "karras"

# Initialize the high-level KSampler

k = KSampler(model, steps, device, sampler=sampler_name, scheduler=scheduler_name)

# Generate noise and sample

noise = torch.randn(1, 4, 64 // 8, 64 // 8, device=device)
latent = k.sample(noise, positive, negative, cfg=7.5, seed=42)

```

This example demonstrates how `KSampler.__init__` automatically calls `calculate_sigmas` to build the schedule, while `k.sample` handles the `CFGGuider` instantiation and conditioning preparation.

### Adding a Custom Scheduler

```python
from comfy.samplers import SCHEDULER_HANDLERS, SchedulerHandler
import torch

def my_linear_scheduler(model_sampling, steps):
    sigma_max = model_sampling.sigma_max
    sigma_min = model_sampling.sigma_min
    return torch.linspace(sigma_max, sigma_min, steps + 1)

# Register with use_ms=True to receive model_sampling object

SCHEDULER_HANDLERS["my_linear"] = SchedulerHandler(my_linear_scheduler)

# Use in subsequent KSampler instances

k = KSampler(model, steps=30, device=device, sampler="dpm_fast", scheduler="my_linear")

```

### Inspecting Generated Sigma Values

```python
k = KSampler(model, steps=10, device=device, sampler="euler", scheduler="ddim_uniform")
print(k.sigmas)  # Shape [11], ending with 0.0

```

## Key Source Files

Understanding the repository structure helps navigate the codebase:

- **[`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py)**: Core dispatcher containing `KSampler`, `sampler_object`, `calculate_sigmas`, `SAMPLER_NAMES`, `SCHEDULER_HANDLERS`, and CFG handling logic.
- **[`comfy/sampler_helpers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/sampler_helpers.py)**: Utilities for conditioning preparation (`process_conds`, `prepare_sampling`), model loading bookkeeping, and memory estimation.
- **[`comfy/k_diffusion/sampling.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/k_diffusion/sampling.py)**: Low-level diffusion step implementations including `sample_euler`, `sample_heun`, and `sample_dpm_2`.
- **[`comfy/model_sampling.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/model_sampling.py)**: Provides the `ModelSampling` object supplying `sigma_min`, `sigma_max`, and `percent_to_sigma` utilities used by schedulers.

## Summary

- **ComfyUI sampler configuration** relies on `sampler_object()` to map names to `KSAMPLER` instances that wrap low-level ODE/SDE solvers.
- **Scheduling** is handled by `SCHEDULER_HANDLERS`, which dispatch to functions like `simple_scheduler` or `karras_scheduler` to generate sigma tensors.
- The **`KSampler`** class orchestrates both components, managing sigma calculation, classifier-free guidance, and the iterative sampling loop.
- Custom schedulers register via `SchedulerHandler` objects in `SCHEDULER_HANDLERS` for immediate integration with existing samplers.
- Low-level sampling algorithms reside in [`comfy/k_diffusion/sampling.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/k_diffusion/sampling.py), completely decoupled from schedule generation logic.

## Frequently Asked Questions

### What is the difference between a sampler and a scheduler in ComfyUI?

A **sampler** is the numerical algorithm that solves the diffusion equation (such as Euler or DPM-Solver), while a **scheduler** generates the sequence of noise levels (sigma values) that the sampler uses to guide the denoising process. The sampler determines *how* to step, and the scheduler determines *where* to step in the noise space.

### How do I add a custom noise scheduler to ComfyUI?

Define a function that accepts `model_sampling` and `steps` arguments and returns a `torch.FloatTensor` of sigma values. Wrap this function in a `SchedulerHandler` with `use_ms=True` and register it in `SCHEDULER_HANDLERS` under a unique name. The scheduler becomes immediately available to all `KSampler` instances without modifying core code.

### Where are the low-level sampling algorithms implemented in ComfyUI?

The actual diffusion step implementations reside in **[`comfy/k_diffusion/sampling.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/k_diffusion/sampling.py)**, which contains functions like `sample_euler`, `sample_heun`, and `sample_dpm_2`. These functions operate on the sigma schedule provided by `KSampler` and are wrapped by the `KSAMPLER` class for integration with ComfyUI's conditioning and guidance systems.

### How does ComfyUI handle classifier-free guidance (CFG) during sampling?

CFG is applied in the `sampling_function` within [`comfy/samplers.py`](https://github.com/Comfy-Org/ComfyUI/blob/main/comfy/samplers.py) before the sampler executes each step. The system uses `cfg_function` to combine positive and negative conditionings based on the user-provided `cfg` scale, then passes the conditioned prediction to the low-level sampler algorithm for the actual latent update.