Texture-Fix-VAE: A Cleaner VAE Decoder for Qwen-Image 2.1

ComfyUI Wikinews

madebyollin's Texture-Fix-VAE retrains the Qwen-Image 2.1 VAE decoder to remove checkerboard texture artifacts. Drop the file into ComfyUI/models/vae and load it as usual.

Texture-Fix-VAE-for-Qwen-Image-2.1 is an unofficial finetune of the Qwen-Image 2.1 VAE decoder. It keeps the exact same latent space, and only retrains the decoder so that fine texture comes back clean instead of checkered. It is a drop-in file: copy it into ComfyUI/models/vae/ and select it in the Load VAE node.

Qwen-Image 2.1 denoises in a compressed latent space, and the VAE decoder is the last step that turns that latent back into pixels. Whatever the decoder cannot reconstruct cleanly is baked into the finished image, no matter how good the sampling was. Users have been describing the symptom since launch: a faint two-pixel grid and a slightly dithery look in busy areas such as foliage, hair and fabric.

Texture-Fix-VAE attacks that step specifically. The encoder is untouched, so the latent format, the sampling schedule and every LoRA or quantized checkpoint keep working unchanged.

Before and after

The author generated the latents for the comparison below with Qwen-Image 2.1 from a photo-style prompt full of fine texture:

Landscape photograph of a subalpine wildflower meadow in the Pacific Northwest in midsummer: a clear mountain stream winding over mossy boulders through purple lupine and red paintbrush, dense old-growth Douglas fir and western red cedar forest behind, a snow-capped volcano in the distance, golden late-afternoon light, highly detailed

Both columns decode the same latents, so any difference is the decoder alone.

Stock Qwen-Image 2.1 VAETexture-Fix-VAE
Stock VAE, zoomed cropTexture-Fix-VAE, same crop
Stock Qwen-Image 2.1 VAETexture-Fix-VAE
Stock VAE, second zoomed cropTexture-Fix-VAE, same crop
Stock Qwen-Image 2.1 VAETexture-Fix-VAE
Stock VAE, full 1024 x 1024 decodeTexture-Fix-VAE, full decode

What changed inside

Only the decoder was finetuned, for roughly 5,000 steps at a learning rate of 3e-5. The two highest-resolution decoder stages and the output head were left unfrozen, which comes to about 7.5M trainable parameters, and training used the recipe the author developed for TAESD.

That recipe mixes three loss families, and each one pushes reconstruction in a different direction:

LossWhat it rewards
MSE / MAE (PSNR-focused)Safe averaging, which blurs detail it cannot place
LPIPSPerceptual plausibility, which for fine texture shows up as blurring plus checkerboarding
Adversarial (GAN)Sharp, plausible detail that looks real instead of obviously synthetic

The adversarial term is what makes the difference here. The author's read is that the original Qwen-Image 2.1 VAE was trained without a working adversarial loss term, which would explain the grid: the perceptual term was free to push toward checkerboarding because nothing was penalising obviously fake structure.

Metrics

MetricQwen-Image 2.1 VAETexture-Fix-VAE
rFID, lower is better (COCO val2017, 5000 images at 256²)3.372.08
PSNR, higher is better (COCO val2017 at 256²)33.3032.86
LPIPS, lower is better (COCO val2017 at 256²)0.03570.0373
PSNR, higher is better (DIV2K valid, native 1024² crops)32.8632.46
LPIPS, lower is better (DIV2K valid, native 1024² crops)0.04600.0480

This is the usual trade for a GAN-style decoder: perceptual quality (rFID) improves by roughly a third while reconstruction accuracy (PSNR and LPIPS) slips very slightly. The author notes the improvement is most visible on detailed, photo-style images rather than flat illustrations.

Using it in ComfyUI

Download texture_fix_vae_for_qwen_image_2.1_bf16.safetensors into ComfyUI/models/vae/, then pick it in the Load VAE node in place of qwen_image_2.1_vae_bf16.safetensors. No node, workflow or sampler change is needed, and the file can be swapped back at any time.

Outside ComfyUI the same weights load as a normal diffusers VAE:

import torch
from diffusers import QwenImage21Pipeline, AutoencoderKLQwenImage21

vae = AutoencoderKLQwenImage21.from_pretrained(
    "madebyollin/texture-fix-vae-for-qwen-image-2.1", torch_dtype=torch.bfloat16
)
pipe = QwenImage21Pipeline.from_pretrained(
    "Qwen/Qwen-Image-2.1", vae=vae, torch_dtype=torch.bfloat16
).to("cuda")

Availability

Weights: madebyollin/texture-fix-vae-for-qwen-image-2.1
ComfyUI file: texture_fix_vae_for_qwen_image_2.1_bf16.safetensors
Base model: Qwen/Qwen-Image-2.1
Author's earlier work: TAESD, sdxl-vae-fp16-fix

Comments

Sign in with GitHub to join the discussion.

Loading comments…
Texture-Fix-VAE: A Cleaner VAE Decoder for Qwen-Image 2.1 | ComfyUI Wiki