FLUX.1-schnell INT4 / FP4¶
Example for black-forest-labs/FLUX.1-schnell.
Set precision = "int4" or precision = "fp4" in the script.
Run from the repository root:
from pathlib import Path
import torch
from diffusers import FluxPipeline
from nunchaku_lite import load_nunchaku_pipeline
model_id = "black-forest-labs/FLUX.1-schnell"
precision = "fp4" # "int4" or "fp4"
checkpoints = {
"int4": "nunchaku-ai/nunchaku-flux.1-schnell/svdq-int4_r32-flux.1-schnell.safetensors",
"fp4": "nunchaku-ai/nunchaku-flux.1-schnell/svdq-fp4_r32-flux.1-schnell.safetensors",
}
checkpoint = checkpoints[precision]
output_path = Path(f"outputs/flux_schnell_nunchaku_lite_{precision}.png")
pipe = load_nunchaku_pipeline(
model_id,
pipeline_cls=FluxPipeline,
checkpoint=checkpoint,
target="flux",
precision=precision,
torch_dtype=torch.bfloat16,
device="cuda",
)
pipe = pipe.to("cuda")
image = pipe(
"A cat holding a sign that says hello world",
height=1024,
width=1024,
num_inference_steps=4,
guidance_scale=0.0,
generator=torch.Generator(device="cuda").manual_seed(12345),
).images[0]
output_path.parent.mkdir(parents=True, exist_ok=True)
image.save(output_path)
print(f"saved {output_path}")
Quantized T5 Encoder¶
FLUX.1 can also replace the large T5 text_encoder_2 with a quantized
Nunchaku checkpoint:
pipe = load_nunchaku_pipeline(
"black-forest-labs/FLUX.1-dev",
pipeline_cls=FluxPipeline,
checkpoint="nunchaku-tech/nunchaku-flux.1-dev/svdq-int4_r32-flux.1-dev.safetensors",
target="flux",
quantized_encoder_checkpoints={
"text_encoder_2": "mit-han-lab/nunchaku-t5/awq-int4-flux.1-t5xxl.safetensors",
},
torch_dtype=torch.bfloat16,
device="cuda",
)
Advanced callers can construct the encoder directly:
from nunchaku_lite import NunchakuT5EncoderModel
text_encoder_2 = NunchakuT5EncoderModel.from_pretrained(
"mit-han-lab/nunchaku-t5/awq-int4-flux.1-t5xxl.safetensors",
torch_dtype=torch.bfloat16,
device="cuda",
)
FLUX.1-dev Runtime LoRA¶
Patched FLUX transformers expose load_lora, set_lora_strength, and
reset_lora. load_lora accepts Diffusers-format FLUX LoRAs and
Nunchaku-format low-rank tensors. Multiple LoRAs can be active at the same
time; they are recomposed from the original checkpoint low-rank branch when a
strength changes or one adapter is reset.
from pathlib import Path
import torch
from diffusers import FluxPipeline
from nunchaku_lite import load_nunchaku_pipeline
model_id = "black-forest-labs/FLUX.1-dev"
precision = "fp4" # "int4" or "fp4"
checkpoints = {
"int4": "nunchaku-tech/nunchaku-flux.1-dev/svdq-int4_r32-flux.1-dev.safetensors",
"fp4": "nunchaku-tech/nunchaku-flux.1-dev/svdq-fp4_r32-flux.1-dev.safetensors",
}
pipe = load_nunchaku_pipeline(
model_id,
pipeline_cls=FluxPipeline,
checkpoint=checkpoints[precision],
target="flux",
precision=precision,
torch_dtype=torch.bfloat16,
)
pipe.enable_model_cpu_offload()
pipe.load_lora_weights(
"aleksa-codes/flux-ghibsky-illustration",
weight_name="lora.safetensors",
adapter_name="ghibsky",
)
pipe.set_adapters("ghibsky", adapter_weights=0.75)
image = pipe(
"GHIBSKY style painting of a cozy mountain cabin beside a clear lake at sunset",
height=1024,
width=1024,
num_inference_steps=28,
guidance_scale=3.5,
generator=torch.Generator(device="cpu").manual_seed(12345),
).images[0]
output_path = Path(f"outputs/flux_dev_ghibsky_{precision}.png")
output_path.parent.mkdir(parents=True, exist_ok=True)
image.save(output_path)
pipe.unload_lora_weights()
Multiple LoRAs¶
Load each adapter with a stable name, then update or remove one without disturbing the others.
pipe.load_lora_weights(
"aleksa-codes/flux-ghibsky-illustration",
weight_name="lora.safetensors",
adapter_name="ghibsky",
)
pipe.load_lora_weights(
"prithivMLmods/Canopus-LoRA-Flux-UltraRealism-2.0",
weight_name="Canopus-LoRA-Flux-UltraRealism.safetensors",
adapter_name="realism",
)
pipe.set_adapters(["ghibsky", "realism"], adapter_weights=[0.65, 0.35])
pipe.set_adapters(["ghibsky", "realism"], adapter_weights=[0.65, 0.5])
pipe.delete_adapters("realism") # leaves "ghibsky" loaded and active
pipe.unload_lora_weights() # removes all runtime LoRAs