Open-Source Wikis

/

ComfyUI

/

Systems

/

Sampling pipeline

comfyanonymous/ComfyUI

Sampling pipeline

What happens when you click Queue Prompt on a workflow that ends in KSampler. This page covers the journey from a checkpoint and a text prompt to a finished latent.

Purpose

The sampling pipeline takes a model, conditioning, a noise schedule, and an initial latent and runs an iterative denoising loop, optionally with classifier-free guidance, ControlNet, hooks, and per-area conditioning.

Layout

comfy/
├── samplers.py              # The high-level sampling loop, CFG, sampling_function
├── sample.py                # Convenience wrappers used by KSampler nodes
├── sampler_helpers.py       # Conditioning preprocessing, mask sizing, area packing
├── model_sampling.py        # ModelSamplingDiscrete, FlowMatch, EDM (continuous-time formulations)
├── k_diffusion/
│   ├── sampling.py          # k-diffusion samplers (Euler, DPM++, Heun, …)
│   ├── deis.py              # DEIS sampler
│   ├── sa_solver.py         # SA solver
│   └── utils.py
└── extra_samplers/
    └── uni_pc.py            # UniPC + restart variants

Key abstractions

Type / function File What it does
KSampler comfy/samplers.py High-level wrapper used by KSampler and KSamplerAdvanced nodes
sampling_function comfy/samplers.py The CFG-aware noise prediction call
KSAMPLER comfy/samplers.py Functional wrapper around a k-diffusion sampler
ModelSamplingDiscrete, ModelSamplingFlowMatch, … comfy/model_sampling.py Architecture-specific sampling math (eps/v/x0 prediction, schedules)
sample_euler, sample_dpmpp_2m_sde_gpu, … comfy/k_diffusion/sampling.py One function per sampler
sample_uni_pc_bh1, sample_restart comfy/extra_samplers/uni_pc.py Extra samplers
prepare_noise, prepare_sampling comfy/sample.py Latent + conditioning preparation done by KSampler nodes
pre_run_control, apply_empty_x_as_equal_area comfy/sampler_helpers.py Conds normalization and ControlNet pre-run
Guider, CFGGuider comfy/samplers.py The "guidance object" used by the Custom Sampler family

How a KSampler call flows

sequenceDiagram
    autonumber
    participant Node as KSampler node
    participant Smp as comfy.sample.sample
    participant Help as sampler_helpers
    participant Model as ModelPatcher.model
    participant KD as k_diffusion sampler
    participant CFG as sampling_function
    participant CN as ControlNet (if any)
    participant Hook as Hooks (if any)

    Node->>Smp: sample(model, noise, steps, cfg, sampler, scheduler, positive, negative, latent)
    Smp->>Help: pre_run_control + prepare_noise
    Smp->>Model: load_model_gpu via ModelPatcher
    Smp->>KD: sampler_callable(noise, sigmas, denoise_callback)
    loop each timestep
        KD->>CFG: predict_noise(x, sigma, conds)
        CFG->>Model: apply_model(x, t, c_concat=..., c_crossattn=...)
        Model-->>CFG: noise prediction
        CFG-->>KD: combined cond/uncond
        KD->>KD: step from sigma_i to sigma_{i+1}
        KD-->>Smp: progress callback (preview, percent)
        opt
            CN->>Model: residuals
        end
        opt
            Hook->>Model: apply / unapply hooks
        end
    end
    Smp-->>Node: sampled latent

The sampling_function is the heart of CFG: it batches conditional and unconditional noise predictions into one model call when memory allows, then mixes them by cfg_scale (with various interpolation modes for newer guidance methods).

Schedules

Schedules turn a step count into a list of sigmas:

Scheduler Where
karras comfy/k_diffusion/sampling.py:get_sigmas_karras
exponential comfy/k_diffusion/sampling.py
simple, ddim_uniform, sgm_uniform, beta comfy/samplers.py
linear_quadratic, kl_optimal comfy/samplers.py
normal the model's model_sampling schedule

The complete list of sampler names is the SAMPLER_NAMES and SCHEDULER_NAMES arrays at the top of comfy/samplers.py — those are what populate the dropdowns in the KSampler node.

Custom Sampler decomposition

The Custom Sampler family in comfy_extras/nodes_custom_sampler.py breaks the K-Sampler into reusable pieces:

  • BasicScheduler / KarrasScheduler / … — produce SIGMAS (1D tensor)
  • KSamplerSelect — produce a SAMPLER (function reference)
  • BasicGuider / CFGGuider / … — produce a GUIDER (something with predict_noise)
  • RandomNoise — produce NOISE
  • SamplerCustom — combine the above into a finished latent

This is graph-level composability: you can swap a different scheduler in without touching the sampling loop. The shared interface for GUIDER is in comfy/samplers.py.

Per-area conditioning, masks, hooks

sampler_helpers.py and samplers.py together support:

  • Area — apply a conditioning to a sub-region of the latent.
  • Mask — apply a soft mask to a conditioning (e.g., for inpainting + prompt blending).
  • Strength scaling — boost or attenuate a conditioning's effect.
  • Timestep rangetimestep_start/timestep_end inside cond only applies for specific timesteps.
  • Hooks — see LoRA and hooks. Hooks can scope LoRA application or attention modifications to specific timesteps and conditioning paths.

ControlNet integration

A cond dict can carry control — a ControlBase (from comfy/controlnet.py) that's woken up during apply_model to inject residuals into the unet. ControlNet weights live in their own ModelPatcher so they participate in the same VRAM accounting as the main model.

Latent format normalization

Different architectures use different latent statistics. comfy/latent_formats.py registers per-architecture means/stds so previewers (and any cross-model nodes) can convert latents to a normalized space. Every BaseModel subclass declares its latent_format.

Integration points

Where to start a change

  • New k-diffusion sampler: add to comfy/k_diffusion/sampling.py; register the name in comfy.samplers.SAMPLER_NAMES.
  • New scheduler: add to comfy/samplers.py's calculate_sigmas and the SCHEDULER_NAMES list.
  • New CFG variant: study sampling_function in comfy/samplers.py. Many existing variants are nodes that wrap sampling_function with a custom callback (e.g., PAG/SAG in comfy_extras/).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Sampling pipeline – ComfyUI wiki | Factory