Skip to content

feat(flux3): load unsloth's diffusers-named torchao fp8 build - #10182

Draft
Pfannkuchensack wants to merge 15 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/torchao-fp8-flux3
Draft

Pfannkuchensack wants to merge 15 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/torchao-fp8-flux3

Conversation

@Pfannkuchensack

@Pfannkuchensack Pfannkuchensack commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Stacked on #10093 (FLUX.3 quantized single files) and #10179 (torchao fp8 decoder). The diff shows both until they merge; the change here is the top commit. Draft so it cannot merge first.

Summary

unsloth's flux-3-image-klein-FP8.safetensors installed as an unknown model: it uses diffusers' key names, and identification only read Black Forest Labs' native layout. It now installs as Klein and loads.

  • The diffusers-named layout is recognized only beside a torchao payload, so no plain diffusers-named single file becomes newly accepted.
  • The file skips the native key conversion entirely, so nothing swaps its adaLN rows. flux3_transformer_config reads shapes through the same key mapping as the native route, and flux3_transformer_from_native is renamed to flux3_transformer_from_single_file.
  • The flow-map check accepts _weight_qdata, so a Klein file that quantizes that embedder is not recorded as Klein Base.
  • Still refused at install, with a message: native-named torchao files, INT8 builds, other torchao layouts, and torchao layers mixed with int8.

Related Issues / Discussions

Follow-up to #9798. Depends on #10093 and #10179.

QA Instructions

RTX 4090, Windows, 1024x1024, 16 steps, CFG 1, three prompts with fixed seeds, use_cache=false, model cache emptied before each block. Reference is flux3_image_klein_sd_bf16.safetensors, whose dense tensors match the FP8 file byte for byte under native names (44 of 45 compared directly); flux3-image-klein-base-bf16 matches none. All its tensors are BF16 and fp8_storage is unset. The FP8 file installs as Klein with FP8 Storage on; the log reports 228 layers kept in fp8.

bf16 FP8 Storage (default) fp8_compute
PSNR against bf16, per prompt 26.6 / 27.2 / 32.9 dB 30.8 / 24.0 / 29.9 dB
Seconds per image 8.0 8.5 7.0
Transformer in the model cache 11.1 GB 6.4 GB 6.4 GB
Peak device memory 18.1 GB 13.8 GB 13.7 GB

Repeated renders with the same seed were bit-identical on both sides, and bf16 was identical across both server settings. Images compared by eye: clean, same subject, text intact.

Real files on CPU: after translation the key set equals the native conversion of the bf16 source (359 keys), all 131 dense tensors match it by value, including the swapped norm_out.linear, and all 228 quantized layers sit at a relative error of 0.0263-0.0265.

pytest tests/backend/flux3 tests/backend/model_manager/configs/test_flux3_main_config.py tests/backend/model_manager/configs/test_moss_image_identification.py tests/backend/quantization/test_fp8_scaled.py tests/test_calibrate_flux3_denoise_working_memory.py

ruff check and ruff format --check pass. make frontend-openapi and make frontend-typegen were rerun.

Not run: a partial load on a real device, the fold path on a GPU, ROCm and other hardware. The family E2E tool was not run. No Klein Base torchao file exists, so that case is covered by fixtures only, and the INT8 build's refusal rests on the layout of the sibling families.

Review

Resolved during review:

  • Native-named torchao files would have installed as Klein Base while the loader built the flow-map model, failing at the first render. They stay refused.
  • Variant detection missed a quantized flow-map embedder.
  • An int8 file with torchao layers passed install and failed at the first render. It is refused at install.
  • The fold path pinned the file mapping through its dense tensors. It now calls clone_unreplaced_tensors.

Remaining: a diffusers-named torchao file with quantized x_embedders is refused safely, but the message wrongly names Black Forest Labs' key names. No such file is known.

The 86 F32 q/k norms in this file go through the existing cast and are widened again by _keep_qk_norms_in_fp32; all of them are exactly representable in bf16, so nothing is lost.

Compatibility / Rollout

No migration. openapi.json and schema.ts change only in the Main_Checkpoint_Flux3_Config description.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Meaningful regression coverage added / updated where needed; obsolete tests/code removed
  • Persisted-state and API changes include required migrations / compatibility validation
  • Relevant performance/efficiency opportunities considered; material claims have evidence
  • Material review findings resolved and relevant checks rerun
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

FLUX.3 Klein and Klein Base now load Comfy-Org's int8_convrot and nvfp4 files and BFL's fp8r and nvfp4 variants; one rule set refuses at install what the loader cannot run.
BFL's nvfp4 is re-laid out to Comfy's packing after the reservation, and the int8 build's fused qkv is split into the model's projections.
…hecks

Install-time validation now reuses check_int8_layer_layout, so a missing scale, blockwise scale or oversized rotation group is refused at install.
… check

Split the rotation-width rule out of check_int8_layer_layout so the swap runs it after the target-shape check; install runs both.
# Conflicts:
#	docs/src/content/docs/Users Guide/03.Models/Local Models/flux-3.mdx
#	invokeai/backend/flux3/denoise_working_memory.py
# Conflicts:
#	docs/src/content/docs/Users Guide/03.Models/Local Models/flux-3.mdx
Translate torchao fp8 layers into the scaled-fp8 form and refuse other torchao layouts at install.
Release the file mapping when a load folds every layer.
Recognize the layout only with a torchao payload and read the Klein variant from it.
@github-actions github-actions Bot added python PRs that change python files backend PRs that change backend files python-tests PRs that change python tests docs PRs that change docs labels Nov 6, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend PRs that change backend files docs PRs that change docs python PRs that change python files python-tests PRs that change python tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant