TwinFlow KSampler
The all-in-one that makes TwinFlow worth installing
- model
- positive
- negative
- latent_image
- LATENT
You've seen the demo: a Z-Image or Qwen-Image render in 2-4 steps, close enough to "instant" that it doesn't feel like diffusion anymore. That's TwinFlow - inclusionAI's one-step / few-step distillation from the self-adversarial flows paper (Dec 2025) - and the TwinFlow KSampler is the node you grab to actually run it in ComfyUI. It's the pack's "just make it work" box: patch the model, wire in your conditioning and a latent, and it handles the scheduler and the sampler internally.
It exists for a reason beyond convenience. TwinFlow is a rectified-flow distillation, and it needs its own sampling logic. Drop a stock KSampler with Euler onto a patched TwinFlow model and you get washed-out results - the community said it plainly at launch: "you need to use a special sampler otherwise results will be bad." This node is that special sampler, packaged with its matching schedule so there's less left for you to get wrong.
How it works
Under the hood it's three things the stock KSampler doesn't have:
- A Kumaraswamy-transformed time grid (
dist_ctrl_a/b/c) confined to a slice of the 0→1 flow viagap_startandgap_end. That's the schedule half. - A TwinFlow-specific sampler: 1st-order Euler or 2nd-order Heun, with two dials controlling how it steps along the flow.
- A target-timestep mechanism - the sampler tells the model where it's aiming on each step, which is the conditioning the patcher depends on.
Everything else mirrors a normal KSampler (noise prep, CFG, denoise, noise mask), so the wiring feels familiar. Output is a single LATENT - decode it with the usual VAE node.
The inputs that matter
There are 17, and you can ignore most once you get one thing right: the model must come out of TwinFlow Model Patcher, not straight from the loader. After that, the few you'll actually touch:
- sampling_style -
few(2-4 steps, the headline mode),any(flexible step counts),mul(multi-step). The most consequential dropdown. - sampling_method -
euler(default) orheun(2nd order, a bit cleaner, a bit slower). - steps - default 4; drop to 2 with
fewfor the real speed run. - cfg - default 1.0. These are guidance-distilled flow models, and the whole distillation-era lesson applies: keep it near 1 or you burn the image.
- stochast_ratio (default 1.0) and extrapol_ratio (0.0) - stochasticity and extrapolation dials. The defaults are what the authors ship; treat them as "don't touch until you're experimenting."
- gap_start / gap_end - where in the flow the steps live. Defaults are sane.
Installing it
ComfyUI Manager, search "TwinFlow" - or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/mengqin/ComfyUI-TwinFlow.git
pip install -r requirements.txt
Dependencies are light: safetensors and gguf>=0.6.0 (the GGUF one only matters if you use GGUF patch or base files). Restart ComfyUI after. There are no model downloads - you bring the TwinFlow weights yourself (e.g. TwinFlow_Z_Image_Turbo_bf16.safetensors or inclusionAI's Qwen-Image TwinFlow release on HuggingFace) and drop them in ComfyUI/models/unet/.
When it goes wrong
- Output looks like ordinary, un-patched Z-Image/Qwen - you skipped the patcher, or the patch file's key prefixes don't match your model's embedder names. The patcher is mandatory, not optional.
- GGUF stubbornness - some HuggingFace GGUF conversions carry the wrong architecture field (
"qwen"instead of"qwen_image") and won't load. Grab a corrected conversion or fix the metadata. - The quality tradeoff - few-step distilled output is softer than the full model. That's the deal distillation always makes, and TwinFlow isn't the exception; community tests on Z-Image found GGUF Q4 rough, Q6 acceptable.
One honest caveat: this pack is young and small, and the author has said upkeep's been thin lately. There's also a competing implementation (smthemex/ComfyUI_TwinFlow) built with its own self-contained loader and sampler - it won't mix with this one. Pick this pack for standard inputs and LoRA compatibility, and don't load workflows from both.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 41–100 | — |
| cfg | FLOAT | 1.00–100 | — |
| sampling_method | COMBO | euler | 2 options: euler, heun |
| sampling_style | COMBO | few | 3 options: few, any, mul |
| stochast_ratio | FLOAT | 1.000–1 | — |
| extrapol_ratio | FLOAT | 0.000–1 | — |
| dist_ctrl_a | FLOAT | 1.000.01–10 | — |
| dist_ctrl_b | FLOAT | 1.000.01–10 | — |
| dist_ctrl_c | FLOAT | 1.000.01–10 | — |
| gap_start | FLOAT | 0.0010–1 | — |
| gap_end | FLOAT | 0.6000–1 | — |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| latent_image | LATENT | — | |
| denoise | FLOAT | 1.000–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |