Skip to content

feat: Add Z-Image and Z-Image-Turbo support to MaxDiffusion#446

Open
csgoogle wants to merge 1 commit into
mainfrom
sagarchapara/zimage
Open

feat: Add Z-Image and Z-Image-Turbo support to MaxDiffusion#446
csgoogle wants to merge 1 commit into
mainfrom
sagarchapara/zimage

Conversation

@csgoogle

@csgoogle csgoogle commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Add Z-Image and Z-Image-Turbo support

Adds the Tongyi-MAI Z-Image family to MaxDiffusion: a 6.15B flow-matching DiT, its Flux-format VAE, and a Qwen3-4B text encoder — all running in JAX on TPU, with an Orbax cache for the whole pipeline.

What's here

models/z_image/transformer_z_image.py NNX port of the 6.15B denoiser
models/z_image/z_image_utils.py Streaming Diffusers→NNX checkpoint conversion
pipelines/z_image/z_image_pipeline.py Runtime pipeline: encode → denoise → decode
checkpointing/z_image_checkpointer.py All loading, plus the Orbax cache
models/qwen3_utils.py Qwen3 checkpoint conversion, split out of qwen3_flax.py
generate_zimage.py Driver, structured like generate_wan.py
configs/base_zimage{,_turbo}.yml Inference configs
tests/z_image/ Transformer + module-parity tests

Performance (v6e-8, Z-Image-Turbo, 1024², 9 steps)

8 images (per_device_batch_size: 1.0) 1 image
generation 2.47s — 0.31s/image 0.59s
compile ~110s ~44s
load (warm Orbax cache) ~12–20s ~15s

Default mesh is data=8. Measured alternatives at batch 8: data=4/ctx=2 0.325s/img, ctx=8 0.519s/img, fsdp=8 1.179s/img.

Notable fixes made along the way

  • NNXFlaxQwen3Attention was numerically broken — no causal mask, and it read attention_mask as additive when callers pass 0/1. Cosine 0.242 vs HF Transformers; now 0.999996. Its existing test never checked numerics.
  • Qwen3 weights were stored fp32 under a bf16 config. Flax stores params in param_dtype (float32 default) regardless of compute dtype, so the 4B encoder occupied 16.1 GB/chip instead of 8.0. Norm scales stay fp32 deliberately, now declared in the module.
  • get_git_commit_hash / GCS upload / delete_file / save_images moved to max_utils, deduping ~90 lines across the generate_wan, generate_ltx2 and generate_zimage drivers.

Verification

  • Qwen3 encoder vs HF Transformers on the real 4B checkpoint: cosine 0.999996.
  • Orbax round trip on tiny models: param values, dtypes, target shardings, and a jitted batched generation.
  • Full cold and warm runs on v6e-8; output is visually correct and matches the pre-refactor reference.
  • pyink --check clean across 319 files; ruff clean on all touched files.
image
  • We could extend max batchsize > 256, by offloading the Qwen Encoder.

@github-actions

Copy link
Copy Markdown

@csgoogle
csgoogle marked this pull request as ready for review July 22, 2026 05:35
@csgoogle
csgoogle requested a review from entrpn as a code owner July 22, 2026 05:35
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@csgoogle
csgoogle force-pushed the sagarchapara/zimage branch 9 times, most recently from f56b6a1 to b6c4e39 Compare July 23, 2026 07:51
@csgoogle csgoogle self-assigned this Jul 23, 2026
@csgoogle
csgoogle force-pushed the sagarchapara/zimage branch from b6c4e39 to c176505 Compare July 23, 2026 11:39
…harding specs

- Pre-split text_encoder and transformer during initialization to avoid host-side splitting CPU overhead.
- Fully tensorize ZImageTransformer2DModel __call__ forward path using statically-padded 3D stacked sequences, bypassing cross-device all-reduce/all-gather collectives and loops.
- Pass 4D transposed layouts directly to NNXAttentionOp to bypass unflatten/flatten transposes.
- Maintain RMSNorm outputs in float32 and pass them directly into _apply_rope to enable seamless on-device loop/kernel fusion and avoid float32 <-> bfloat16 casting loops.
- Inline latent generation logic inside pipeline call, removing redundant JIT overhead.
- Add logical sharding specs and registry for Z-Image transformer.
@csgoogle
csgoogle force-pushed the sagarchapara/zimage branch from c176505 to 7d5e1d0 Compare July 23, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant