EvalSamplerAdvanced
Same Wiretap, Built for the Custom Sampler Graph
- noise
- guider
- sampler
- sigmas
- latent_image
- output
- denoised_output
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 - KSamplerSelect → BasicGuider → BasicScheduler → SamplerCustomAdvanced - 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 byNoise/BasicGuider/KSamplerSelect/BasicSchedulerand friends.latent_image(LATENT) - the starting latents.output_folder- where recordings go underComfyUI/output; defaulteval_latents. Give each model variant its own folder soMeasureResults.pycan 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.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| noise | NOISE | — | |
| guider | GUIDER | — | |
| sampler | SAMPLER | — | |
| sigmas | SIGMAS | — | |
| latent_image | LATENT | — | |
| output_folder | STRING | eval_latents | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| output | LATENT | — |
| denoised_output | LATENT | — |