TAEF2 is very tiny autoencoder which uses the same "latent API" as FLUX.2's VAE.
FLUX.2 is useful for real-time previewing of the FLUX.2 generation process, as well as general resource-constrained encoding/decoding.
NOTE: Unlike TAEF1, TAEF2's architecture
isn't properly integrated into Diffusers yet.
So for now you'll want some wrapper code:
1pip install git+https://www.github.com/huggingface/diffusers # needed for Klein support as of 2026-01-18
2wget -nc -nv https://raw.githubusercontent.com/madebyollin/taesd/refs/heads/main/taesd.py -O taesd.py
3wget -nc -nv https://huggingface.co/madebyollin/taef2/resolve/main/taef2.safetensors -O taef2.safetensors
1# Construction
2from taesd import TAESD
3import torch
4import safetensors.torch as stt
5from diffusers.utils.accelerate_utils import apply_forward_hook
6
7def convert_diffusers_sd_to_taesd(sd):
8 out = {}
9 for k, v in sd.items():
10 encdec, _layers, index, *suffix = k.split(".")
11 offset = 0
12 if encdec == "decoder":
13 offset = +1
14 out[".".join([encdec, str(int(index)+offset), *suffix])] = v
15 return out
16
17class DotDict(dict):
18 __getattr__ = dict.__getitem__
19 __setattr__ = dict.__setitem__
20
21class DiffusersTAEF2Wrapper(torch.nn.Module):
22 def __init__(self):
23 super().__init__()
24 self.dtype = torch.bfloat16
25 self.taesd = TAESD(encoder_path=None, decoder_path=None, latent_channels=32, arch_variant="flux_2").to(self.dtype)
26 self.taesd.load_state_dict(convert_diffusers_sd_to_taesd(stt.load_file("taef2.safetensors")))
27 self.bn = torch.nn.BatchNorm2d(128, affine=False, eps=0.0) # default bn
28 self.config = DotDict(batch_norm_eps=self.bn.eps)
29
30 @apply_forward_hook
31 def encode(self, x):
32 return DotDict(latent_dist=DotDict(sample=lambda : self.taesd.encoder(x.to(self.dtype).mul(0.5).add_(0.5)).to(x.dtype)))
33
34 @apply_forward_hook
35 def decode(self, x, return_dict=True):
36 x = self.taesd.decoder(x.to(self.dtype)).mul(2).sub_(1).clamp_(-1, 1).to(x.dtype)
37 return dict(sample=x) if return_dict else x,
38
39taef2_diffusers = DiffusersTAEF2Wrapper().eval().requires_grad_(False)
40
41# Usage
42from diffusers import Flux2KleinPipeline
43
44device = "cuda"
45dtype = torch.bfloat16
46
47pipe = Flux2KleinPipeline.from_pretrained("black-forest-labs/FLUX.2-klein-4B", torch_dtype=dtype)
48pipe.vae = taef2_diffusers
49pipe.enable_sequential_cpu_offload() # pipe.enable_model_cpu_offload() # pipe = pipe.to(device)
50
51prompt = "A slice of delicious New York-style berry cheesecake"
52image = pipe(
53 prompt=prompt,
54 height=1024,
55 width=1024,
56 guidance_scale=1.0,
57 num_inference_steps=4,
58 generator=torch.Generator(device="cpu").manual_seed(0)
59).images[0]
60image.save("flux-klein.png")
61image