KSampler Sequence
Looping KSampler passes for prompt-progression generations
- model
- positive_seq
- negative_seq
- latent_image
- LATENT
A normal KSampler runs once. This one runs a KSampler in a loop, evolving the seed, the prompt, and optionally the latent itself on every pass, so the image nudges forward instead of regenerating from scratch each time. The README calls this "prompt progression" - each loop is a small push toward the next described state, and it's built specifically to consume the frame-indexed prompt schedules from this pack's CLIPTextEncodeList node.
How it works
sequence_loop_count sets how many passes to run. Each loop, the seed evolves according to seed_mode_seq (increment, decrement, random, or fixed), and the prompt is pulled from wherever the positive_seq/negative_seq schedule says it should be for that point in the sequence. The first loop denoises from denoise_start (typically close to 1.0, a full pass from your starting latent); every loop after that uses denoise_seq - usually a lower value, since you're now nudging an existing image rather than generating one cold. That gap between the two denoise values is the actual mechanism behind "progression": high denoise once to establish the image, lower denoise repeatedly to walk it forward.
Two smoothing options sit on top of that core loop. use_conditioning_slerp (with cond_slerp_strength) spherically interpolates between consecutive prompts in the schedule instead of hard-switching, softening the transition. use_latent_interpolation (with latent_interpolation_mode - Blend, Slerp, or Cosine Interp - and latent_interp_strength) does the same thing to the latent between loops, blending consecutive outputs instead of letting each loop fully replace the last. unsample_latents is a different trick entirely: it reverses a few sampling steps before resampling, which injects a bit of controlled variation rather than just repeating the same trajectory.
The inputs and outputs that matter
model,latent_image- the usual sampler inputs;latent_imageis your starting point for loop one.positive_seq/negative_seq(CONDITIONING_SEQ) - this is the part that makes this node specific: it only accepts the schedule type fromCLIPTextEncodeList, not a plainCONDITIONING. If you don't have that node upstream, this input has nothing valid to connect to.sequence_loop_count(default 20, 1–1024) - how many times to loop. Start small (4–8) while you're tuning everything else; 20 loops of a slow model is a long feedback cycle to debug against.denoise_start(default 1) /denoise_seq(default 0.5) - the two denoise values that drive progression versus regeneration. This pair is worth understanding before touching anything else on the node.sampler_name/scheduler- the same full sampler and scheduler lists as a standard KSampler.
Single output: LATENT.
How to install it
Via ComfyUI Manager: search "WAS_Extras", install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/WAS_Extras
pip install -r WAS_Extras/requirements.txt
This node lives in ksampler_sequence.py, and the README is explicit that this file needs its requirements.txt installed even if you're grabbing individual .py files rather than the whole repo - don't skip it.
Common issues & troubleshooting
Can't connect a normal CLIP Text Encode to positive_seq. Expected - only CLIPTextEncodeList's CONDITIONING_SEQ output fits here. A plain CONDITIONING won't type-match.
Wired CLIPTextEncodeSequence2 in instead and it won't connect. That node's output type is CONDITIONING, built for KSamplerSeq2, not this node. The pack ships two parallel "sequence" systems (v1 here, v2 elsewhere) that don't cross-wire.
The image barely changes across loops, or changes too drastically. That's denoise_seq. Too low and successive loops barely move the image; too high and each loop is closer to a full regeneration, which fights the whole point of progression. 0.4–0.6 is a reasonable range to start experimenting in.
Long runs are slow to iterate on. This is genuinely an experimental, exploratory node - the README bills the whole pack that way. Drop sequence_loop_count down while dialing in denoise and slerp strengths, then raise it back up once the per-loop behavior looks right.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | The diffusion model every loop in the run samples with. | |
| seed | INT | 00–18446744073709550000 | The seed the first loop runs on, and the base every later loop's seed is worked out from. The same seed replays the whole run; change it for a different one. Any whole number; `0` is as good a seed as any. |
| seed_mode_seq | COMBO | How the seed moves from loop to loop. 'increment' and 'decrement' step it by one, which keeps consecutive frames close and the run smooth; 'random' picks a fresh seed each loop, which makes every frame its own image; 'fixed' holds one seed for the whole run, so only the prompt and the denoise change anything. | |
| alternate_values | BOOLEAN | true | Whether every other loop runs on a second seed that drifts away from the first instead of on the stepped one. It gives the run a slight back-and-forth flicker between two looks, which reads as movement in a short sequence. Turn it off for a single steady progression. |
| steps | INT | 201–10000 | Sampling steps per loop. Around 20 suits most models; more takes proportionally longer, and the whole run is this many steps times sequence_loop_count. |
| cfg | FLOAT | 8.00–100 | How closely each loop is held to its prompt. Around 7-8 suits most models; lower is looser and softer, much higher burns contrast and makes a sequence flicker. |
| sampler_name | COMBO | The sampling algorithm. 'euler' is the plain, predictable choice and the steadiest across a sequence; the 'ancestral' and 'sde' variants add fresh noise as they go, which adds detail and also adds flicker frame to frame. The list is whatever this ComfyUI offers. | |
| scheduler | COMBO | How the noise level is stepped down within each loop. 'normal' and 'karras' are the usual choices, karras spending more steps at low noise where fine detail is decided. The list is whatever this ComfyUI offers. | |
| sequence_loop_count | INT | 201–1024 | How many loops to run, which is how many latents come out. At 20 the output is a 20-image batch; the frame indices in the conditioning schedule are counted against this same number. |
| positive_seq | CONDITIONING_SEQ | The positive prompt schedule from CLIPTextEncodeList: pairs of frame index and conditioning. A loop with no entry of its own keeps the last one it was given, so a prompt stays in force until the next index in the list. | |
| negative_seq | CONDITIONING_SEQ | The negative prompt schedule, read exactly as positive_seq is. It needs at least one entry at frame 0, since a loop with nothing to fall back on has no negative prompt at all. | |
| use_conditioning_slerp | BOOLEAN | false | Whether the prompt changes gradually instead of switching over on one frame. On, each loop's conditioning is interpolated towards the one before it by cond_slerp_strength, which is what turns a list of prompts into a blend rather than a cut. |
| cond_slerp_strength | FLOAT | 0.5000–1 | How far each loop moves towards the new prompt when use_conditioning_slerp is on. 0.0 keeps the previous prompt, 1.0 takes the new one whole, 0.5 sits halfway between them. Ignored while that switch is off. |
| latent_image | LATENT | The latent the first loop starts from, which also sets the size of every frame. An empty latent generates from scratch; an encoded image starts the sequence on that picture. | |
| use_latent_interpolation | BOOLEAN | false | Whether each new latent is mixed back towards the previous frame before it is kept. It damps down how much can change between two frames, which is the main handle on how jumpy the finished sequence looks. |
| latent_interpolation_mode | COMBO | How the previous frame is mixed in. 'Blend' is a straight average; 'Slerp' travels along the arc between the two latents and holds contrast better; 'Cosine Interp' is a blend that eases in and out, so each frame is held a little longer. Ignored while use_latent_interpolation is off. | |
| latent_interp_strength | FLOAT | 0.5000–1 | How much of the newly sampled frame survives the mix. 1.0 keeps it whole and changes nothing, 0.5 is an even blend with the frame before, and low values nearly freeze the sequence. Ignored while use_latent_interpolation is off. |
| denoise_start | FLOAT | 1.000–1 | How much of the first loop is redrawn. 1.0 ignores latent_image's content and generates the opening frame from noise; around 0.5 keeps its composition and changes the detail. |
| denoise_seq | FLOAT | 0.500–1 | How much every loop after the first redraws. This is what decides whether the run drifts or jumps: 0.5 lets a frame change noticeably, 0.2 barely moves, and near 1.0 each frame is a fresh image holding nothing of the last. |
| unsample_latents | BOOLEAN | false | Whether each loop first runs the sampler backwards over the previous frame, pushing it back up the noise schedule before resampling. It gives the new prompt something to re-resolve rather than a finished image to leave alone, at roughly double the time per loop. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | Every loop's latent, stacked into one batch in order. Decode it with a VAE Decode to get the frames, then save them as an image sequence or a video. |