Conduit Speculative KSampler
Roll several seeds, keep the best
- model
- clip
- vae
- positive
- negative
- latent_image
- best_latent
- best_seed
- best_score
Conduit Speculative KSampler is the pack's flagship - the one node that does what the README's flashiest claims describe. Instead of running one seed to completion and hoping, it starts several seeds, samples all of them partway, picks a winner, and finishes only that one. The pitch is that you get the reliability of trying multiple seeds without paying for all of them in full. It's a real, working sampler, and it's the node most worth installing from this pack.
How it works
It takes everything a KSampler takes - model, clip, vae, positive, negative, latent_image, steps, cfg, sampler_name, scheduler, denoise - plus the speculative knobs. On each run it:
- Generates
num_branchesseeds starting frombase_seed(each branch offset by 1000). - Samples every branch up to the checkpoint step:
checkpoint_pct×steps(default 30%, tooltip "When to score and prune (as fraction of steps)"). - Scores each partial latent, keeps the best.
- Continues the winner from the checkpoint to completion and returns it.
Outputs are best_latent (LATENT - straight into your VAE decode), best_seed (INT, "Seed that produced best result"), and best_score (FLOAT). There's also an optional scoring_prompt ("Prompt for CLIP scoring (uses positive if empty)").
The honesty section - read this before you trust the scores
The tooltips and the scoring_method naming (clip_similarity, aesthetic, hybrid) suggest CLIP-based scoring, and scoring_prompt implies the score measures prompt alignment. The actual code does none of that: _score_latent decodes nothing and runs no CLIP. Its scoring is a heuristic over latent statistics - higher variance and lower absolute mean score better, on the theory that a good latent has detail and isn't drifting. The source comments say it plainly: "This is simplified - full implementation would use CLIP properly." So the scores are plausibility signals, not prompt-fidelity measurements. The practical consequence: this node is best for "which seed converges cleanly," and its notion of "best" may not match the image you'd actually prefer. And one more honest note - the README says the branches run "in parallel," but the implementation runs them sequentially in a loop. The math still works; the wall-clock claim is just optimistic.
Tuning it
num_branches(default 4, 2–8) - more seeds = better odds, but you pay for the full early segment of each one.checkpoint_pct(default 0.3, 0.1–0.5) - earlier checkpoints prune sooner but score noisier latents.base_seed- the anchor; branches arebase_seed + i*1000.
The compute math is easy to sanity-check: with 4 branches at 30%, you run 4×30% then 1×70% = 190% of a single run's work instead of 400% - roughly half off, which is exactly the README's "~50% compute cost." With 8 branches it's 8×30% + 70% = 310% of one run: still a big saving versus 800%, but the upfront cost climbs, so don't set 8 branches unless the checkpoint is early.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/joe002/comfyui-conduit-optimizer
Or ComfyUI Manager → search "comfyui-conduit-optimizer" → restart. No model downloads; PyTorch 2.0+ is the only dependency. Startup logs [CONDUIT] v1.1.0 loaded: 13 optimization nodes.
Common issues
Two things get people. First, the scoring being a heuristic means the "best" latent is occasionally a dud by your standards - if you're after prompt adherence specifically, generate the returned best_seed with a normal KSampler and compare; you can even use it as a seed-finder, then lock that seed in. Second, expect the console to be chatty - it prints every branch's progress and score, which is great for understanding what happened and noisy when you just wanted an image. And if you change checkpoints, remember the pack's caches aren't model-aware: clear them (ConduitCacheClear) or they can serve stale results.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| clip | CLIP | — | |
| vae | VAE | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| latent_image | LATENT | — | |
| base_seed | INT | 00–18446744073709550000 | — |
| num_branches | INT | 42–8 | Number of parallel generations |
| checkpoint_pct | FLOAT | 0.300.1–0.5 | When to score and prune (as fraction of steps) |
| steps | INT | 201–150 | — |
| cfg | FLOAT | 7.00–100 | — |
| sampler_name | COMBO | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 | |
| scheduler | COMBO | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 | |
| denoise | FLOAT | 1.000–1 | — |
| scoring_promptopt | STRING | Prompt for CLIP scoring (uses positive if empty) |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| best_latent | LATENT | Best latent from speculative generation |
| best_seed | INT | Seed that produced best result |
| best_score | FLOAT | Score of best result |