AsymFLUX2
Native ComfyUI v3 nodes for the pixel-space AsymFLUX.2-klein 9B model from LakonLab (Asymmetric Flow Models, arXiv 2605.12964).
Nodes (4)
ComfyUI-AsymFLUX2
[!IMPORTANT] The original authors have released an official node pack: Lakonik/ComfyUI-piFlow. If you're just looking to run AsymFLUX.2 in ComfyUI, you should probably install that instead — it's maintained by the people who trained the model. This repo predates AsymFLUX.2 support landing in piFlow and stays up as an alternative.
ComfyUI nodes for running AsymFLUX.2-klein in pixel space on top of a stock FLUX.2-klein-base-9B safetensors.
AsymFLUX.2 is from the Asymmetric Flow Models paper (arXiv 2605.12964, Chen et al.) and ships as an adapter on top of FLUX.2-klein — the transformer denoises a 3-channel Oklab image directly instead of going through a VAE latent.

Workflow
Load Diffusion Model (FLUX.2-klein-base-9B) ─┐
├─► AsymFLUX2 Apply Adapter ─► KSampler ─► AsymFLUX2 Oklab Decode ─► Save Image
CLIPLoader (Qwen3 8B, type=flux2) ─► CLIPTextEncode (pos / neg) ────┘ ▲
│
AsymFLUX2 Empty Pixel Latent ───────────────────────┘
Example: example_workflows/asymflux2_t2i.json.
Nodes
- AsymFLUX2 Apply Adapter — takes a FLUX.2-klein MODEL + the adapter filename, returns a patched MODEL ready for KSampler.
- AsymFLUX2 Empty Pixel Latent — 3-channel pixel-space empty latent (no /8 VAE downscale).
- AsymFLUX2 Oklab Encode —
IMAGE→ 3-channel OklabLATENT. - AsymFLUX2 Oklab Decode — 3-channel Oklab
LATENT→IMAGE. Goes after KSampler.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Nynxz/ComfyUI-AsymFLUX2
No extra Python deps.
Models you need
- FLUX.2-klein-base-9B safetensors in
ComfyUI/models/diffusion_models/, loaded viaLoad Diffusion Model(UNETLoader). - AsymFLUX.2-klein adapter —
diffusion_pytorch_model.safetensorsfrom the HF repo (~707 MB). Drop intoComfyUI/models/loras/. - Qwen3 8B text encoder for FLUX.2-klein, loaded via single
CLIPLoaderwithtype=flux2.
You'll need to accept the FLUX.2 klein and AsymFLUX.2-klein licenses on Hugging Face.
Settings
Apply Adapter:
| Input | Default | What it does |
| --- | --- | --- |
| shift | 17.0 | Flow shift, paper convention. Converted to comfy's mu = log(shift) internally. |
| adapter_strength | 1.0 | LoRA strength. |
| orthogonal_guidance | 1.0 | Upstream guidance_jit strength. 0.0 = standard CFG. |
| clamp_denoised | True | Per-step Oklab gamut clamp on the x0 estimate. |
KSampler: the example workflow ships uni_pc + simple, 20 steps,
CFG 4.0, at 960 × 1280. UniPC is a multistep solver — its per-step
quality is high enough that 15-25 steps generally matches what a
single-step solver does at 30-50. Pushing it much past ~25 steps tends
to degrade output because the per-step clamp_denoised non-linearity
compounds in the multistep polynomial extrapolation. If you want to
try other samplers: dpmpp_2m and dpmpp_2m_sde at 30-50 steps,
deis at 20-30, all with simple scheduler.
Known limitations
- Output is close to the HF Space
but not identical. Known differences from upstream:
- Static flow shift (we use
17from the paper; upstream uses a resolution-dependent dynamic shift betweenlog(17)andlog(34)). For 960 × 1280 the upstream value lands around20. The gap widens at higher resolutions. - Sampler. Upstream uses
UniPCMultistepintegrated by itsFlowAdapterScheduler. We default touni_pcat 20 steps — comfy's port of the same algorithm — which should track upstream closely. The remaining difference is mostly that comfy'suni_pcruns through a generic-denoised path rather than diffusers'prediction_type='flow_prediction'route; they're mathematically equivalent for our model_sampling but the code path is different.
- Static flow shift (we use
- Image-editing / reference-image conditioning isn't supported. The
upstream
image=kwarg onPixelFlux2KleinPipeline.__call__is plumbing inherited fromFlux2KleinPipeline; output quality on reference-conditioned generation didn't match the t2i output in our testing, so it isn't shipped here. - No Qwen3-VL prompt rewriter (the demo's optional prompt-quality preprocessor — separate model).
How it's wired together
Read the code under asymflux2/ for the details. The short version:
apply_adapter.pyclones the input ModelPatcher, splits the adapter state dict into overwrites and LoRA, and registers everything viaModelPatcher.add_object_patchso the base model is never mutated.model/surgery.pyis where the patches live: replacement Linears forimg_in/final_layer/final_layer.adaLN_modulation[1], the AsymFlowproj_buffer/scale_buffer, a wrappedforwardthat applies AsymFlow calibration + velocity around the originalFlux.forward, and the two optional post-CFG hooks (orthogonal CFG and Oklab gamut clamp).model/asymflow.pyis the AsymFlow math: calibration (k = 1/(s + (1-s)·σ)) and velocity (orthogonal decomposition alongproj_buffer).oklab_math.pyis the Oklab transform pair, used by the encode/decode nodes and the per-step clamp.
The AsymFlow math, the orthogonal CFG, and the Oklab transform each have a synthetic-input unit test verifying they match the upstream LakonLab functions when run on the same tensors. The end-to-end output still depends on sampler choice, schedule discretization, and the static vs dynamic shift, so it's close to but not identical to the HF Space.
Citation & credits
- LakonLab — trained the AsymFLUX.2-klein
adapter and authored the reference
lakonlabimplementation that this node pack reimplements against ComfyUI primitives. - Black Forest Labs — FLUX.2-klein base model.
- ComfyUI — host runtime.
Original paper:
@article{chen2026asymmetric,
title={Asymmetric Flow Models},
author={Hansheng Chen and Jan Ackermann and Minseo Kim and Gordon Wetzstein and Leonidas Guibas},
journal={arXiv preprint arXiv:2605.12964},
url={https://arxiv.org/abs/2605.12964},
year={2026},
}