Sampler Peek (Advanced)
Get every intermediate frame as a real image
- noise
- guider
- sampler
- sigmas
- latent_image
- vae
- output
- denoised_output
- preview_images
- step_indices
ComfyUI already paints a live preview while a KSampler runs - but that preview is smoke. It's rendered on the fly, never saved, and you can't grab frame 9 as a real image or feed it into another node. SamplerPeekAdvanced fixes exactly that. It's a drop-in replacement for SamplerCustomAdvanced that decodes intermediate latents through a VAE at the steps you pick, then hands you the whole run as an IMAGE batch plus the matching step numbers.
Two things people actually use it for: progress animations (queue a 20-step generation, get a 20-frame "watch the image form" video) and debugging ("which step did the hands go wrong?" - now you can see it). There's a bonus on top: step-dependent CFG, so your guidance scale can ramp through the run instead of sitting flat.
How it works
During diffusion, the model doesn't just output noise at each step - it also produces x₀, its current best guess at the clean image. That's exactly what the live preview shows. SamplerPeekAdvanced hooks the sampling loop's step callback (the same one ComfyUI's own preview uses) and, when the current step matches your conditions, decodes x₀ through the VAE and appends it to a batch. Step numbers are recorded alongside, 1-based. That's the whole trick, and it's why the node has zero external dependencies - it's built on ComfyUI's own sampling internals.
The inputs that matter
The five SamplerCustomAdvanced inputs are all there unchanged - noise, guider, sampler, sigmas, latent_image - plus a vae input for the decoding. Wire them exactly as you already do. Then set:
decode_expr- the expression that decides which steps get decoded. Variables arestep(1..n) andn(total steps).step % 5 == 0decodes every 5th step;step >= 10 and step <= 20decodes the middle;step == 1 or step == ngrabs just the bookends. Empty string means every step.start_step/end_step- hard bounds around the decode window (1-based).end_step0 means no upper limit.max_previews- a RAM cap on stored previews. 0 = unlimited, which is a footgun if your expression matches a lot (see below).cfg_expr(optional) - step-dependent CFG.clamp(1 + step / n * 7, 1, 8)ramps CFG linearly from 1 to 8 across the run. It wraps the guider'spredict_noiseand callsset_cfgper step, so it only does anything on guiders that support that.
Outputs
output- the final sampled latent, ready for your VAE decode as usual.denoised_output- the final x₀ prediction.preview_images- the IMAGE batch of decoded intermediate frames. Wire this into aSaveImageorPreviewImage.step_indices- an INT tensor holding the 1-based step number for each preview. It's a batch, so if you want a plain scalar, run it through the pack'sPeekStepIndexnode.
Install
ComfyUI Manager: search comfyui-sampler-peek. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/Prohect/comfyui-sampler-peek
Then restart ComfyUI. No pip install, no model files, no requirements beyond Python 3.10+ and ComfyUI's own PyTorch. One trap: the README's own clone command still points at the old aria4comfyui repo, which now 404s - use the URL above.
Where people get burned
- Decoding every step is slow. Each decoded frame is a full VAE pass on GPU time. Leave
decode_exprempty withmax_previews0 and a 30-step gen becomes noticeably heavier.step % 5 == 0plus amax_previewscap keeps it cheap. - A typo in
decode_exprfails silently. Invalid expressions are skipped per-step, so you don't get an error - you get no previews, or a 1x1 black placeholder. Test your expression inStepExpressionfirst. - The indices are 1-based while many ComfyUI step notions are 0-based. If you're matching this against a KSampler's step counter, off-by-one will bite.
If the image falls apart only near the end of the run, that's the classic too-high-CFG-at-few-steps failure mode, and this node is the perfect tool to actually watch it happen. Otherwise, enjoy turning every generation into a little movie.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| noise | NOISE | Noise source for sampling | |
| guider | GUIDER | Guider (e.g., CFGGuider) | |
| sampler | SAMPLER | Sampler to use | |
| sigmas | SIGMAS | Sigmas schedule | |
| latent_image | LATENT | Latent image to sample from | |
| vae | VAE | VAE model for decoding intermediate latents | |
| decode_expr | STRING | Expression that determines when to decode. Variables: step (1..n), n (total steps). e.g., 'step % 5 == 0'. Empty = every step. | |
| start_step | INT | 11–10000 | Only decode at or after this step (1-based) |
| end_step | INT | 00–10000 | Only decode at or before this step. 0 = no limit |
| max_previews | INT | 00–10000 | Max previews to store in RAM. 0 = unlimited |
| cfg_expropt | STRING | Step-dependent CFG expression. Evaluated at each step to dynamically set the guider CFG. Variables: step, n. e.g., 'clamp(1 + step / n * 7, 1, 8)' for a linear ramp. Empty = use the guider's default CFG. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| output | LATENT | Final sampled latent (with optional step-dependent CFG applied) |
| denoised_output | LATENT | Final x0 prediction |
| preview_images | IMAGE | Batch of decoded preview images from intermediate steps |
| step_indices | INT | Step indices (1-based) for each preview image |