+
Weights: pretrained Keras weights live on Hugging Face under
+
zeromodels/<variant>
+(each repo carries
zm_config.json + sharded
+
*.weights.json /
*.weights.h5 +
+
tokenizer.json). Load with
from_weights("zeromodels/<variant>").
+
+
+Qwen-Image, ported to pure Keras 3: latent text-to-image flow-matching with a
+60-layer double-stream MMDiT denoiser, a Wan-derived KL autoencoder and the
+Qwen2.5-VL-7B Instruct text tower. The whole model is **one container**,
+`QwenImageModel`, a single functional graph with the three towers as disconnected
+sub-graphs (the way `CLIPModel` holds its two), so a hosted repo is one set of
+sharded weights and one `zm_config.json`. `QwenImageTextToImage` is that same
+graph plus `generate`: the true-CFG denoising loop of `BaseDiffusion`, the
+diffusion counterpart of `BaseGeneration`.
+
+The weights are converted once, offline, and hosted: on-the-fly `hf:` conversion
+is deliberately **not supported** for diffusion models.
+
+Key facts of the port:
+
+- **Packed latents**: the denoiser sees `(B, H/2 · W/2, 64)` tokens; pack / unpack
+ match Diffusers' 2×2 patching around the 16-channel VAE latent grid
+ (`AutoencoderKLQwenImage`, 8× spatial, channels-last NDHWC with `T=1`).
+- **True CFG**: when `guidance_scale > 1`, two transformer forwards and Diffusers'
+ prediction-norm renormalization (`true_cfg_scale`); a space negative prompt is
+ the default when none is passed.
+- **bf16-safe dual-stream clip**: Diffusers clips dual-stream activations to the
+ fp16 finite range only under float16; the port matches that, so bf16 runs keep
+ the ~1e7 magnitudes Qwen-Image produces instead of collapsing to noise.
+- **Schedulers match Diffusers**: `FlowMatchEulerDiscreteScheduler` with dynamic
+ resolution shifting (`mu` from packed sequence length) so timesteps agree with
+ the reference within float rounding.
+- **Verified against Diffusers**: transformer, text encoder, VAE and scheduler
+ outputs agree with the reference within float noise (see
+ [Verified against Diffusers](#verified-against-diffusers)).
+
+Links:
+
+- Paper: [Qwen-Image Technical Report (arXiv:2508.02324)](https://arxiv.org/abs/2508.02324)
+- Reference implementation: [diffusers `QwenImagePipeline`](https://huggingface.co/docs/diffusers/api/pipelines/qwenimage)
+- License: [Apache-2.0](https://huggingface.co/Qwen/Qwen-Image/blob/main/LICENSE)
+
+See also [qwen2_5_vl.md](qwen2_5_vl.md) (the text tower),
+[stable_diffusion_3.md](stable_diffusion_3.md) (flow-match / MMDiT-style diffusion
+in ZeroModels).
+
+## Variants
+
+Preconverted, bfloat16 weights are hosted under `zeromodels/`. Load with
+`from_weights("zeromodels/