Nodes/AsymFLUX2/AsymFLUX2 Empty Pixel Latent
ComfyUI Node

AsymFLUX2 Empty Pixel Latent

The pixel-space latent that has no VAE behind it

By Nynxz·Created 4 months ago·Updated 3 months ago· 13
AsymFLUX2 Empty Pixel Latent
    • latent
    width960
    height1280
    batch_size1

    Every normal ComfyUI workflow starts a generation with an empty latent from EmptyLatentImage or EmptySD3LatentImage, and AsymFLUX2 needs the same thing - except its "latent" is a 3-channel Oklab image at full resolution, not a 16-channel VAE feature map at one-eighth resolution. That's what this node emits: a tensor of zeros shaped [batch, 3, height, width], ready for the AsymFLUX2 transformer to start denoising.

    You won't use it outside this pack, and inside it you have no choice but to use it. Drop a stock EmptyLatentImage into the graph and the patched model's 3-channel latent format will fight ComfyUI's channel-inflation logic - the whole reason this node exists is that a plain empty latent would get blown up to the stock Flux channel count and the model would choke. It mirrors the upstream PixelFlux2KleinPipeline.prepare_latents shape, and it cribs the design from HiDream-O1's EmptyHiDreamO1LatentImage (ComfyUI PR #13817). That lineage is the tell: this is the "no-VAE" family of models, and the "VAE" for AsymFLUX2 is just the Oklab color transform pair.

    The inputs - all three of them

    That's the whole widget. width (960) and height (1280) snap down to the nearest multiple of 16, so the model's 16×16 patch token grid comes out integral. Request 1000 and you get 992; request 960 and you get exactly 960. Don't expect ComfyUI's usual latent math - 512 in, 64-latent out. Here the spatial size is 1:1 with the output image. batch_size is the count, default 1, and the only reason you'd raise it is batching on a big card.

    Output is one latent, wired straight into a KSampler's latent input. After sampling, AsymFLUX2 Oklab Decode turns the result back into an image. The Apply Adapter node has already installed a 3-channel pass-through latent format, so the KSampler leaves your zeros alone instead of reshaping them.

    Why resolution is the whole story

    No VAE downscale sounds like a win until you remember why VAEs exist in the first place: the latent is a workaround for pixel-space diffusion being too slow. At 960×1280 the token count is (960/16) × (1280/16) = 4800 tokens per image, every one of them 768-wide, and the transformer computes over all of them at full pixel resolution. That's the compute tax this architecture pays, and it's why the whole pixel-space wave - HiDream-O1, the L2P conversions, this - reads as a movement but hasn't displaced latent models for volume work. On the plus side, there's no encode-decode round trip to accumulate loss, which is the argument for the whole family: recursive editing doesn't grind the image down.

    The known downside, visible on AsymFLUX.2 too, is that pixel-space output tends toward a "blobby" look in fine details that a VAE would have cleaned up. Small stuff at 100% zoom, not a dealbreaker. If your goal is rapid prompt iteration you'd be happier with the distilled Klein at CFG 1 - but that's a different workflow entirely.

    Install and gotchas

    Same pack install as everything here:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Nynxz/ComfyUI-AsymFLUX2
    

    No Python deps for this node. It generates zeros on your compute device, so it's the cheapest node in the graph - the expensive part is the model stack behind it: FLUX.2-klein-base-9B in models/diffusion_models/, the AsymFLUX.2 adapter in models/loras/, and the Qwen3 8B encoder via CLIPLoader (type=flux2), with the FLUX.2-klein and AsymFLUX.2 licenses accepted on Hugging Face. The whole pack uses ComfyUI's newer native-node API, so update ComfyUI before you file a bug report.

    If the graph errors on latent channels, you used the wrong empty-latent node. And a genuinely honest heads-up: the model's authors now maintain the official ComfyUI-piFlow pack, which this repo's own README points you to first. This one stays as the working alternative - and if you're here, this node is where you set the render cost, so keep the resolution honest and you'll be fine.

    CategoryAsymFLUX2

    Inputs (3)

    NameTypeDefaultDescription
    widthINT960128–4096Output width. Snapped down to a multiple of 16.
    heightINT1280128–4096Output height. Snapped down to a multiple of 16.
    batch_sizeINT11–64

    Outputs (1)

    NameTypeDescription
    latentLATENT