Inference Time Scaler
Let an AI panel do your seed-rolling
- model
- vae
- positive
- negative
- latent_image
- loaded_clip_score_verifier
- loaded_image_reward_verifier
- loaded_qwen_verifier
- Best Image
- Top-k Grid
- Top-k Score(s)
You know the loop: generate, squint, reroll the seed, repeat until one image survives. Inference Time Scaler automates that whole process - it generates a batch of images from your prompt, hands them to a panel of AI judges, and returns the winner, a grid of the top few, and the scores that decided it. It's the ComfyUI implementation of "Inference-time scaling for diffusion models beyond scaling denoising steps" (Ma et al., Google DeepMind, arXiv:2501.09732), which asked a deceptively simple question: instead of buying quality with more denoising steps, why not buy it with more search?
Let's be honest about what this is before you get excited. It is not a quality dial you flip on - every search round is a full image generation, and every candidate gets scored, so a one-shot generation becomes a 5–30x more expensive one. But if you've ever rerolled a hero image twelve times by hand, that's exactly the compute you were already spending - just with your gut as the judge instead of a model.
How it works
Two algorithms from the paper, picked with search_algorithm:
- random: generate
search_roundsimages, each with its own seed, decode them all through the VAE, and rank. - zero-order: gradient-free local search. Start with one noise vector, generate
num_neighborsvariations that sit on the same noise sphere (cosine similarity =lambda_threshold), score the whole batch, promote the best to the new pivot, and repeat forsearch_roundsiterations.
That "same noise sphere" bit is the interesting part - the neighbor generator is lifted from sayakpaul's tt-scale-flux. Perturbing noise lets the search walk toward better latents instead of hopping blindly. It's cleverer and pricier: each round generates and decodes num_neighbors + 1 images.
The judges are the three verifier loaders in this pack (CLIP, ImageReward, Qwen VLM). Each scores every candidate; the node converts each verifier's raw scores into ranks and averages the rank across verifiers. Ensemble voting, so one weird judge can't hijack the result. You can connect one, two, or all three - but you must connect at least one; the node raises a hard error otherwise.
The inputs that matter
The top of the node is a KSampler wearing a trenchcoat: model, vae, positive, negative, latent_image, seed, steps, cfg, sampler_name, scheduler, denoise. Same rules as always - Flux likes CFG 1 with guidance handled separately, which is exactly how the shipped example wires it.
The three that aren't sampler-y:
text_prompt_to_compare- the prompt the verifiers grade against. Set this to your positive prompt. It's the one people forget, and it's why scores look like garbage when they do.search_rounds- your compute budget. Random: number of images. Zero-order: number of iterations.view_top_k- how many top-ranked images go in the grid output.
Zero-order-only: num_neighbors (default 4) and lambda_threshold (default 0.9, how close neighbors hug the pivot). Ignored entirely under random search.
Outputs: Best Image, Top-k Grid, and Top-k Score(s) - a JSON string with per-verifier scores and the average rank per candidate. Wire that into a ShowText node and you can see exactly why the winner won.
Install
ComfyUI Manager: search "ComfyUI-InferenceTimeScaling", install, restart. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/YRIKKA/ComfyUI-InferenceTimeScaling
cd ComfyUI-InferenceTimeScaling
pip install -e .
Fair warning: the dependency list is heavy and pinned - transformers==4.49.0, outlines==0.2.0, image_reward==1.5, open-clip-torch, plus OpenAI's CLIP built from source (you need a compiler). ComfyUI doesn't ship most of these, so if a Manager-only install throws import errors, run that pip install -e . inside the folder. And because it pins transformers, go easy if your other custom nodes share the environment.
Where people get burned
- VRAM. The README was developed on an L40S (48GB) with 62GB of RAM, and it shows. Qwen 7B alone is ~18GB in fp16, sitting alongside your diffusion model and the other verifiers. Don't be surprised when this needs more than a 24GB card has.
- Speed. The output is 100% worth it for a handful of hero images and a trap if you queue a batch. Batch size is hard-coded to 1.
- Silent failure mode. If something throws, the node returns a blank image and puts the error inside the JSON output. If you get black outputs, read the scores string before assuming the pack is broken.
It's an obscure pack with a tiny footprint, so you're somewhat on your own. But the mechanism is sound, the paper it implements is legit, and for "I need this one image to be great," this is the most honest way to spend your compute.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | Denoising model. | |
| vae | VAE | VAE model for decoding latents. | |
| seed | INT | 00–18446744073709550000 | Random seed. |
| steps | INT | 201–10000 | Number of denoising steps to apply during each forward evaluation. |
| cfg | FLOAT | 1.00–100 | Classifier-Free Guidance Scale. |
| sampler_name | COMBO | Sampling algorithm to be used during each forward evaluation. | |
| scheduler | COMBO | Noise removal scheduler. | |
| positive | CONDITIONING | Positive prompt conditioning. | |
| negative | CONDITIONING | Negative prompt conditioning. | |
| latent_image | LATENT | Latent image to be denoised. | |
| denoise | FLOAT | 1.000–1 | Amount of denoising. |
| search_algorithm | COMBO | random | Select the search algorithm: 'random' for standard random search or 'zero-order' for gradient-free local search. |
| text_prompt_to_compare | STRING | Text prompt for verifier(s). | |
| search_rounds | INT | 51–10000 | Number of search rounds (random seeds for random search, or iterations for zero-order search). |
| view_top_k | INT | 31–100 | Return grid view of the top-k images. |
| num_neighbors | INT | 41–100 | Number of neighbors to sample per iteration in zero-order search (only used if search_algorithm is 'zero-order'). |
| lambda_threshold | FLOAT | 0.900–1 | Perturbation step size for zero-order search (only used if search_algorithm is 'zero-order'). |
| loaded_clip_score_verifieropt | CS_VERIFIER | HF CLIP model identifier. | |
| loaded_image_reward_verifieropt | IR_VERIFIER | ImageReward model identifier. | |
| loaded_qwen_verifieropt | QWN_VERIFIER | Qwen model identifier. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| Best Image | IMAGE | Best single image, grid of the top-k images, and their scores in JSON. |
| Top-k Grid | IMAGE | — |
| Top-k Score(s) | STRING | — |