SIGN IN SIGN UP

fix(format-adapters): complete QwenImageLayered arch enumeration across staging chain

A QwenImageLayered raw single-file checkpoint (e.g. qwen_image_layered_control_bf16.safetensors)
crashed at staging with `ValueError: Unknown arch: 'QwenImageLayered'` in
format_adapters/tools/hf_layout.py::HFLayout.write_model_index — the engine .so was never
reached. arch_fingerprint.py already recognizes QwenImageLayered (CLASS_NAME_TO_ARCH +
addition_t_embedding key detection), but the downstream staging dispatch tables /
bundled-asset lookups only enumerated {QwenImage, QwenImageEdit, Flux2Klein, ZImage}, so a
layered checkpoint fingerprinted then crashed and silently mis-staged transformer-class /
TE config / tokenizer / scheduler.

Complete the enumeration across the whole staging chain:
- hf_layout.py: add QwenImageLayered to ARCH_TO_PIPELINE_CLASS (QwenImageLayeredPipeline) and
  ARCH_TO_TRANSFORMER_CLASS (QwenImageTransformer2DModel, shared). Add BUNDLED_ASSET_ARCH_ALIAS
  + _bundled_asset_arch() aliasing QwenImageLayered->QwenImage for the TE config / tokenizer /
  scheduler bundled lookups (byte-identical to base QwenImage; avoids duplicating the ~5 MB
  tokenizer). The VAE is intentionally NOT aliased — layered's VAE is 4-channel RGBA
  (AutoencoderKLQwenImage, input_channels=4) and ships its own bin/vae_configs/QwenImageLayered.json.
- weight_derived_config.py: _TRANSFORMER_DESCRIPTORS["QwenImageLayered"] = QwenImage's (same
  transformer_blocks layout -> identical weight-derived dims).
- hf_native.py: replace the drifted inline arch->transformer-class dict with the central
  ARCH_TO_TRANSFORMER_CLASS (DRY; auto-covers layered; behavior-preserving for existing archs).
- nunchaku_svdq.py: a layered SVDQ reuses QwenImageTransformer2DModel so the class string can't
  disambiguate it from base QwenImage — confirm via fingerprint_arch_from_keys (addition_t_embedding)
  when arch would otherwise default to base QwenImage. Upgrade-only -> ZImage/Edit detection (#408)
  untouched.

Verified: drove the real ComfyUIDiffusionModelAdapter.adapt() against the actual 40GB layered
checkpoint -> complete diffusers layout (model_index QwenImageLayeredPipeline, weight-derived
transformer config 60 layers, tokenizer, scheduler) with no crash. The engine reads the VAE
class from vae/config.json (QwenImageLayeredPipeline.cpp:103), not the model_index vae tuple,
so the 4-ch VAE config is correctly selected. worker.py untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Y
yejianhui committed
8677d71211d5430a62c764ef231dd19c82fc6fee
Parent: 54ac629