Views
No views yet
FLUX.2-klein that, unusually, drives both
the un-distilled foundation (FLUX.2-klein-base-9B) and the step-distilled
inference variant (FLUX.2-klein-9B). The same file gives a quality-first
path (28 inference steps on the base) and a speed-first path (4 inference
steps on the distilled), so you can iterate fast and ship slow with one set
of weights.1import torch
2from diffusers import Flux2KleinPipeline
3
4pipe = Flux2KleinPipeline.from_pretrained(
5 "black-forest-labs/FLUX.2-klein-base-9B",
6 torch_dtype=torch.bfloat16,
7).to("cuda")
8
9pipe.load_lora_weights(
10 "24yearsold/flux2-klein-character-transfer-portable-r128",
11 weight_name="pytorch_lora_weights.safetensors",
12)
13
14cond_image = build_stitched_conditioning(source_path, reference_path) # 1504x544 RGB
15prompt = open("character_transfer_prompt.txt", encoding="utf-8").read() # ~300 CJK chars
16out = pipe(
17 image=cond_image,
18 prompt=prompt,
19 num_inference_steps=28,
20 guidance_scale=3.5, # un-distilled foundation honours real CFG
21).images[0]
22out.save("transferred_quality.png")1pipe = Flux2KleinPipeline.from_pretrained(
2 "black-forest-labs/FLUX.2-klein-9B", # <-- distilled variant
3 torch_dtype=torch.bfloat16,
4).to("cuda")
5pipe.load_lora_weights(
6 "24yearsold/flux2-klein-character-transfer-portable-r128",
7 weight_name="pytorch_lora_weights.safetensors",
8)
9out = pipe(
10 image=cond_image,
11 prompt=prompt,
12 num_inference_steps=4, # <-- 4 steps matches the distilled recipe
13 guidance_scale=1.0,
14).images[0]
15out.save("transferred_fast.png")pipe.set_adapters("default", adapter_weights=0.85) (anything 0.0..1.0+).
The LoRA was trained at α=1.0; 0.8–1.0 is the recommended range.+--------------------+----------+
| source 960x544 | ref 544² | -> 1504 × 544 RGB
| (center-cropped) | (white- |
| | padded) |
+--------------------+----------+FLUX.2-klein-9B (distilled) and FLUX.2-klein-base-9B (foundation) share
the same transformer architecture (joint_attention_dim=12288, 8 dual-streamLoad LoRA node thanks to
Comfy-Org/ComfyUI #11981,
which added FLUX.2's to_qkv_mlp_proj and to_out key mapping to
comfy/utils.py:flux_to_diffusers. Drop the safetensors into
models/loras/ and use either the foundation or the distilled klein-9B as
your Load Checkpoint source. Strength 0.8–1.0.| Base | black-forest-labs/FLUX.2-klein-base-9B (un-distilled foundation) |
| Rank | 128 (alpha=128) |
| Init | gaussian (NOT PiSSA) |
| Target modules | to_k/q/v/out.0 + to_qkv_mlp_proj + single_transformer_blocks.{0..23}.attn.to_out |
| Trainable params | ~222 M |
| Schedule | cosine to 0.25× peak, 4 056 steps over 6 epochs |
| LR | 2 × 10⁻⁴ (warmup 50, num_cycles=0.3333) |
| Effective batch | 3 (3 GPU × bsz 1 × no grad-accum) |
| Precision | bf16 |
| Weighting scheme | none (uniform σ-sampling; NOT logit_normal) |
| Hardware | 3× RTX 4090 24 GB |
| Wall clock | ~5.5 h training + ~1.5 h eval/diagnose |
| u | loss |
|---|---|
| 0.10 (texture) | 0.3252 |
| 0.25 | 0.2294 |
| 0.50 | 0.2484 |
| 0.75 | 0.3591 |
| 0.90 (struct) | 0.5480 |
| mean | 0.3420 |
samples/p13_lora_on_distilled_ablation.png — 8 triplets × 4 columns:
foundation-no-LoRA, foundation+LoRA (28 steps), distilled-no-LoRA (4 steps),
distilled+LoRA (4 steps). The two no-LoRA columns confirm neither base does
character transfer on its own; the LoRA does all the work and the
quality/speed gap between the two LoRA columns is modest.samples/triplet_0..7_foundation_28steps.png — finals on the foundation base
samples/triplet_0..7_distilled_4steps.png — finals on the distilled base24yearsold/flux2-klein-9b-character-transfer-lora-r128 (P12) — earlier
LoRA trained against the distilled klein-9B. Lower MSE on the held-out
triplets but tied to the distilled base; ships its own inference recipe.24yearsold/flux2-klein-9b-character-transfer-pissa-r64 (P7) — original
PiSSA r=64 merged release.black-forest-labs/FLUX.2-klein-base-9B, black-forest-labs/FLUX.2-klein-9B)
have their own licenses; please follow theirs when using.