Repository navigation
feat(flux3): add FLUX.3 Image Klein and Klein Base - #9883
Pfannkuchensack wants to merge 2 commits into
Conversation
| submodels = resp.json() | ||
| paths = [Path(subfolder or "", x) for x in paths if Path(x).parent.as_posix() in submodels] | ||
| paths.insert(0, Path(f"{prefix}model_index.json")) | ||
| elif not prefix and Path("modular_model_index.json") in paths: |
There was a problem hiding this comment.
P2 Account for the repository prefix when filtering modular downloads
HuggingFaceMetadataFetch.from_id() constructs paths as Path(name, s.rfilename), and filter_files() preserves that prefix. Consequently, an actual install of black-forest-labs/flux-3-image-klein contains flux-3-image-klein/modular_model_index.json, so this condition is always false. The install retains the approximately 11 GB root checkpoint and weights under variants/ alongside the Diffusers components. A reproduction using the pinned selector and prefixed paths confirms both unwanted checkpoints remain selected. Normalize paths relative to the repository root for the index check and component-folder comparison, while retaining the original paths in the returned files. The added test currently uses unprefixed paths, so it does not exercise the production metadata contract.
There was a problem hiding this comment.
Good catch, thanks. from_id() builds paths as Path(name, rfilename), so the modular branch never matched. Fixed in 045e7e3: the modular_model_index.json check and the component-folder comparison now work relative to the repository root, while the returned files keep their prefixed paths. The test now uses production-shaped prefixed paths and fails against the previous code.
The classic model_index.json branch has the same pre-existing prefix issue (it never runs for from_id metadata either); that is out of scope here and will get its own issue.
Adds the flux3 base (Klein flow map, Klein Base) with a vendored transformer, Diffusers/bf16/GGUF loading, text encoder, denoise node with up to 10 reference images, starter models and docs. webv2 generates, edits and runs canvas img2img/inpaint/outpaint with FLUX.3, shows <ref_image_N> tags on reference cards and blocks CFG on Klein. FLUX.3 encodes references untiled where they fit; quantized single files are refused at install until a follow-up.
…o root Metadata paths carry the repository name, so the modular_model_index.json check never matched and a repo-id install also pulled the root single file and variants/.
4838210 to
045e7e3
Compare
| # File paths start with the repo name (HuggingFaceMetadataFetch.from_id), so folders compare below it. | ||
| url = hf_hub_url(self.id, filename="modular_model_index.json") | ||
| try: | ||
| resp = session.get(url, timeout=HF_METADATA_REQUEST_TIMEOUT_SECONDS) |
There was a problem hiding this comment.
P1 Authenticate the modular model-index request
Installing either gated Black Forest Labs FLUX.3 Diffusers repository reaches this request without an Authorization header, including through the new starter models. ModelInstallServiceDefault._import_from_hf() puts the configured/cached token on source.access_token, but _remote_files_from_source() does not pass that token to download_urls(), which normally creates a plain requests.Session; the token is only used later by _multifile_download(). Consequently, fetching modular_model_index.json fails with an authorization error before the download job is created, even after the user accepts the license and configures a valid token. Use an authenticated Hub request or propagate the source token into this metadata fetch, with coverage for the gated installation path.
Important
Do not merge before a diffusers release ships
Flux3Transformer2DModel. Review is welcome now.Flux3Transformer2DModelexists only on diffusersmain(commit7ecb1e1b4f, "Flux3 image (#15046)"). The PR vendors that file, unchanged apart from absolute imports, so it runs and can be tested on the pinneddiffusers==0.41.0. Before merging:invokeai/backend/flux3/transformer_flux3.py;invokeai/backend/flux3/__init__.py, the only import point;pyproject.toml.tests/backend/flux3/test_vendored_transformer.pyfails on the bump and lists these steps.Summary
Adds Black Forest Labs' FLUX.3 Image Klein as a new
flux3base with two variants:Both handle text-to-image and editing with up to 10 reference images. They install as Diffusers, as a bf16 single file or as GGUF.
Backend
flux3base andFlux3VariantType.modular_model_index.json), the bf16 single file and GGUF, with FLUX.1/FLUX.2 exclusions; community GGUFs declaregeneral.architecture="flux".flux3_model_loader,flux3_text_encoderandflux3_denoise(Prototype).modular_model_index.json, so it downloads only the Diffusers folders, not the 11 GB root single file next to them.webv2
<ref_image_N>tag the prompt uses, numbered like the graph's reference order; clicking the tag copies it.Docs
Follow-ups (stacked, not in this PR): layout boxes from canvas regions, quantized single files, LoRA, and BFL's prompt upsampler.
Related Issues / Discussions
None. First PR of the FLUX.3 stack.
QA Instructions
Automated (Windows, RTX 4090):
uv tool run ruff@0.11.2 check/format --checkon all changed Python: clean.uv run --no-sync pytest -n 4overtests/backend/flux3,tests/backend/flux2,tests/backend/architectures,tests/backend/model_manager/configs,tests/app/invocationsandtests/backend/utilandtests/app/routers/test_architecture_capabilities.py: 4114 passed.tests/backend/util/test_sage_attention.pyandtests/backend/model_manager/load/model_cache/test_model_cache_ram_budget.pyfail to collect onmaintoo ('filterwarnings' not found in markers); they are unrelated to this PR.format:check,lint:oxc,lint:tscandarchitecture:checkpass.pnpm test: 10202 passed, 3 failed. The three fail only under a German locale (digit grouping inclusterStats,indexProgressandmodelCacheStore) and are unrelated.invokeai/frontend/api: lint and tests pass.node --testpasses andpnpm buildsucceeds.Numerical comparison against the diffusers
mainreference pipeline with BFL's noise:use_cache=false, model cache emptied between models.Timings, RTX 4090, 1024²:
Memory, measured at driver level on the 4090:
Browser (webv2), all checked:
flux2_vae_encode→flux3_denoise, FLUX.2 strength curve).To try it, install the FLUX.3 bundle (or
black-forest-labs/flux-3-image-klein, which is gated) and pick FLUX.3 Klein on the Generate tab.Review
Material findings resolved:
unpack_ggml_at_loadinstead of being decoded every forward. QK norms keep their stored fp32 values.Remaining risks and limitations:
flux3_denoise.Compatibility / Rollout
flux3base and theflux3_klein/flux3_klein_basevariants are additive; existing model records are unaffected and no migration is needed.schema.tschange by additions only: three nodes, one conditioning field and output type, enum values, and theflux3_*generation modes.backend/flux2/latent_norm.py;encode_reference_image, whose default keeps FLUX.2's tiled encode;Checklist
What's Newcopy (if doing a release after this PR)Need help on this PR? Tag
@codesmith-botwith what you need.