Diffusers documentation
FLUX 3 Image Klein
FLUX 3 Image Klein
FLUX 3 Image Klein is a 5.6B image generation model from Black Forest Labs: a single transformer (Flux3Transformer2DModel) generates images from a text prompt, alone or together with one or more reference images. Text conditioning comes from Qwen3-VL, and images use the FLUX.2 packed autoencoder (AutoencoderKLFlux2).
FLUX 3 Image Klein ships as a modular pipeline. Prompting matters: the model responds best to full scene captions that describe the subject, composition, lighting, and atmosphere, so the pipeline runs the prompt upsampler first on every request, text-to-image and editing alike. It is a separate 9B model from Black Forest Labs (black-forest-labs/flux-3-image-klein-pup) that expands prompt into such a caption before the text encoder, and a short prompt is all it takes. Get started with a text-to-image generation:
import torch
from diffusers import ModularPipeline
pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base")
pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
pipe.to("cuda")
out = pipe(
prompt="A red fox in a snow-covered forest clearing at golden hour",
generator=torch.Generator().manual_seed(0),
output=["images", "prompt"],
)
out["images"][0].save("fox.png")
print(out["prompt"]) # the caption the image model receivedprompt is the only required input: the pipeline carries the recommended sampling settings (50 steps, guidance scale 3.5, scheduler shift 6.93) and generates 1024 x 1024 images by default. It takes one prompt per call; use num_images_per_prompt for several images of the same prompt.
Prompt upsampling
The prompt upsampler turns a short request, together with the reference images when editing, into the full scene caption the model takes: medium and style, scene, lighting and camera, each subject with its colors, materials and position in the frame. One model covers text-to-image, editing with reference images and layout with boxes; the step picks the task from the inputs, like the rest of the pipeline. Its two components, prompt_upsampler and prompt_upsampler_processor, load from the upsampler repository with the others. The caption it wrote comes back as the prompt output, as above; max_new_tokens caps its length (3584 by default).
To send a caption as given, one you wrote in full or got from another LLM, build the pipeline without the step:
blocks = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base").blocks
blocks.sub_blocks.pop("prompt_upsampler")
plain = blocks.init_pipeline("black-forest-labs/flux-3-image-klein-base")
plain.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
plain.to("cuda")
image = plain(prompt=caption, generator=torch.Generator().manual_seed(0), output="images")[0]Any other LLM can write the caption: give it the system prompt for the task from the upsampler repository’s system_prompts.json (t2i, or i2i with the references first in the user message) and the request as the user message, and pass what it returns as prompt to the pipeline without the step.
The step also runs on its own, to write captions without generating:
pup = pipe.blocks.sub_blocks["prompt_upsampler"].init_pipeline("black-forest-labs/flux-3-image-klein-base")
pup.load_components(dtype=torch.bfloat16)
pup.to("cuda")
caption = pup(prompt="A red fox in a snow-covered forest clearing at golden hour", output="prompt")Image-to-image
Pass one or more reference images with image. Every reference keeps its own resolution (center-cropped to the 16-pixel grid; references above 16 megapixels are downscaled first), and the generation size defaults to one megapixel at the first reference’s aspect ratio. The prompt the image model takes is the target image as a complete caption of the reference with the edit folded in, not a one-line instruction; the upsampler sees the references too and writes it from your instruction: what to keep, what to change.
night = pipe(
prompt="the same scene at night under a full moon",
image=image,
generator=torch.Generator().manual_seed(0),
output=["images", "prompt"],
)With several references, refer to them as the first image, the second image, … in the order they are passed to image; the caption names them <ref_image_0>, <ref_image_1>, … for the image model:
combined = pipe(
prompt="the fox from the first image sitting on the wooden bench from the second image",
image=[image, bench],
height=768,
width=1360,
output="images",
)[0]Pass height and/or width to override the derived size.
Layout control
To place content explicitly, pass boxes: for each element an id, a short desc, and a bbox of [y_min, x_min, y_max, x_max] in 0-1 (origin top-left), so it is independent of the output size. The upsampler writes the caption around them, citing each element as <id>, and appends the table of boxes, yours kept exactly:
boxes = [
{"id": "balloon_1", "desc": "a red and yellow striped hot-air balloon", "bbox": [0.08, 0.06, 0.48, 0.38]},
{"id": "balloon_2", "desc": "a small blue hot-air balloon", "bbox": [0.20, 0.62, 0.42, 0.80]},
]
out = pipe(prompt="hot-air balloons over a green valley at sunrise", boxes=boxes, output=["images", "prompt"])When editing, a box names its source with from: "target" with a tgt_bbox adds a new element there, "ref_image_0" with a src_bbox and a tgt_bbox moves an element of that reference (equal boxes keep it in place):
boxes = [{"id": "cactus", "desc": "a small potted cactus", "from": "target", "src_bbox": None, "tgt_bbox": [0.55, 0.62, 0.85, 0.85]}]
out = pipe(prompt="add a small potted cactus in the marked spot", image=mug, boxes=boxes, output=["images", "prompt"])
boxes = [{"id": "knight", "desc": "the knight figure", "from": "ref_image_0", "src_bbox": [0.50, 0.15, 0.85, 0.35], "tgt_bbox": [0.19, 0.06, 0.54, 0.26]}]
out = pipe(prompt="move the knight up and to the left, keep the rest unchanged", image=knight, boxes=boxes, output=["images", "prompt"])The caption the image model reads has the elements tagged <id> in the text and the table appended as JSON, with the boxes on a 0-1000 canvas; print the prompt output to see it. A caption written in that form by hand goes to the pipeline without the step, as in Prompt upsampling.
Guidance scale
The pipeline applies classifier-free guidance through its guider component and does not take a guidance_scale argument at call time. The default guider is ClassifierFreeGuidance with guidance_scale=3.5, the recommended setting for both workflows. To change it, create an updated copy of the guider:
pipe.guider = pipe.guider.new(guidance_scale=5.0)See the guiders guide to switch to a different guidance method.
Step-distilled model
The step-distilled checkpoint generates in 16 steps without classifier-free guidance. Its transformer is a flow map: at every step it is told the current timestep and the one the step jumps to. It loads like the base model (the repo’s modular_model_index.json resolves to Flux3DistilledModularPipeline and Flux3DistilledAutoBlocks); the pipeline has no guider and does not take negative_prompt:
pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein")
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")
image = pipe(prompt=prompt, generator=torch.Generator().manual_seed(0), output="images")[0]It serves the same two workflows as the base model. num_inference_steps defaults to 16; the model is trained for 4 to 16 steps.
Reproducible generation
A generator fixes the noise the pipeline draws (see Reproducibility). To reuse noise drawn elsewhere, pass it as latents with shape (batch_size, 128, height // 16, width // 16). For example, the BFL implementation draws its noise as image tokens on the CPU and casts it to bf16; this reproduces its sample for a given seed:
height, width = 1024, 1024
h, w = height // 16, width // 16
noise = torch.randn((h * w, 128), generator=torch.Generator().manual_seed(0)).to(torch.bfloat16)
latents = noise.T.reshape(1, 128, h, w)
image = pipe(prompt=prompt, latents=latents, height=height, width=width, output="images")[0]Workflows
The pipeline serves two workflows, text2image and image_conditioned; the one that runs is picked by the inputs (image selects image-to-image). from_pretrained() can also build a pipeline for one workflow with the workflow argument, which then only expects and loads the components that workflow needs:
from diffusers.modular_pipelines import Flux3AutoBlocks
print(Flux3AutoBlocks().available_workflows)
# ["text2image", "image_conditioned"]
t2i = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base", workflow="text2image")
print(t2i.blocks.doc)Memory
Loading everything in bf16 takes about 39 GB of weights: the transformer is 5.5B parameters, the Qwen3-VL-4B text encoder 4B and the prompt upsampler 9B (about 19 GB on its own), with the image VAE in fp32. A pipeline built without the upsampler step (see there) loads about 20 GB. For GPUs with less memory, enable component offloading; the manager moves components between the CPU and the GPU as each step needs them, the upsampler included:
from diffusers import ComponentsManager, ModularPipeline
manager = ComponentsManager()
pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base", components_manager=manager)
pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
manager.enable_auto_cpu_offload(device="cuda")Single-file loading
Flux3Transformer2DModel loads the transformer straight from a Black Forest Labs model package with from_single_file(). The package config.json is not read; pass the diffusers config with config and subfolder.
import torch
from diffusers import Flux3Transformer2DModel, ModularPipeline
transformer = Flux3Transformer2DModel.from_single_file(
"https://huggingface.co/black-forest-labs/flux-3-image-klein-base/blob/main/model.safetensors",
config="black-forest-labs/flux-3-image-klein-base",
subfolder="transformer",
dtype=torch.bfloat16,
)
pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base")
pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
pipe.update_components(transformer=transformer)
pipe.to("cuda")Load the other components by name first: load_components() without names would also load the transformer from the pipeline repo.
Loading the FP8r and NVFP4 single-file checkpoints are also supported. Both load through the same call with a BFLQuantizationConfig. See the BFL quantization guide for the kernel requirements of each scheme.
from diffusers import BFLQuantizationConfig
transformer = Flux3Transformer2DModel.from_single_file(
"https://huggingface.co/black-forest-labs/flux-3-image-klein-base/blob/main/variants/nvfp4/model.safetensors",
config="black-forest-labs/flux-3-image-klein-base",
subfolder="transformer",
quantization_config=BFLQuantizationConfig(compute_dtype=torch.bfloat16),
dtype=torch.bfloat16,
)When loading the step-distilled checkpoints, we need their
configs (flow_map=True):
transformer = Flux3Transformer2DModel.from_single_file(
"https://huggingface.co/black-forest-labs/flux-3-image-klein/blob/main/variants/nvfp4/model.safetensors",
config="black-forest-labs/flux-3-image-klein",
subfolder="transformer",
quantization_config=BFLQuantizationConfig(compute_dtype=torch.bfloat16),
dtype=torch.bfloat16,
)Flux3ModularPipeline
class diffusers.Flux3ModularPipeline
< source >( blocks: diffusers.modular_pipelines.modular_pipeline.ModularPipelineBlocks | None = Nonepretrained_model_name_or_path: str | os.PathLike | None = Nonecomponents_manager: diffusers.modular_pipelines.components_manager.ComponentsManager | None = Nonecollection: str | None = Noneworkflow: str | None = Nonemodular_config_dict: dict[str, typing.Any] | None = Noneconfig_dict: dict[str, typing.Any] | None = None**kwargs )
A ModularPipeline for FLUX.3.
Flux3AutoBlocks
Auto blocks that perform text-to-image and image-to-image generation using FLUX.3. prompt goes through the prompt
upsampler first; pop the prompt_upsampler step to encode it as given.
Supported workflows:
text2image: requirespromptimage_conditioned: requiresprompt,image
Components:
prompt_upsampler (Qwen3_5ForConditionalGeneration): The prompt upsampler. prompt_upsampler_processor
(AutoProcessor): Its processor. text_encoder (Qwen3VLForConditionalGeneration) tokenizer
(AutoProcessor) image_processor (Flux3ImageProcessor) vae (AutoencoderKLFlux2) transformer
(Flux3Transformer2DModel) scheduler (FlowMatchEulerDiscreteScheduler) guider (ClassifierFreeGuidance)
Inputs:
prompt (str):
The edit instruction to expand into the full caption (one per call).
image (Image | list, optional):
The reference image(s) of the edit, at most 10; the same ones the pipeline receives.
boxes (list, optional):
Layout boxes, each {‘id’, ‘desc’, ‘from’, ‘src_bbox’, ‘tgt_bbox’} with the boxes as [y_min, x_min, y_max,
x_max] in 0-1: ‘from’: ‘target’ with tgt_bbox adds an element there, ‘from’: ‘ref_image_0’, … with src_bbox and tgt_bbox moves one from a reference image.
max_new_tokens (int, optional, defaults to 3584):
The most tokens the upsampler may generate for the caption.
negative_prompt (str, optional):
The prompt not to guide the generation
max_sequence_length (int, optional, defaults to 8192):
Maximum number of prompt tokens; longer prompts are truncated.
text_encoder_out_layers (tuple, optional, defaults to (4, 8, 12, 16, 20, 24, 28, 32)):
Indices of the text-encoder hidden layers whose states are stacked to form the text embeddings
num_images_per_prompt (int, optional, defaults to 1):
The number of images to generate per prompt.
image_cond_latents (list, optional):
Normalized packed latents of the reference images, one tensor of shape (B, C, height_i//16, width_i//16)
per image
height (int, optional, defaults to None or 1024, depending on the workflow):
The height in pixels of the generated image; defaults to the first reference image’s aspect ratio at the
default area
width (int, optional, defaults to None or 1024, depending on the workflow):
The width in pixels of the generated image; defaults to the first reference image’s aspect ratio at the
default area
latents (Tensor):
Pre-generated noisy latents for image generation.
generator (Generator, optional):
Torch generator for deterministic generation.
num_inference_steps (int):
The number of denoising steps.
timesteps (Tensor):
Timesteps for the denoising process. (overrides num_inference_steps when provided)
sigmas (list, optional):
Custom sigmas for the denoising process. (overrides num_inference_steps when provided)
*denoiser_input_fields (None,optional):
conditional model inputs for the denoiser: e.g. prompt_embeds, negative_prompt_embeds, etc.
attention_kwargs (dict,optional):
Additional kwargs for attention processors.
output_type (str,optional*, defaults to pil):
Output format: ‘pil’, ‘np’, ‘pt’.
Outputs:
images (list):
Generated images.
latents (Tensor):
Denoised latents.
Flux3DistilledAutoBlocks
Auto blocks that perform text-to-image and image-to-image generation using the step-distilled FLUX.3 model (16
steps, no classifier-free guidance). prompt goes through the prompt upsampler first; pop the prompt_upsampler step to encode it as given.
Supported workflows:
text2image: requirespromptimage_conditioned: requiresprompt,image
Components:
prompt_upsampler (Qwen3_5ForConditionalGeneration): The prompt upsampler. prompt_upsampler_processor
(AutoProcessor): Its processor. text_encoder (Qwen3VLForConditionalGeneration) tokenizer
(AutoProcessor) image_processor (Flux3ImageProcessor) vae (AutoencoderKLFlux2) transformer
(Flux3Transformer2DModel) scheduler (FlowMatchEulerDiscreteScheduler)
Inputs:
prompt (str):
The edit instruction to expand into the full caption (one per call).
image (Image | list, optional):
The reference image(s) of the edit, at most 10; the same ones the pipeline receives.
boxes (list, optional):
Layout boxes, each {‘id’, ‘desc’, ‘from’, ‘src_bbox’, ‘tgt_bbox’} with the boxes as [y_min, x_min, y_max,
x_max] in 0-1: ‘from’: ‘target’ with tgt_bbox adds an element there, ‘from’: ‘ref_image_0’, … with src_bbox and tgt_bbox moves one from a reference image.
max_new_tokens (int, optional, defaults to 3584):
The most tokens the upsampler may generate for the caption.
max_sequence_length (int, optional, defaults to 8192):
Maximum number of prompt tokens; longer prompts are truncated.
text_encoder_out_layers (tuple, optional, defaults to (4, 8, 12, 16, 20, 24, 28, 32)):
Indices of the text-encoder hidden layers whose states are stacked to form the text embeddings
num_images_per_prompt (int, optional, defaults to 1):
The number of images to generate per prompt.
image_cond_latents (list, optional):
Normalized packed latents of the reference images, one tensor of shape (B, C, height_i//16, width_i//16)
per image
height (int, optional, defaults to None or 1024, depending on the workflow):
The height in pixels of the generated image; defaults to the first reference image’s aspect ratio at the
default area
width (int, optional, defaults to None or 1024, depending on the workflow):
The width in pixels of the generated image; defaults to the first reference image’s aspect ratio at the
default area
latents (Tensor):
Pre-generated noisy latents for image generation.
generator (Generator, optional):
Torch generator for deterministic generation.
num_inference_steps (int):
The number of denoising steps.
timesteps (Tensor):
Timesteps for the denoising process. (overrides num_inference_steps when provided)
sigmas (list, optional):
Custom sigmas for the denoising process. (overrides num_inference_steps when provided)
*denoiser_input_fields (None,optional):
conditional model inputs for the denoiser: e.g. prompt_embeds, negative_prompt_embeds, etc.
output_type (str,optional*, defaults to pil):
Output format: ‘pil’, ‘np’, ‘pt’.
Outputs:
images (list):
Generated images.
latents (Tensor):
Denoised latents.
Flux3DistilledModularPipeline
class diffusers.Flux3DistilledModularPipeline
< source >( blocks: diffusers.modular_pipelines.modular_pipeline.ModularPipelineBlocks | None = Nonepretrained_model_name_or_path: str | os.PathLike | None = Nonecomponents_manager: diffusers.modular_pipelines.components_manager.ComponentsManager | None = Nonecollection: str | None = Noneworkflow: str | None = Nonemodular_config_dict: dict[str, typing.Any] | None = Noneconfig_dict: dict[str, typing.Any] | None = None**kwargs )
A ModularPipeline for the step-distilled FLUX.3 model (16 steps, no classifier-free guidance).