Flipfloppersamearch
The model-weaving party trick
- model1
- model2
- vae1
- vae2
- positive1
- negative1
- positive2
- negative2
- latent_image
- LATENT
- FINAL_VAE
FlipFlopper SameArch is a sampler that alternates between two checkpoints inside a single sampling run. Model 1 runs for a few steps, hands the latent to model 2, which runs for a few steps, and so on until you hit steps. Instead of merging weights or doing one model's output as another model's img2img, you're weaving two models through the same denoising pass - and the results can be genuinely unlike anything either checkpoint produces alone.
The "SameArch" part of the name is the whole deal, not a suggestion. It swaps models mid-latent, so both have to live in the same latent space. SDXL with SDXL, Flux with Flux, SD 1.5 with SD 1.5. Cross an SDXL with an SD 1.5 checkpoint and you'll get mush, because their latents mean different things. This is a nicety for model-blending experiments, not something you'd run on every image.
How it works
Under the hood it's a hand-rolled KSamplerAdvanced loop. It splits your steps into chunks, then runs KSamplerAdvanced once per chunk, alternating model1/model2 - and each model brings its own cfg, sampler, scheduler, and its own positive/negative conditioning. The first chunk always adds noise; intermediate chunks keep "leftover noise" so the next model has something to chew on, and the final chunk cleans up. That's the same chaining trick KSamplerAdvanced uses for partial sampling, just pointed at a different model each time.
Chunk math: the number of passes is steps // chunks, with one extra pass if there's a remainder. With chunks = 1 you flip models every single step, which is chaotic and fun for about a minute. With chunks = 10 on 30 steps, you get three clean handoffs. invert just swaps which model runs first, so you can A/B the same pairing in one go.
The inputs that matter
You'll set the whole top row: model1/model2, plus each model's cfg1/cfg2, sampler_name1/sampler_name2, scheduler1/scheduler2, and its own positive1/negative1/positive2/negative2 conditioning. Then three that steer everything:
steps- total across both models, not per model.chunks- steps per model before the swap. Start at 5–10, not 1.invert- which model leads.
noise_seed is shared across both models, so the noise is consistent between the two phases.
Outputs are simple: LATENT (the finished latent) and FINAL_VAE - the VAE of whichever model ran last, so you can decode without guessing. Wire LATENT into a VAEDecode and feed it FINAL_VAE.
Where people get burned
Read the code before you trust the README, because they disagree. The README promises "supports different VAEs for each model," but the VAE round-trip (decode → re-encode at chunk boundaries) is commented out in the shipped source. vae1/vae2 are required inputs but do nothing except decide which comes back as FINAL_VAE. Just plug the same VAE into both and move on.
Two more inputs are quietly ignored: add_noise and denoise are in the UI but never referenced by the sampling code - the first iteration always adds noise and the loop is driven entirely by steps/chunks. Don't expect denoise to give you partial sampling; it won't.
And it prints a lot. Every iteration logs latent stats, sampler settings, and model IDs to the console. Harmless, but your terminal will be chatty.
Installing it
It's part of the small Comfyui-calbenodes pack, and it's the only dependency-free install you'll get all day:
cd ComfyUI/custom_nodes
git clone https://github.com/caleboleary/Comfyui-calbenodes
then restart ComfyUI. Or use ComfyUI Manager and search for "Comfyui-calbenodes" - either works, and there are no extra pip dependencies to fight with; the pack leans entirely on what ComfyUI already ships. Everything lands under the calbenodes menu.
Should you use it?
Honestly? This is a tinkerer's node from a personal-use pack. If you want a clean two-model blend, a checkpoint merge or a LoRA will get you there with fewer knobs. FlipFlopper is for when you want the texture of switching - different cfg and prompting per model, mid-pass - and you're willing to babysit the console. Fun party trick, and occasionally it produces something you can't get any other way. Just don't hand it a 60-step task with chunks = 1 and expect coherence.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| model1 | MODEL | — | |
| model2 | MODEL | — | |
| vae1 | VAE | — | |
| vae2 | VAE | — | |
| add_noise | COMBO | 2 options: enable, disable | |
| noise_seed | INT | 00–18446744073709550000 | — |
| steps | INT | 201–10000 | — |
| cfg1 | FLOAT | 8.00–100 | — |
| cfg2 | FLOAT | 8.00–100 | — |
| sampler_name1 | COMBO | 34 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +28 | |
| sampler_name2 | COMBO | 34 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +28 | |
| scheduler1 | COMBO | 9 options: normal, karras, exponential, sgm_uniform, simple, ddim_uniform, +3 | |
| scheduler2 | COMBO | 9 options: normal, karras, exponential, sgm_uniform, simple, ddim_uniform, +3 | |
| positive1 | CONDITIONING | — | |
| negative1 | CONDITIONING | — | |
| positive2 | CONDITIONING | — | |
| negative2 | CONDITIONING | — | |
| latent_image | LATENT | — | |
| denoise | FLOAT | 1.000–1 | — |
| chunks | INT | 11–1000 | — |
| invert | COMBO | 2 options: false, true |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |
| FINAL_VAE | VAE | — |