Skip to content

feat(Model Support): add Krea-2-Turbo model + LoRA support (WIP)#9304

Open
Pfannkuchensack wants to merge 27 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/krea2-turbo-support
Open

feat(Model Support): add Krea-2-Turbo model + LoRA support (WIP)#9304
Pfannkuchensack wants to merge 27 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/krea2-turbo-support

Conversation

@Pfannkuchensack

@Pfannkuchensack Pfannkuchensack commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Integrate Krea-2 text-to-image per NEW_MODEL_INTEGRATION.md: both Krea-2-Turbo (krea/Krea-2-Turbo, distilled) and Krea-2-Raw (krea/Krea-2-Raw, undistilled Base). Architecture: Krea2Transformer2DModel (single-stream MMDiT, ~12B) + Qwen3-VL text encoder (12-layer hidden-state tap → 4D prompt_embeds) + reused Qwen-Image VAE (AutoencoderKLQwenImage) + FlowMatchEulerDiscreteScheduler.

  • Turbo (is_distilled=true): fixed mu=1.15, 8 steps, CFG off (cfg 1.0).
  • Raw (is_distilled=false): resolution-aware mu, ~28 steps, CFG ~4.5. Variant is read from the pipeline is_distilled flag (single-file/GGUF fall back to a filename heuristic).

Formats: full Diffusers pipeline, single-file checkpoint (incl. ComfyUI scaled fp8), and GGUF (Q2–Q8). Single-file/GGUF ship only the transformer, so a standalone Qwen-Image VAE + Qwen3-VL encoder are selected in the loader UI (enforced by readiness before enqueue). NVFP4 intentionally skipped (needs Blackwell FP4 kernels).

VRAM: fp8 layerwise-cast weight storage for the transformer (diffusers + single-file) and for the fp8 Qwen3-VL encoder (~8.9 GB bf16 → ~4.4 GB resident), keeping 1024² + LoRA within 24 GB.

diffusers dependency (resolved)

Krea2Transformer2DModel / Krea2Pipeline landed in diffusers 0.39.0 (stable). pyproject.toml now pins diffusers[torch]==0.39.0 and uv.lock is updated accordingly — the previous git-main blocker is gone.

Notable extras

  • Conditioning enhancers (Advanced Options, under CFG Scale, default OFF, with tooltips): Conditioning Rebalance (per-layer weighting) and Seed Variance Enhancer (restores per-seed diversity on the distilled model).
  • Metadata recall for the standalone VAE, Qwen3-VL encoder, and both enhancers, so single-file/GGUF generations reproduce from metadata.
  • Starter models: Krea-2 Turbo, Krea-2 Raw, Krea-2 Turbo GGUF (Q4_K_M / Q8_0, with VAE + encoder dependencies), and a standalone Qwen3-VL 4B encoder.
  • Fixed a latent type-guard bug surfaced by the new loader union (isMainModelWithoutUnet is now a proper type predicate covering all transformer-based loaders).

QA Instructions

  1. Dependency: uv sync --extra cuda (pulls diffusers 0.39.0); confirm python -c "from diffusers import Krea2Transformer2DModel, Krea2Pipeline".
  2. Install (Diffusers): point InvokeAI at a Krea-2-Turbo and a Krea-2-Raw folder. Confirm they probe as main / diffusers / krea-2 with variant krea2_turbo / krea2_base, and the bundled encoder as qwen3_vl_encoder. On model select, Turbo defaults to 8 steps / cfg 1.0, Raw to ~28 steps / cfg 4.5.
  3. Generate (txt2img): 1024², enable FP8 in the model's Default Settings on 24 GB cards. Confirm an image renders for both Turbo and Raw.
  4. Single-file / GGUF: install a GGUF transformer (e.g. vantagewithai/Krea-2-Turbo-GGUF) + the standalone Qwen-Image VAE + Qwen3-VL encoder. Confirm the loader UI requires the VAE + encoder before enqueue and that generation succeeds. The fp8 encoder logs FP8 layerwise casting enabled for Qwen3-VL encoder.
  5. LoRA: load a Krea-2 LoRA (diffusers PEFT). Confirm it probes as lora.lycoris.krea-2 (not qwen-image), applies, and that 1024² + LoRA + fp8 does not OOM.
  6. CFG: at cfg 1.0 (Turbo) confirm no negative prompt is run and recall shows no negative prompt; at cfg > 1 (Raw) confirm negative conditioning is used.
  7. Enhancers: with both off, output matches stock. Enable Conditioning Rebalance → stronger prompt adherence; enable Seed Variance → meaningfully different images across seeds. Confirm tooltips render and that recall restores both.
  8. img2img / inpaint / outpaint: round-trip an init image.

Tests

  • Config-probe unit tests for Krea-2 variant detection (name heuristic, _has_krea2_keys, GGUF/checkpoint/diffusers variant, default settings) and the single-file Qwen3-VL encoder probe (visual-tower vs. text-only Qwen3). Run: pytest tests/backend/model_manager/configs/test_krea2_main_config.py tests/backend/model_manager/configs/test_qwen3_vl_encoder_config.py.

Merge Plan

diffusers blocker is resolved (pinned to stable 0.39.0). No DB schema changes. paramsSlice gains Krea-2 fields with a corresponding migration.

Out of scope / follow-ups

  • ControlNet / IP-Adapter plumbing exists but cannot be validated until a Krea-2 control checkpoint is released.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Tests added / updated (if applicable)
  • ❗Changes to a redux slice have a corresponding migration
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

Integrate Krea-2-Turbo (krea/Krea-2-Turbo) text-to-image per
NEW_MODEL_INTEGRATION.md: Krea2Transformer2DModel (single-stream MMDiT)
+ Qwen3-VL text encoder (12-layer hidden-state tap, 4D prompt_embeds)
+ reused Qwen-Image VAE + FlowMatchEulerDiscrete scheduler.

Backend:
- taxonomy: BaseModelType.Krea2, ModelType/ModelFormat.Qwen3VLEncoder,
  Krea2VariantType (Turbo = "krea2_turbo" to avoid Z-Image collision)
- config probes: Main_Diffusers/Checkpoint_Krea2, Qwen3VLEncoder,
  LoRA_LyCORIS_Krea2 (text_fusion/time_mod_proj signature; excluded
  from the Qwen-Image probe to avoid double-match)
- loaders for the diffusers pipeline + standalone Qwen3-VL encoder,
  with runtime workarounds for the HF model's version mismatches
  (AutoTokenizer, extra_special_tokens={}, rope_parameters->rope_scaling)
- native sampling (pack/unpack, position_ids, linear-mu shift) and
  hand-written Euler denoise loop; reuses qwen_image l2i/i2l
- invocations: model_loader, text_encoder, denoise, lora_loader, plus
  two ecosystem enhancers (conditioning rebalance, seed variance)
- LoRA conversion for diffusers PEFT (lora_transformer- prefix)

Frontend:
- 'krea-2' base + qwen3_vl_encoder type/format across model maps,
  buildKrea2Graph, addKrea2LoRAs, graph-builder denoise/base lists,
  optimal dimension 1024, regenerated schema.ts

Fixes:
- estimate transformer working memory in krea2_denoise so the cache
  reserves activation headroom and offloads more model under partial
  loading; fixes fp8 + LoRA OOM at 1024 (model was placed before LoRA
  patches were applied, leaving no room for their activations)

WIP: requires diffusers main (>=0.39 dev) for Krea2Transformer2DModel;
pyproject.toml temporarily pins diffusers to git main.
@github-actions github-actions Bot added api python PRs that change python files Root invocations PRs that change invocations backend PRs that change backend files services PRs that change app services frontend PRs that change frontend files python-deps PRs that change python dependencies labels Jun 25, 2026
@lstein

lstein commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Amazing! I was just thinking of working on this myself and you did it for me!

Allow non-diffusers Krea-2 transformers (GGUF/fp8) to run with standalone
single-file VAE + Qwen3-VL encoder, fixing several blockers found in testing.

- buildKrea2Graph: drop the hard "requires Diffusers-format" assert; instead
  require both a VAE and a Qwen3-VL encoder to be selected when the transformer
  is not diffusers (mirrors readiness.ts).
- Qwen3-VL encoder remap: handle both single-file key conventions — implicit
  (model.layers.*) and explicit (model.language_model.*). The old blind
  model.* -> language_model.* turned the bf16 file's keys into
  language_model.language_model.* (398 meta tensors -> "Cannot copy out of meta
  tensor" crash). Both files now load 0 missing / 0 unexpected / 0 meta.
- Qwen3-VL tokenizer/config: broaden the offline-cache fallback from OSError to
  Exception so a partial HF cache (config present, vocab missing) re-fetches
  instead of dying with TypeError.
- Qwen3-VL encoder fp8: keep an fp8 source checkpoint fp8-resident with
  per-layer upcast (storage float8_e4m3fn, compute bf16) instead of dequantizing
  to bf16. Halves resident VRAM (~8.9GB -> ~4.4GB), avoiding partial-load
  thrashing alongside a large transformer. Auto-enabled for fp8 sources on CUDA;
  bf16 files stay bf16.
- Qwen-Image VAE: a native-layout qwen_image_vae single file is classified with
  the Anima base and loaded as AutoencoderKLWan, but the qwen l2i/i2l nodes need
  AutoencoderKLQwenImage. Add backend/krea2/vae_compat.py::as_qwen_image_vae to
  reinterpret a Wan VAE as AutoencoderKLQwenImage (state dicts are identical,
  194/194 keys); both qwen VAE nodes use it. Idempotent for real QwenImage VAEs.
@lstein lstein added the 6.14.x label Jun 28, 2026
@lstein lstein moved this to 6.14.x Theme: USER EXPERIENCE in Invoke - Community Roadmap Jun 28, 2026
@kappacommit

Copy link
Copy Markdown
Contributor

Can you add it to the list of supported models here https://github.com/invoke-ai/InvokeAI/blob/main/README.md?plain=1#L61

An upstream merge reintroduced the AutoencoderKLQwenImage isinstance asserts in
the qwen VAE nodes (without the import → F821) and dropped the adapter in the
i2l path. A native-layout qwen_image_vae single file is classified with the
Anima base and loaded as AutoencoderKLWan, so the asserts fail at runtime.

- qwen_image_latents_to_image: drop the reintroduced pre-device assert (the
  as_qwen_image_vae adapter inside model_on_device already handles the class).
- qwen_image_image_to_latents: restore the as_qwen_image_vae import + adapter
  call, remove both asserts.
- estimate_vae_working_memory_qwen_image only reads tensor shape + element size,
  so it runs correctly on either VAE class before the adapter.
…l_loader

krea2_model_loader was added to MainModelLoaderNodes but not to
isMainModelWithoutUnet, and the guard wasn't a type predicate — so it never
narrowed modelLoader. OutputFields of the loader union collapses to the common
'vae' field, making g.addEdge(modelLoader, 'unet', ...) in addInpaint/addOutpaint
fail to type-check ('unet' not assignable to 'vae').

Redefine the guard as a type predicate keyed on the inverse (only
main_model_loader/sdxl_model_loader expose a unet), so every transformer-based
loader is treated as unet-less automatically and the negated branch narrows to
the unet-bearing loaders.
zKrea2VariantType was only used within common.ts (in zAnyModelVariant) and never
referenced externally, so knip flagged it as an unused export. Every sibling
variant enum avoids this by being asserted in common.test-d.ts; add the missing
Krea2VariantType assertion, which both uses the export and verifies the manual
zod enum matches the generated S['Krea2VariantType'].
@Pfannkuchensack Pfannkuchensack marked this pull request as ready for review July 3, 2026 15:50
@Pfannkuchensack Pfannkuchensack marked this pull request as draft July 3, 2026 15:50
diffusers 0.39.0 is the first stable release containing Krea2Pipeline /
Krea2Transformer2DModel (plus the Qwen-Image VAE and Qwen3-VL text encoder
Krea-2 relies on). Replace the temporary git-main dependency with the pinned
release and update the lockfile's diffusers entry (version, sdist, wheel,
specifier) to the official PyPI 0.39.0 artifacts.
Close the remaining gaps against docs/new-model-integration for Krea-2.

Metadata recall (§7): buildKrea2Graph now records the standalone VAE, Qwen3-VL
encoder, and both conditioning enhancers (seed-variance + rebalance) to image
metadata, and parsing.tsx adds the matching recall handlers (base-guarded to
'krea-2'), so a Krea-2 image's VAE/encoder/enhancer settings restore on recall —
important for reproducing single-file/GGUF generations.

Starter models: add Krea-2 Raw (Base variant, full pipeline), Krea-2 Turbo GGUF
Q4_K_M / Q8_0 (vantagewithai/Krea-2-Turbo-GGUF) with Qwen-Image VAE + Qwen3-VL
encoder dependencies, and a standalone Qwen3-VL 4B encoder (Qwen/Qwen3-VL-4B-
Instruct). The VAE dependency reuses the existing diffusers qwen_image_vae
starter; krea2_turbo gains its explicit Turbo variant.

Tests: add config-probe unit tests for Krea-2 variant detection (name heuristic,
_has_krea2_keys, GGUF/checkpoint/diffusers variant, default settings) and for the
single-file Qwen3-VL encoder probe (visual-tower vs. text-only Qwen3). 31 tests.
@github-actions github-actions Bot added the python-tests PRs that change python tests label Jul 5, 2026
@JPPhoto

JPPhoto commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

@Pfannkuchensack Here's a list of things that should probably to be addressed:

  • pyproject.toml:39 requires diffusers[torch]==0.39.0, but uv.lock:632 and uv.lock:1128 still resolve 0.37.0. Because docker/Dockerfile:77 runs uv sync --frozen, Docker installations retain a Diffusers release without the new Krea2 classes. Regenerate and commit uv.lock.

  • invokeai/app/invocations/krea2_text_encoder.py:69 ignores self.qwen3_vl_encoder.loras. Meanwhile, invokeai/backend/patches/lora_conversions/krea2_lora_conversion_utils.py:54 converts text-encoder patches and invokeai/frontend/web/src/features/nodes/util/graph/generation/addKrea2LoRAs.ts:35 routes them to the encoder. Qwen3-VL portions of Krea2 LoRAs are silently ignored. Apply them with LayerPatcher and KREA2_LORA_QWEN3VL_PREFIX, following z_image_text_encoder.py. To expose this issue, add a test that supplies a LoRA containing a text-encoder patch and asserts that the encoder layer is patched during _encode().

  • invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts:106 handles component cleanup and default selection for Z-Image, Anima, FLUX.2, and Qwen Image, but not Krea2. Standalone Krea2 VAE and encoder selections survive switches to other model families. When a Krea2 Diffusers model is later selected, invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts:65 passes those stale selections as overrides instead of using the bundled components. To expose this issue, add a listener test that selects Krea2 GGUF components, switches away, then selects Krea2 Diffusers and asserts that the stale component selections are cleared.

  • The same missing Krea2 branch in invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts means installed GGUF starter dependencies are not selected automatically. Generation remains blocked by invokeai/frontend/web/src/features/queue/store/readiness.ts:327 until the user manually selects the VAE and encoder. To expose this issue, add a listener test with installed Qwen Image VAE and Qwen3-VL encoder records and assert that selecting a Krea2 GGUF model populates both fields.

  • invokeai/frontend/web/src/features/metadata/parsing.tsx:1162 defines recall handlers for the Krea2 VAE, Qwen3-VL encoder, seed variance settings, and rebalance settings, but invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx:32 omits every one of them. These values are absent from the Recall Parameters tab and cannot be recalled individually. To expose this issue, extend ImageMetadataActions.test.tsx to require every Krea2 metadata handler in IMAGE_METADATA_ACTION_HANDLERS.

  • Krea2SeedVarianceEnabled.parse() at invokeai/frontend/web/src/features/metadata/parsing.tsx:1213 and Krea2RebalanceEnabled.parse() at invokeai/frontend/web/src/features/metadata/parsing.tsx:1269 return false when their fields are absent and do not gate that fallback on the current model being Krea2. Recalling metadata from an unrelated or older image can therefore clear hidden Krea2 enhancer state. To expose this issue, add a metadata recall test that starts with the Krea2 settings enabled, recalls non-Krea2 metadata without these keys, and checks whether those settings should remain unchanged.

  • invokeai/backend/model_manager/starter_models.py:1932 does not add a Krea2 entry to STARTER_BUNDLES. The launchpad renders this mapping, so the newly defined Krea2 models and their dependencies are not offered as a Krea2 launchpad bundle. To expose this issue, add a starter-model response test asserting that BaseModelType.Krea2 is present and that its GGUF option includes the Qwen Image VAE and Qwen3-VL encoder dependencies.

  • The new user-facing model family, approximately 26 GB Diffusers installation, standalone component requirements, GGUF workflow, Raw versus Turbo behavior, and enhancer controls are undocumented. Add Krea2 hardware requirements to docs/src/content/docs/start-here/system-requirements.mdx and an appropriate model usage page under docs/src/content/docs/features/.

  • Krea2GGUFCheckpointModel._load_from_gguf() in invokeai/backend/model_manager/load/model_loaders/krea2.py:365 detects parameters left on the meta device but only logs a warning and returns the incomplete model. Unsupported or partially converted GGUF layouts will fail later during inference instead of being rejected during loading. To expose this issue, add a loader test with a required key missing and assert that loading raises a descriptive exception.

  • Krea2CheckpointModel._load_from_singlefile() in invokeai/backend/model_manager/load/model_loaders/krea2.py:326 uses strict=False and discards the missing and unexpected key lists. A misidentified, incomplete, or differently converted checkpoint may retain meta parameters or silently omit weights. To expose this issue, add a checkpoint loader test with missing required transformer weights and assert that the loader rejects it before returning the model.

  • Qwen3VLEncoderCheckpointLoader._load_text_encoder() in invokeai/backend/model_manager/load/model_loaders/krea2.py:535 also uses strict=False without inspecting missing keys or checking for remaining meta parameters. A partially compatible Qwen3-VL checkpoint can be accepted and fail only when prompt encoding begins. To expose this issue, add a loader test with an incomplete language-model tower and assert that loading fails with the missing key names.

  • _has_krea2_lora_keys() in invokeai/backend/model_manager/configs/lora.py:904 requires a LoRA to target text_fusion or time_mod_proj. A legitimate Krea2 LoRA trained only against shared transformer_blocks cannot be installed as Krea2 and may instead be classified as Qwen Image. Explicitly selecting Krea2 as an override does not bypass the same validation. To expose this issue, add a config-probe test for a transformer-block-only Krea2 LoRA and define how ambiguous LoRAs should be classified or manually overridden.

  • Krea2DenoiseInvocation._prepare_cfg_scale() in invokeai/app/invocations/krea2_denoise.py:124 requires a list length equal to the number of timesteps after img2img schedule clipping. A custom workflow supplying one CFG value per configured step will fail when denoising_start or denoising_end reduces the active steps. To expose this issue, add a denoise test with eight CFG values, eight configured steps, and a nonzero denoising_start.

  • denoising_start and denoising_end are independently constrained in invokeai/app/invocations/krea2_denoise.py:72, but nothing requires start to be less than or equal to end. A reversed range can produce an empty sigma slice, after which sigmas_sched[0] is accessed before the zero-step guard. To expose this issue, add an invocation validation test using denoising_start=0.9 and denoising_end=0.1 and require a clear validation error.

  • Supplying denoise_mask without initial latents reaches assert init_latents is not None in invokeai/app/invocations/krea2_denoise.py:223. API and workflow callers can construct that graph, producing an assertion failure instead of a user-facing validation error. To expose this issue, add an invocation test with a mask but no initial latents.

  • Krea2DenoiseInvocation._run_diffusion() in invokeai/app/invocations/krea2_denoise.py:155 hardcodes torch.bfloat16, while the Krea2 model loaders use TorchDevice.choose_bfloat16_safe_dtype(). On a device where the loader selects a fallback dtype, conditioning and inference still force bfloat16 and may fail or trigger unsupported operations. To expose this issue, mock a device whose safe dtype is float32 or float16 and assert that denoising consistently uses that selected dtype.

  • Krea2TextEncoderInvocation._encode() in invokeai/app/invocations/krea2_text_encoder.py:114 also hardcodes torch.bfloat16, independently of the dtype selected when the Qwen3-VL model was loaded. Use the loaded model's effective dtype or the same safe-dtype helper. To expose this issue, load or mock an encoder using a non-bfloat16 dtype and assert that its output conditioning uses a compatible dtype.

  • _is_distilled() in invokeai/app/invocations/krea2_denoise.py:132 catches every exception and defaults to Turbo behavior. Configuration lookup failures, malformed model_index.json, and filesystem errors are silently converted into a fixed Turbo shift, which can produce incorrect sampling for a Raw model. To expose this issue, make context.models.get_config() fail and assert that the invocation reports the configuration error instead of silently changing variants.

  • Main_Diffusers_Krea2_Config._get_variant() in invokeai/backend/model_manager/configs/main.py also catches every exception and defaults to Turbo. A malformed or unreadable Raw model index can therefore be registered with Turbo defaults. To expose this issue, add a model-probe test with malformed model_index.json and require an identification error rather than a Turbo classification.

  • Krea2LoRALoaderInvocation in invokeai/app/invocations/krea2_lora_loader.py:54 checks only that the model exists; unlike the collection loader, it does not verify that the selected LoRA has BaseModelType.Krea2. Direct API or workflow callers can attach an unrelated LoRA and receive an apparently valid output whose patches are ignored or mismatched. To expose this issue, add an invocation test passing a FLUX or SDXL LoRA and require a compatibility error.

  • Krea2LoRACollectionLoader in invokeai/app/invocations/krea2_lora_loader.py:137 deduplicates only entries within the incoming collection. It does not check LoRAs already present on the supplied transformer or encoder, so chaining collection loaders can apply the same LoRA more than once. To expose this issue, start with a field containing one LoRA, pass the same LoRA in the collection, and assert that it is rejected or retained only once.

  • as_qwen_image_vae() in invokeai/backend/krea2/vae_compat.py:20 accepts any model that is not already AutoencoderKLQwenImage and attempts to reinterpret its entire state dictionary. The modified Qwen Image encode and decode nodes therefore no longer reject an incompatible VAE immediately; they instantiate a large replacement module before strict loading fails. Add an explicit AutoencoderKLWan type check. To expose this issue, connect an unrelated VAE and assert that it is rejected before constructing a Qwen Image VAE.

  • The Krea2 model-loader and denoise paths have no coverage for full Diffusers loading, single-file conversion, GGUF conversion, Qwen3-VL prompt encoding, LoRA application, schedule clipping, CFG, img2img, inpaint, outpaint, cancellation, or model-cache cleanup. Add focused coverage under tests/backend/model_manager/load/ and tests/app/invocations/, plus graph construction coverage alongside invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts.

  • The new diffusers upgrade affects every existing model family, but the PR changes only the dependency declaration and Krea2 code. Add representative compatibility coverage for existing FLUX, Qwen Image, Z-Image, SD, and Anima loader paths against Diffusers 0.39.0.

  • The numeric placeholder in invokeai/frontend/web/src/features/parameters/components/Krea2Enhancers/ParamKrea2RebalanceWeights.tsx:26 is a direct user-visible string rather than an en.json translation key. Move it into invokeai/frontend/web/public/locales/en.json to keep all newly introduced UI text within the localization system.

@JPPhoto

JPPhoto commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

I fixed a few of the light effort issues:

  • Updated uv.lock to Diffusers 0.39.0 with minimal lockfile churn.
  • Added input validation in invokeai/app/invocations/krea2_denoise.py for empty/inverted denoising ranges and masks without initial latents.
  • Restricted as_qwen_image_vae() in invokeai/backend/krea2/vae_compat.py to compatible VAE classes.

…-model coverage

Backend:
- test_krea2_state_dict_utils.py: cover the pure loader transforms (prefix
  strip, native<->diffusers conversion, scaled-fp8 dequant, Qwen3-VL key remap)
  and _reject_incomplete_load parametrized over the single-file/GGUF/encoder
  call sites (rejects meta-tensor partial loads, names the missing params)
- test_krea2_denoise.py: _prepare_cfg_scale (broadcast/length/type), the
  per-step cfg list vs. img2img-clip regression, _validate_inputs happy path,
  and _get_noise determinism/shape
- test_starter_models.py: Krea-2 bundle registration, diffusers+GGUF+standalone
  membership, and GGUF entries declaring their VAE + Qwen3-VL dependencies

Frontend:
- modelSelected.test.ts: Krea-2 standalone-component defaulting (auto-select on
  GGUF, anima-VAE fallback, no-overwrite, diffusers clears overrides, clear on
  switch away)
- parsing.test.tsx: Krea2 VAE/encoder + enhancer recall gating (parses only for
  krea-2, never clobbers otherwise)
- buildKrea2Graph.test.ts: CFG negative-conditioning gating, enhancer node
  insertion/chaining, non-diffusers standalone-model assertion, metadata
- ImageMetadataActions.test.tsx: require all eight Krea2 recall handlers

Fix: exclude krea-2 from the generic VAEModel metadata handler (it has a
dedicated Krea2VAEModel handler), matching the existing z-image/flux2 exclusions.
@Pfannkuchensack Pfannkuchensack marked this pull request as ready for review July 13, 2026 20:22
@github-actions github-actions Bot added the docs PRs that change docs label Jul 13, 2026
@JPPhoto

JPPhoto commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Got these in as well:

  • Added all Krea handlers to the metadata recall action list.
  • Prevented the generic VAE handler from duplicating the dedicated Krea VAE action.
  • Gated Krea scalar metadata using the image's model base, preventing unrelated images from exposing or recalling Krea defaults.
  • Localized the rebalance-weight placeholder through en.json.

JPPhoto added 2 commits July 13, 2026 15:34
…4-review

# Conflicts:
#	invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.test.tsx
#	invokeai/frontend/web/src/features/metadata/parsing.test.tsx
#	invokeai/frontend/web/src/features/metadata/parsing.tsx

@JPPhoto JPPhoto left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current state. I'll work on these:

  • invokeai/backend/model_manager/load/model_loaders/krea2.py:409 loads standalone directory-format Qwen3-VL encoders without copying rope_parameters into rope_scaling. The bundled Diffusers and single-file paths explicitly perform this compatibility fix because the current Transformers implementation can otherwise crash. Apply the same normalization here. Add a standalone-directory loader test where rope_scaling is absent and rope_parameters is present.

  • invokeai/backend/patches/lora_conversions/krea2_lora_conversion_utils.py:85 discards a layer's stored .alpha and .dora_scale whenever the layer uses PEFT lora_A/lora_B keys. This changes explicit LoRA scaling and turns DoRA weights into ordinary LoRA weights. Preserve both values during normalization. Add conversion tests asserting that per-layer alpha is retained and that a PEFT DoRA layer produces a DoRA patch with its magnitude tensor.

  • invokeai/app/invocations/krea2_lora_loader.py:69 and invokeai/app/invocations/krea2_lora_loader.py:122 assume the transformer and encoder LoRA lists are synchronized. If a LoRA is already attached to only one field, the single loader raises before repairing the other field, while the collection loader's global added_loras list silently skips both. The result can be a transformer patch without its Qwen3-VL patch, or the reverse. Deduplicate independently per output field. Test both asymmetric starting states against both loader invocations.

  • invokeai/backend/model_manager/configs/lora.py:904 still requires text_fusion or time_mod_proj keys to classify a LoRA as Krea-2. A legitimate transformer-block-only Krea-2 LoRA is indistinguishable from Qwen Image automatically, but it also cannot be installed through an explicit Krea-2 selection because the same probe rejects it. Provide a deliberate override path for ambiguous LoRAs. Test automatic ambiguity plus successful explicit Krea-2 installation for transformer.transformer_blocks.*.lora_A/B weights.

  • invokeai/app/invocations/krea2_denoise.py:196 enables CFG globally when any entry in a list exceeds 1.0, and invokeai/app/invocations/krea2_denoise.py:354 then applies the CFG formula at every active step. A schedule such as [4.0, 1.0, 0.5] therefore applies unconditional blending at the 1.0 and 0.5 steps even though the invocation documents values <= 1 as disabling CFG. Decide CFG per step, using the conditional prediction directly when that step's scale is <= 1. Test mixed schedules, including clipped schedules whose active window contains no value above 1.0.

  • invokeai/app/invocations/krea2_denoise.py:245 rounds fractional denoising bounds independently. A valid narrow interval can round to identical indices, and invokeai/app/invocations/krea2_denoise.py:278 silently returns undenoised latents. Without input latents this returns raw noise for subsequent VAE decoding; with input latents it silently performs a no-op or noise blend. Reject intervals that produce zero effective steps, or explicitly define safe zero-step behavior. Test low step counts with bounds such as 0.0 to 0.01.

  • invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts:326 and invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts:580 treat a missing model-config cache entry as a non-Diffusers Krea-2 model. During startup, metadata recall, or direct dispatch, selecting a Diffusers model before getModelConfigs is populated can auto-select standalone components that buildKrea2Graph.ts later passes as stale overrides. The listener does not rerun when the cache arrives. Defer component changes until the format is known, or obtain the selected model's individual cached configuration. Test selection with an initially absent list cache followed by a Diffusers configuration response.

  • invokeai/backend/model_manager/configs/factory.py:424 now considers any root config.json an unambiguous model marker and bypasses the general-purpose-directory file-count guard. config.json is generic, so a large application or data directory can now be hashed and registered as an unknown model instead of being rejected. Restrict the bypass to recognized model configuration content or model_index.json. Test a large non-model directory containing an unrelated config.json.

  • invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:46 classifies a standalone Qwen3-VL directory solely from its config class. It does not require encoder weights or tokenizer assets, although Qwen3VLEncoderLoader uses local_files_only=True for both. An incomplete directory can therefore install successfully, satisfy readiness, and fail only during generation. Validate the required weight index/files and tokenizer files for direct and nested layouts. Add rejection tests for config-only, weights-only, and tokenizer-only directories.

  • The current focused tests do not exercise actual full Diffusers Krea-2 loading, standalone Qwen3-VL directory loading, single-file or GGUF model construction, prompt encoding with LoRA patches, CFG numerical behavior, or complete img2img/inpaint/outpaint execution. Add small fixture-based loader and invocation tests that reach model construction and forward boundaries rather than stopping at state-dict utilities and graph shape assertions.

  • The upgrade to diffusers==0.39.0 changes a shared dependency used by existing FLUX, Qwen Image, Z-Image, SD, and Anima loaders, but this PR contains no representative compatibility coverage for those paths. Add smoke coverage that constructs or loads one representative configuration from each affected family against the pinned version.

@JPPhoto

JPPhoto commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

New chunk I'm addressing:

  • invokeai/frontend/web/src/features/controlLayers/store/types.ts:793 keeps _version at 3 while lines 870-878 add eight required Krea-2 fields. paramsSliceConfig.persistConfig.migrate() in invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts:802 only backfills the earlier Qwen Image fields, so an existing version-3 state fails zParamsState.parse(). The catch in invokeai/frontend/web/src/app/store/store.ts:159 then replaces the entire parameter slice with defaults, discarding prompts, dimensions, seeds, model selections, and other saved generation settings. To expose this issue, add a migration test using a real pre-PR version-3 state with all Krea-2 fields absent and assert that existing settings are preserved while the new fields receive defaults.

  • invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:57 accepts every Qwen3VLModel or Qwen3VLForConditionalGeneration, even though Krea-2 requires the 4B encoder layout. invokeai/app/invocations/krea2_text_encoder.py:129 unconditionally reads hidden-state layer 35, and the transformer configuration at invokeai/backend/model_manager/load/model_loaders/krea2.py:196 requires a hidden width of 2560. Smaller Qwen3-VL variants can fail with an out-of-range hidden-state access, while larger variants produce conditioning with an incompatible width. Single-file checkpoints are additionally forced into the 4B configuration at invokeai/backend/model_manager/load/model_loaders/krea2.py:480. To expose this issue, add directory and checkpoint classification tests for non-4B hidden sizes and layer counts, plus a positive test for the exact 4B configuration.

  • The single-file probes accept formats their loaders cannot read. Main_Checkpoint_Krea2_Config.from_model_on_disk() in invokeai/backend/model_manager/configs/main.py:1418 and Qwen3VLEncoder_Checkpoint_Config.from_model_on_disk() in invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:110 do not restrict the suffix, so .bin, .pt, .pth, and .ckpt files can be classified through ModelOnDisk.load_state_dict(). The corresponding loaders call the safetensors-only load_file() at invokeai/backend/model_manager/load/model_loaders/krea2.py:306 and line 525. Such models install successfully but always fail when loaded. To expose this issue, add matching .bin probe cases and require either rejection during identification or loading through the appropriate PyTorch checkpoint reader.

  • The Krea-2 model-selection listener still has no lifecycle after deferring an unknown format. invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts:326 and line 582 do nothing when neither model-config cache contains the selected model, and the listener is registered only for modelSelected at line 74. When the configuration query later completes, the listener does not rerun. A non-Diffusers model remains blocked by invokeai/frontend/web/src/features/queue/store/readiness.ts:327 despite installed starter components, while persisted standalone components can remain attached to a Diffusers model and be passed as overrides by invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts:65. To expose this issue, add a listener test that selects a model with empty caches, then fulfills the model-config query and verifies that components are cleared or selected according to the resolved format.

  • Directory weight validation in invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:73 treats any top-level .safetensors or .bin file as a complete encoder. A directory containing only adapter_model.safetensors, training_args.bin, or one shard from a sharded checkpoint is therefore installable and satisfies readiness, but Qwen3VLModel.from_pretrained() at invokeai/backend/model_manager/load/model_loaders/krea2.py:418 cannot load it as a complete model. To expose this issue, add negative cases for unrelated artifacts and missing shards, and positive cases for recognized complete model.safetensors, indexed sharded safetensors, and pytorch_model.bin layouts.

  • The dedicated component metadata handlers validate the currently selected model but not the image metadata's model. Krea2VAEModel.parse() and Krea2Qwen3VlEncoderModel.parse() in invokeai/frontend/web/src/features/metadata/parsing.tsx:1175 and line 1199 omit the assertMetadataModelBase() check used by the Krea-2 scalar handlers. While a Krea-2 model is selected, metadata from a non-Krea image can therefore expose its generic vae as a Krea-2 recall action and store an incompatible VAE override, which later reaches the Krea graph and fails in the backend. To expose this issue, add cases with a selected Krea-2 model and non-Krea metadata containing a VAE or encoder, alongside positive Krea-2 metadata cases using supported Qwen Image and Anima-tagged VAEs.

  • The LoRA compatibility check trusts caller-supplied identifier metadata instead of the installed model record. invokeai/app/invocations/krea2_lora_loader.py:63 and line 135 check self.lora.base or lora.lora.base, while context.models.exists() and context.models.load() resolve only the key. A raw workflow can supply the key of an installed FLUX or SDXL LoRA but claim base: "krea-2", bypassing the new validation and producing outputs containing an incompatible LoRA. To expose this issue, add tests where the identifier claims Krea-2 but context.models.get_config() returns another base, and require rejection based on the stored configuration.

  • Explicit Krea-2 override still cannot install a text-encoder-only Krea-2 LoRA. invokeai/backend/model_manager/configs/lora.py:920 permits an ambiguous explicit override only when transformer-block keys are present, even though invokeai/backend/patches/lora_conversions/krea2_lora_conversion_utils.py:54 supports text_encoder.* keys and invokeai/app/invocations/krea2_text_encoder.py:91 applies those patches. A legitimate adapter trained only against Qwen3-VL is therefore rejected despite an explicit Krea-2 selection. To expose this issue, add an explicit-override test containing paired text_encoder.language_model.layers.*.lora_A.weight and lora_B.weight keys while retaining automatic rejection for ambiguous text-encoder LoRAs.

  • The synchronization repair in invokeai/app/invocations/krea2_lora_loader.py:76 and lines 141-158 handles a LoRA missing from one side, but silently preserves divergent weights when the same key already exists on both the transformer and encoder. Custom or chained workflows can consequently apply the transformer portion at one strength and the Qwen3-VL portion at another, and a subsequent loader invocation ignores its requested weight. To expose this issue, supply matching keys with different existing weights and require either a clear conflict error or deterministic normalization to one documented weight.

  • The tests still stop before the highest-risk runtime boundaries. The loader coverage under tests/backend/model_manager/load/test_krea2_state_dict_utils.py exercises helpers rather than constructing the full transformer or encoder, while tests/app/invocations/test_krea2_denoise.py primarily exercises schedule helpers and validation. There is no fixture-based coverage proving full Diffusers loading, standalone Qwen3-VL loading, single-file or GGUF construction, prompt encoding with LoRA patches, numerical CFG behavior, or complete img2img/inpaint/outpaint execution. Add small model fixtures that reach from_pretrained(), load_state_dict(), prompt encoding, transformer forward, and masked denoising boundaries with both valid and invalid inputs.

  • The shared upgrade to diffusers==0.39.0 remains unguarded for existing model families. The PR pins the new version in pyproject.toml and uv.lock, but its compatibility tests cover Krea-2 only. Because existing FLUX, Qwen Image, Z-Image, Stable Diffusion, and Anima loaders all import the same dependency, API or state-dict behavior changes can regress unrelated models without detection. Add representative loader-construction smoke tests for each affected family against the pinned release.

JPPhoto and others added 4 commits July 13, 2026 18:43
The rotary position ids (text tokens + image grid) were built once from the
positive prompt's length and reused for the negative pass. When the negative
prompt tokenizes to a different length than the positive one, the rotary
embedding ends up a different length than the uncond query sequence and the
transformer crashes in apply_rotary_emb ("tensor a (N) must match tensor b (M)").

Build a separate neg_position_ids from the negative prompt's length and pass it
to the uncond transformer call. txt2img with CFG off (distilled Turbo) is
unaffected — only the cond pass runs there.

Adds a regression test that drives differing positive/negative prompt lengths and
asserts len(position_ids) == text_len + image_tokens for each pass.
…A and tokenization

HIGH:
- qwen3_encoder: _has_qwen_vl_visual_tower now also matches the nested model.visual.*
  layout (mirroring _is_qwen3_vl_encoder_state_dict), so a single-file Qwen3-VL 4B
  encoder no longer matches BOTH the text-only Qwen3 and the Qwen3-VL configs. The
  nondeterministic tie-break could register it as the wrong type and hide it from
  Krea-2's encoder dropdown, hard-blocking the single-file/GGUF install path.

MEDIUM:
- krea2_text_encoder: tokenize (prefix+prompt) and the assistant-turn suffix separately
  and concatenate, so prompts over the token budget keep the suffix (append-after-truncate)
  instead of having it silently cut off.

LOW:
- main: _get_krea2_variant_from_name lets "turbo" win and only matches "raw"/"base" as
  whole tokens, so Turbo files like "krea2_turbo_baseline_q4.gguf" are not read as Base.
- krea2_lora_conversion_utils: raise a descriptive ValueError (not a bare KeyError) when a
  PEFT layer has lora_A without a matching lora_B.
- factory: read config.json as UTF-8 so a non-ASCII config is not mis-treated as
  unrecognized (and the model dir wrongly rejected) under a cp1252 locale.
- krea2 loader: _reject_incomplete_load also inspects named_buffers(), so a checkpoint
  missing a persistent buffer fails at load time rather than mid-inference.

Tests: Qwen3-VL dual-match rejection, long-prompt suffix preservation, addKrea2LoRAs
reroute, rebalance gains/validation, seed-variance determinism/out-of-place, variant
filename heuristic, incomplete-LoRA error, UTF-8 config dir, meta-buffer rejection.
…hift config

- loader: last.modulation.lin (native/GGUF) is reshaped to (2, hidden) to match
  diffusers Krea2FinalLayer.scale_shift_table, not just renamed. assign=True would
  otherwise install a flat 1-D parameter (which the meta-only completeness guard
  cannot catch), failing at inference on the primary GGUF/native path. Verified the
  final table is (2, hidden) and the per-block tables are (6, hidden) against the
  installed Krea2Transformer2DModel.
- denoise: the resolution-aware timestep shift (mu) now reads base_shift/max_shift/
  base_image_seq_len/max_image_seq_len from the loaded scheduler's config, falling
  back to the Krea-2 defaults, so a Raw checkpoint shipping a customized
  scheduler_config.json is sampled with its own shift parameters.

Adds a converter test asserting last.modulation.lin -> final_layer.scale_shift_table
is reshaped to (2, hidden).
@JPPhoto

JPPhoto commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Working on these next...

  • invokeai/app/invocations/krea2_denoise.py:274-277 and invokeai/app/invocations/krea2_denoise.py:383-394 use InvokeAI's standard CFG convention, uncond + cfg_scale * (cond - uncond), while the reference Krea-2 pipeline uses cond + guidance_scale * (cond - uncond) and disables guidance at 0.0. Consequently, the documented Raw default of 4.5 produces reference guidance 3.5, not 4.5. Either translate the reference recommendation to an InvokeAI CFG value of 5.5, or adopt the reference formula and its zero-disabled convention. To expose this issue, add a numerical test with fixed conditional and unconditional predictions and compare the result at the documented Raw default against the Diffusers Krea2Pipeline.

  • invokeai/backend/model_manager/configs/main.py:1412-1415 classifies a Diffusers pipeline with no is_distilled field as Turbo because config.get("is_distilled", True) defaults to True. Diffusers defines Krea2Pipeline.is_distilled with a default of False, and Krea2DenoiseInvocation._is_distilled() independently defaults a missing field to False. A converted or custom Raw pipeline that omits the optional field is therefore classified as Turbo and receives the wrong steps, CFG defaults, and fixed timestep shift. To expose this issue, add classification tests for is_distilled=true, is_distilled=false, and a missing field, requiring the missing case to follow the upstream default or be rejected as ambiguous.

  • invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/krea2ComponentSync.ts:27-33 treats any non-null VAE or encoder selection as valid without checking whether its key remains in the fulfilled compatible-model lists. If a selected standalone component is deleted, handleKrea2Components() in invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts:103-125 preserves the stale identifier. Readiness only checks for non-null selections, so enqueue remains enabled and the graph later fails on an unknown model key. The same logic preserves an installed but incompatible component introduced through persisted or recalled state. To expose this issue, add cases where the selected VAE or encoder is absent from the fulfilled list, with and without an available replacement, and require replacement or clearing respectively.

  • invokeai/frontend/web/src/features/metadata/parsing.tsx:1175-1183 confirms that recalled Krea-2 VAE metadata has type vae, but does not require its base to be qwen-image or anima. Metadata whose main model is correctly tagged krea-2 can therefore recall an SDXL, FLUX, or other incompatible VAE into the dedicated Krea-2 slot. Component synchronization then preserves it because it is non-null, readiness accepts it, and decoding fails in as_qwen_image_vae(). To expose this issue, add negative Krea-2 metadata cases containing SDXL and FLUX VAEs while retaining positive Qwen Image and Anima cases.

  • invokeai/app/invocations/krea2_model_loader.py:75-98 copies the caller-supplied main, VAE, and encoder identifiers into output fields without validating their installed model records. A raw workflow can provide the key of an unrelated main model, VAE, or encoder while spoofing the identifier fields expected by the node. The resulting graph fails later inside an unrelated model loader or VAE conversion instead of rejecting the incompatible component at the boundary. Validate the stored main record as Krea-2 main, the VAE as vae with base qwen-image or anima, and the encoder as qwen3_vl_encoder. To expose this issue, add positive tests for both supported VAE bases and negative tests where supplied identifiers claim compatible metadata but context.models.get_config() returns incompatible stored records.

  • invokeai/app/invocations/krea2_model_loader.py:56-63 declares the standalone VAE field with ui_model_base=BaseModelType.QwenImage, even though the loader, metadata tests, component selector, and compatibility layer explicitly support Anima-tagged VAEs. Users constructing a Krea-2 workflow directly in the node editor cannot select that supported VAE through this field. To expose this issue, inspect the invocation field schema and require its UI base filter to include both qwen-image and anima.

  • invokeai/app/invocations/krea2_denoise.py:83-91 does not require positive dimensions and permits non-finite CFG and shift values. Values such as width=0, height=-16, shift=NaN, or a non-finite entry in a CFG schedule pass field validation and then cause invalid tensor shapes, scheduler state, or silently disabled guidance. To expose this issue, add construction tests for zero and negative dimensions and for NaN or infinity in scalar and scheduled CFG values and shift, alongside positive finite boundary cases.

  • invokeai/app/invocations/krea2_conditioning_rebalance.py:41-53 accepts NaN and infinity in both multiplier and the comma-separated layer weights. invokeai/app/invocations/krea2_seed_variance.py:34-36 similarly accepts non-finite strength. These values poison the saved conditioning tensor and all downstream denoising steps. To expose this issue, add negative cases for non-finite multipliers, layer weights, and variance strengths, plus finite positive and zero cases where applicable.

  • invokeai/backend/model_manager/configs/factory.py:425-455 describes root configs as recognized model markers, but accepts any string-valued _class_name or model_type, or any non-empty string architectures[0]. A general-purpose directory can bypass the file-count safeguard by adding {"model_type":"application"} to config.json; classification then hashes and scans the directory before falling back to an unknown model. This leaves the expensive-directory protection incomplete. To expose this issue, extend the large-directory cases with arbitrary _class_name, model_type, and architectures values and require evidence that the marker belongs to a supported model configuration before bypassing the limit.

  • invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:43-52 filters non-string shard names out of weight_map instead of rejecting the malformed index. An index with one real shard and additional non-string entries is accepted as complete, but Transformers later consumes the original malformed map and fails during loading. The same code allows relative shard names to escape weights_path. To expose this issue, add negative cases for mixed string/non-string entries, absolute paths, and ../ traversal, and require every referenced shard to be a normalized filename contained beneath the encoder directory.

  • invokeai/app/invocations/qwen_image_latents_to_image.py:53-60 applies SeamlessExt.static_patch_model() to the cached AutoencoderKLWan and then replaces the active module with a newly constructed AutoencoderKLQwenImage. The new module shares weights but not the patched convolution methods, so custom workflows using an Anima-classified VAE with non-empty seamless_axes silently decode without seamless padding. Apply the seamless patch after as_qwen_image_vae() returns the module actually used for decoding. To expose this issue, add an Anima VAE conversion case with an instrumented convolution and assert that circular padding is active during decode and restored afterward.

@JPPhoto

JPPhoto commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

@Pfannkuchensack I addressed all of the above. Please do another pass on your end.

JPPhoto and others added 2 commits July 15, 2026 13:52
Add the two regression guards the loader/denoise fixes were missing:

- Validate _convert_krea2_native_to_diffusers against the real
  Krea2Transformer2DModel (built on the meta device from
  KREA2_TRANSFORMER_CONFIG). Every scale_shift_table is sized from the
  actual module dims and asserted after conversion, pinning
  final_layer.scale_shift_table to (2, hidden) and each per-block table
  to (6, hidden). The stub-based boundary tests could not catch a
  wrong-shaped converted tensor, since load_state_dict(assign=True)
  installs any shape and _reject_incomplete_load only checks the meta
  device, not shapes.

- Exercise the resolution-aware mu branch in Krea2Denoise._run_diffusion
  (shift=None, undistilled/Base config) so it is no longer dead: assert
  the mu passed to set_timesteps is derived from the loaded scheduler's
  base_shift/max_shift/base_image_seq_len/max_image_seq_len, and falls
  back to the Krea-2 defaults for absent keys.
@Pfannkuchensack Pfannkuchensack requested a review from JPPhoto July 15, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.14.x api backend PRs that change backend files DO NOT MERGE docs PRs that change docs frontend PRs that change frontend files invocations PRs that change invocations python PRs that change python files python-deps PRs that change python dependencies python-tests PRs that change python tests Root services PRs that change app services

Projects

Status: 6.14.x Theme: USER EXPERIENCE

Development

Successfully merging this pull request may close these issues.

4 participants