Nodes/KarmaNodes/Karma KSampler Cycle
ComfyUI Node

Karma KSampler Cycle

Your entire hires-fix loop in one node

By KarmaSwint·Created about a year ago·Updated 5 months ago· 1
Karma KSampler Cycle
  • primary_model
  • vae
  • latent_image
  • positive
  • negative
  • secondary_model
  • upscale_model
  • pos_additive
  • neg_additive
  • latent(s)
  • vae
steps20
seed0
cfg8.00
sampler_name
scheduler
starting_denoise1.00
cycle_denoise0.50
total_cycles2
enable_denoise_scalingtrue
denoise_min_threshold0.10
enable_steps_scalingfalse
steps_scaling_value5
steps_adjustment_modedecrement
steps_threshold_modeauto
steps_manual_threshold5
secondary_model_start_cycle2
upscale_factor2.0
upscale_methodbasic
scale_sampling
latent_upscale_methodlanczos
enable_gradual_upscalingfalse
gradual_upscale_steps3
pos_add_strength0.25
enable_pos_strength_scalingfalse
pos_add_strength_cutoff2.00
neg_add_strength0.25
enable_neg_strength_scalingfalse
neg_add_strength_cutoff2.00
sharpen_strength0.00
sharpen_radius2
use_tiled_vaefalse

The classic way to get a sharp, high-resolution image is a chain: sample at native resolution, upscale, sample again at low denoise, maybe upscale and sample a third time. That's the hires-fix loop, and on paper it's simple. On canvas it's a sprawl of KSamplers, image scalers and latent resizers that you have to keep in sync by hand. Karma KSampler Cycle is the flagship node of this pack, and its whole pitch is that it runs that loop for you - one node, N cycles, progressive upscaling between each, and it handles the plumbing.

The way it works is worth understanding before you dial it in, because the defaults are not tuned for your model. Each cycle, the node samples your latent with a standard KSampler, then - on every cycle except the last - it upscales toward a single final target dimension and feeds the result back in for the next pass. In pixel space it decodes, upscales, and re-encodes (that's the basic and model methods). Or you pick latent, and it resizes the latent tensor directly with torch interpolation - no VAE roundtrip, meaningfully faster, slightly rougher. The total upscale factor is spread geometrically across cycles, so a 2-cycle run does one upscale operation at factor upscale_factor, while a 4-cycle run takes the fourth root each time.

That's the core. Everything else is automation on top. With denoise scaling on, denoise roughly halves each cycle and floors at denoise_min_threshold, so early cycles do the heavy lifting and later ones just add detail. Steps scaling either increments or decrements steps per cycle, clamped by a threshold you can set to auto (derived from your initial steps) or manual. You can switch to a secondary_model at a chosen cycle, blend extra pos_additive/neg_additive conditioning in with strength scaling, sharpen between cycles, and toggle tiled VAE for large outputs.

The inputs a beginner actually sets: total_cycles, starting_denoise, cycle_denoise, upscale_factor, and upscale_method. The rest of the ~40 inputs have sane defaults and you should touch them only when something's wrong. Wire up primary_model, vae, latent_image, positive, negative, pick a sampler_name/scheduler, and run. You get latent(s) (feed it to VAE Decode) and a passthrough vae.

Where people get burned:

  • upscale_method = model with no upscale model connected doesn't error - it silently falls back to basic and prints a warning to the console. That's a nice degradation, but if your output suddenly looks softer than expected, check the console.
  • If your steps are lower than total_cycles, the node clamps the cycle count down to your steps. A 20-step, 6-cycle run is actually a 6-cycle run; a 4-step run with 6 cycles is a 4-cycle run.
  • Latent upscale "lanczos" isn't really lanczos. Torch's interpolate has no lanczos mode, so the node remaps it to bicubic. It's in the source, not the README. Fine in practice - just don't expect pure lanczos behavior.
  • VRAM. High upscale factors plus many cycles means decode/upscale/re-encode repeatedly. That's the OOM classic, and use_tiled_vae is the first thing to flip when it hits.

Installing it

Search "KarmaNodes" in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/KarmaSwint/ComfyUI-KarmaNodes
cd ComfyUI-KarmaNodes
pip install -r requirements.txt

Restart ComfyUI. No model files download - but if you want upscale_method = model, you supply your own upscale model (drop it in ComfyUI's models/upscale_models and connect it to the upscale_model input).

Tuning it

Start with 3–4 cycles, upscale_factor 1.5–2, starting_denoise 1.0, cycle_denoise 0.4–0.5. Denoise above ~0.5 on the final passes starts moving composition rather than adding detail, which is the usual reason the output drifts from your first-pass framing. For refinement, run steps scaling in decrement mode (20 → 15 → 10 → 5); for detail-hunting, use increment with a manual cap. The node prints a verbose play-by-play to the console with every cycle's denoise, steps and dimensions - genuinely useful when you're diagnosing, if noisy.

Is it a replacement for a hand-built hires-fix + ControlNet-Tile stack? Not quite - it's a convenience node, not a quality ceiling. But for the 80% case where you just want clean, progressively-refined output without maintaining a wall of nodes, it's the fastest route from latent to finished image in this pack.

CategoryKarmaNodes/Sampling

Inputs (40)

NameTypeDefaultDescription
primary_modelMODEL
vaeVAE
latent_imageLATENT
positiveCONDITIONINGThe main positive conditioning.
negativeCONDITIONINGThe main negative conditioning.
stepsINT201–10000
seedINT00–18446744073709550000
cfgFLOAT8.000–100
sampler_nameCOMBO44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBO9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
starting_denoiseFLOAT1.000–1
cycle_denoiseFLOAT0.500–1
total_cyclesINT22–12
enable_denoise_scalingBOOLEANtrueEnable automatic denoise strength scaling between cycles
denoise_min_thresholdFLOAT0.100.01–1Minimum denoise threshold to prevent going too low
enable_steps_scalingBOOLEANfalseEnable automatic steps adjustment between cycles
steps_scaling_valueINT51–50Amount to adjust steps by each cycle
steps_adjustment_modeCOMBOdecrementWhether to decrease or increase steps each cycle
steps_threshold_modeCOMBOautoAuto calculates threshold based on initial steps, manual uses fixed value
steps_manual_thresholdINT51–200Manual threshold value (only used when threshold mode is manual)
secondary_model_start_cycleINT21–12Cycle at which to switch to secondary model (if provided)
upscale_factorFLOAT2.00.1–8
upscale_methodCOMBObasicbasic = PIL image upscale, model = upscale model, latent = direct latent space resize (fastest, no VAE decode/encode)
scale_samplingCOMBOResampling method for image upscaling
latent_upscale_methodCOMBOlanczosResampling method for latent space upscaling
enable_gradual_upscalingBOOLEANfalseEnable gradual upscaling with multiple intermediate steps
gradual_upscale_stepsINT31–10Number of gradual upscaling steps (only used when gradual upscaling is enabled)
pos_add_strengthFLOAT0.250.01–1
enable_pos_strength_scalingBOOLEANfalseEnable positive strength scaling between cycles
pos_add_strength_cutoffFLOAT2.000.01–10
neg_add_strengthFLOAT0.250.01–1
enable_neg_strength_scalingBOOLEANfalseEnable negative strength scaling between cycles
neg_add_strength_cutoffFLOAT2.000.01–10
sharpen_strengthFLOAT0.000–10
sharpen_radiusINT21–12
use_tiled_vaeBOOLEANfalseUse tiled VAE processing for large images
secondary_modeloptMODELOptional secondary model to switch to at specified cycle
upscale_modeloptUPSCALE_MODEL
pos_additiveoptCONDITIONINGAdditional positive conditioning to blend in.
neg_additiveoptCONDITIONINGAdditional negative conditioning to blend in.

Outputs (2)

NameTypeDescription
latent(s)LATENT
vaeVAE