Nodes/ComfyUI-EvalSampler/EvalSamplerAdvanced
ComfyUI Node

EvalSamplerAdvanced

Same Wiretap, Built for the Custom Sampler Graph

By BobJohnson24·Created 4 months ago·Updated 3 months ago· 3
EvalSamplerAdvanced
  • noise
  • guider
  • sampler
  • sigmas
  • latent_image
  • output
  • denoised_output
output_foldereval_latents

EvalSamplerAdvanced (menu name "Eval Sampler (Custom Advanced)") is the same recorder as its sibling EvalSampler, but wired for the modular sampling graph instead of the classic one. If your workflow builds sampling out of parts - KSamplerSelectBasicGuiderBasicSchedulerSamplerCustomAdvanced - then this node is the drop-in replacement for that last piece. Swap it in and, without changing anything else, every denoising step's conditioned and unconditioned predictions get written to disk for later analysis.

Why both exist: the pack ships one recorder shaped like KSamplerAdvanced (the plain EvalSampler) and one shaped like the custom-sampler pipeline, so whichever way you normally assemble sampling, there's a version that slots in without rebuilding your graph. The data they save is identical, and both feed the same MeasureResults.py companion script that compares a BF16 baseline against your fp8/GGUF/INT8 variants.

How it works

It's a subclass of ComfyUI's SamplerCustomAdvanced, and it's written on ComfyUI's newer node API (define_schema / execute classmethods rather than the classic INPUT_TYPES). Read the source and one detail jumps out: before installing its CFG hook it clones the guider's model_patcher, so instrumenting the run doesn't mutate the model object back in your base graph. Then it hooks the CFG function, and at each step saves cond_denoised and uncond_denoised as {seed}_S{step}.safetensors and {seed}_S{step}_uncond.safetensors under ComfyUI/output/eval_latents before letting the real sampling continue.

There's also a genuine behavioral difference hiding here. EvalSamplerAdvanced registers its hook with disable_cfg1_optimization=True. That model option is the switch that tells ComfyUI "still compute the unconditioned prediction even at CFG 1" - normally ComfyUI skips the whole uncond pass at exactly 1 for a free speed win, and the plain EvalSampler doesn't opt back out, so its uncond files at CFG 1 are zeros. This node does opt out, so it records a real uncond prediction at any CFG. If you must eval at low CFG, this is the one.

The inputs and outputs

Six inputs, and five of them are the standard custom-sampler plumbing:

  • noise (NOISE), guider (GUIDER), sampler (SAMPLER), sigmas (SIGMAS) - the four pieces of the advanced pipeline, produced by Noise/BasicGuider/KSamplerSelect/BasicScheduler and friends.
  • latent_image (LATENT) - the starting latents.
  • output_folder - where recordings go under ComfyUI/output; default eval_latents. Give each model variant its own folder so MeasureResults.py can tell them apart.

Two outputs, matching SamplerCustomAdvanced: output (LATENT) is the regular result - wire it to VAEDecode as you normally would - and denoised_output (LATENT) is the fully-denoised latent variant for workflows that inspect it.

The fair-comparison rules from the plain node all still apply: identical seed, prompt, steps, sampler, scheduler and cfg across every run you want to compare, or the numbers measure your inconsistency instead of the model.

Installing and the one real gotcha

Same as its sibling: ComfyUI Manager (search "EvalSampler" or ComfyUI-EvalSampler), or

cd ComfyUI/custom_nodes
git clone https://github.com/BobJohnson24/ComfyUI-EvalSampler

then restart. No requirements.txt; it leans on what ComfyUI already ships. The gotcha is shared and sharper here: the pack's single module imports comfy_api.latest at the top level, so on an old ComfyUI the whole module fails to load - and that takes down both nodes, not just this one. Keep ComfyUI updated, or neither will appear in your node list.

Analysis is unchanged: put runs in subfolders with the baseline named BF16, then run

python MeasureResults.py --eval-dir <ComfyUI>/output/eval_latents --stratify-std

You get the star-marked metric table, CSV, markdown, and (with matplotlib) an MSE-vs-file-size plot. This node is niche - it's for people who already build custom sampling graphs and also care enough about quantization drift to measure it. If that's not you, the plain EvalSampler gets you the same answer with far less plumbing.

Categorymodel/sampling/custom

Inputs (6)

NameTypeDefaultDescription
noiseNOISE
guiderGUIDER
samplerSAMPLER
sigmasSIGMAS
latent_imageLATENT
output_folderSTRINGeval_latents

Outputs (2)

NameTypeDescription
outputLATENT
denoised_outputLATENT