VAE Merge SDXL Block
Mix two SDXL VAEs stage by stage, not all at once
- vae1
- vae2
- VAE
If VAE Merge Simple is the "just blend the whole thing" dial, VAE Merge SDXL Block is the surgical version: it blends two SDXL VAEs per architectural stage, so you can keep vae1's encoder and swap in vae2's decoder, or take vae2's mid block while keeping everything else. Each of the 23 ratio widgets targets one block, and each runs 0.0 to 1.0 - at 0.0 that block is pure vae1, at 1.0 it's pure vae2, in between it's a straight weighted blend.
Why per-block control exists
VAEs aren't homogeneous blobs - encoder and decoder do genuinely different jobs, and within the decoder the first up blocks (which turn coarse latents back into broad structure) are different territory from the final conv that produces pixel color. If your goal is a decoder swap - say, you like vae1's overall pipeline but want vae2's texture behavior - a whole-VAE blend drags the encoder along whether you wanted it or not. Block merging lets you keep the parts you like and replace only the part you don't.
That said, let's be honest about demand: most SDXL users never merge a VAE at all, and when they do it's usually a whole-VAE ratio blend. Block-level control is for when you've actually diagnosed a specific stage as the problem, which usually means you've spent some time with the pack's scale nodes figuring out what each block does first.
How it works
Same engine as the other merges: both VAEs' state dicts are read out, and for each tensor the node picks the ratio whose key is the longest matching prefix - decoder.up.2. beats decoder.up., so each stage blends independently. The formula per matching key is vae1 × (1 − ratio) + vae2 × ratio. The result is a fully materialized VAE in memory (nothing saved to disk by itself), and it comes out the single VAE socket ready to feed VAEDecode or a VAE-save node.
The rules that keep it sane
Only merge VAEs that share the SDXL architecture - both inputs must be SDXL VAEs. The node assumes ldm-style SDXL key names (encoder.down.0., decoder.mid.attn_1., and so on), so feeding it a Flux or Qwen VAE won't blend, it'll just copy mismatched keys around into something that decodes to noise. Same architecture, 4-channel latents, and you're safe.
Installing it
From the easygoing0114/ComfyUI-easygoing-nodes pack: ComfyUI Manager → search Easygoing, or:
cd ComfyUI/custom_nodes
git clone https://github.com/easygoing0114/ComfyUI-easygoing-nodes.git
Restart. No downloads, no extra pip packages. It's built on the V3 node API, so keep ComfyUI itself current or the nodes won't register.
A genuinely niche tool - but if you've ever wished you could keep one VAE's encoder and another's decoder, this is the only kind of node that can do it cleanly.
Inputs (24)
| Name | Type | Default | Description |
|---|---|---|---|
| vae1 | VAE | — | |
| vae2 | VAE | — | |
| quant_conv | FLOAT | 0.500–1 | — |
| post_quant_conv | FLOAT | 0.500–1 | — |
| encoder.conv_in | FLOAT | 0.500–1 | — |
| encoder.down.0. | FLOAT | 0.500–1 | — |
| encoder.down.1. | FLOAT | 0.500–1 | — |
| encoder.down.2. | FLOAT | 0.500–1 | — |
| encoder.down.3. | FLOAT | 0.500–1 | — |
| encoder.mid.attn_1. | FLOAT | 0.500–1 | — |
| encoder.mid.block_1. | FLOAT | 0.500–1 | — |
| encoder.mid.block_2. | FLOAT | 0.500–1 | — |
| encoder.norm_out | FLOAT | 0.500–1 | — |
| encoder.conv_out | FLOAT | 0.500–1 | — |
| decoder.conv_in | FLOAT | 0.500–1 | — |
| decoder.mid.attn_1. | FLOAT | 0.500–1 | — |
| decoder.mid.block_1. | FLOAT | 0.500–1 | — |
| decoder.mid.block_2. | FLOAT | 0.500–1 | — |
| decoder.up.0. | FLOAT | 0.500–1 | — |
| decoder.up.1. | FLOAT | 0.500–1 | — |
| decoder.up.2. | FLOAT | 0.500–1 | — |
| decoder.up.3. | FLOAT | 0.500–1 | — |
| decoder.norm_out | FLOAT | 0.500–1 | — |
| decoder.conv_out | FLOAT | 0.500–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| VAE | VAE | — |