Runge-Kutta Sampler
The sampler that lets you crank CFG to 30 on SDXL without burning out
- SAMPLER
Most samplers fall apart when you push CFG past 10 - colors burn, edges go crispy, the image looks like a bad HDR filter. Runge-Kutta Sampler is the one people reach for when they want to. It's a custom sampler for ComfyUI that solves the denoising process with classic Runge-Kutta ODE methods, and its whole pitch is that those methods carry so little discretization error that high CFG scales stop being a punishment. On SDXL the author runs it happily at CFG 7–35, which sounds like a typo until you try it.
This pack is a bit of a time capsule. It landed in July 2024 - "Batched Runge-Kutta Samplers for ComfyUI (18 new samplers!)" on r/StableDiffusion - aimed squarely at SD 1.5, SDXL, and SD3. It never became a household name the way the flow-matching solver packs did in 2026, and it isn't really built for those models anyway. If you're on Flux or another rectified-flow checkpoint, put this one down and look at RES4LYF instead. If you live on SDXL finetunes and want stronger prompt adherence without artifacts, this is genuinely a contender.
What the node actually is
This isn't a full sampler - it's a sampler factory. It has no model or prompt inputs. It outputs a single SAMPLER object, which you wire into the sampler input of a normal KSampler node (or SamplerCustomAdvanced, if you're feeding it a schedule directly). Confusing the first time you open it, but that's standard for the custom_sampling/samplers category.
Mechanically, it treats sampling as solving the reverse-time ODE, with explicit Runge-Kutta stepping done in parallel across your batch via the torchode library. Because RK methods solve the ODE more accurately per step, you get convergence at moderate step counts and, per the author, the freedom to run high CFG without the usual blowout. It's also deterministic - a converging solver, no fresh noise per step, so same seed, same image.
The inputs that matter
There are seventeen knobs on this thing. Ignore most of them. Three decide everything:
- method - the solver, from a list of 22 (
ae_bosh3,fe_ralston3,fe_kutta4, and friends). Thea/f/sprefix says which controller class it works with: adaptive, fixed, or scipy. - step_size_controller -
adaptive_pid,fixed_scheduled, oradaptive_scipy. This is the choice that defines your whole workflow. - log_absolute_tolerance / log_relative_tolerance - only used by the adaptive controllers. The author's defaults of
-3.5and-2.5are fine; lower the first for better (slower) results, raise it for faster (worse).
The rest - pcoeff/icoeff/dcoeff, norm, safety, factor_min/max, dt_min/max, max_steps, min_sigma - are real but you'll touch them rarely. The PID coefficients default to 0/1/0, which just means "plain integral controller," and that's a good place to leave them.
Which path to take
Pick one of two recipes and stick to it:
fixed_scheduled+fe_ralston3- the author's overall #1. Set your scheduler to Align Your Steps, use 28–150 steps, CFG 7–35. The step count genuinely matters here: the controller uses the sigma schedule the scheduler hands it, so it behaves like a normal non-adaptive sampler.adaptive_pid+ae_bosh3- the flexible default. The solver sizes its own steps from the tolerances, so your scheduler's step count is basically ignored (only start/end timesteps matter). Handy when you don't know the right step count.
For the adaptive route, remember the tolerance constraint baked into the code: log_absolute_tolerance must be ≤ log_relative_tolerance, or it throws.
Install and gotchas
Via ComfyUI Manager, search ComfyUI-RK-Sampler and hit Install. Manual install is the standard one-liner:
cd ComfyUI/custom_nodes
git clone https://github.com/wootwootwootwoot/ComfyUI-RK-Sampler.git
pip install torchode
The only dependency is torchode - if the node fails to import, that's what's missing. A few things that burn people:
- Method/controller mismatches error out.
adaptive_pidonly acceptsa-class methods,fixed_scheduledtakesa- andf-class, andadaptive_scipyonly thes-class scipy wrappers. Mix them and you get a ValueError, not a fallback. - The scipy solvers are slow and sequential.
adaptive_scipyruns on CPU and processes each batch element one at a time. Fine for a single image; forget it for batch work. dt_min,factor_min, tolerances all have ordering constraints (dt_min ≤ dt_max,factor_min ≤ factor_max) - the validation is strict, so read the error if one fires.
It's a niche tool, but for SDXL-at-high-CFG people it's the one that actually holds up. If that's your workflow, give fe_ralston3 at 28 AYS steps a spin. If not, this is a neat piece of sampler history to have around.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| method | COMBO | ae_bosh3 | 22 options: ae_bosh3, ae_cash_karp5, ae_dopri5, ae_dopri8, ae_fehlberg2, ae_fehlberg5, +16 |
| step_size_controller | COMBO | adaptive_pid | 3 options: adaptive_pid, fixed_scheduled, adaptive_scipy |
| log_absolute_tolerance | FLOAT | -3.5000-1e+38–1e+38 | — |
| log_relative_tolerance | FLOAT | -2.5000-1e+38–1e+38 | — |
| pcoeff | FLOAT | 0.00000–1e+38 | — |
| icoeff | FLOAT | 1.00000–1e+38 | — |
| dcoeff | FLOAT | 0.00000–1e+38 | — |
| norm | COMBO | rms_norm | 2 options: rms_norm, max_norm |
| enable_dt_min | BOOLEAN | false | — |
| enable_dt_max | BOOLEAN | true | — |
| dt_min | FLOAT | -0.1000-1e+38–0 | — |
| dt_max | FLOAT | 0.0000-1e+38–0 | — |
| safety | FLOAT | 0.90000–1e+38 | — |
| factor_min | FLOAT | 0.20000–1e+38 | — |
| factor_max | FLOAT | 10.00000–1e+38 | — |
| max_steps | INT | 21474836471–2147483647 | — |
| min_sigma | FLOAT | 0.00000–1e+38 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| SAMPLER | SAMPLER | — |