High-quality image generation on Apple Silicon using Z-Image models, ported to MLX.

This repository provides MLX implementations of the Z-Image family of 6B parameter diffusion transformer models, optimized for Apple Silicon Macs:
| Model | Steps | CFG | Negative Prompts | Best For |
|---|---|---|---|---|
| Z-Image (Base) | 28-50 | 3.0-5.0 | ✅ Yes | Fine-tuning, maximum quality |
| Z-Image-Turbo | 9 | 0.0 (disabled) | ❌ No | Fast generation |
Both models generate high-quality 1024×1024 images with the same architecture. The Base model offers more control with CFG and negative prompts, while Turbo is distilled for speed.
./logs/ for troubleshooting| Document | Description |
|---|---|
| WALKTHROUGH-DOCUMENTATION.md | Start here! Beginner-friendly guide covering installation, GUI usage, CLI commands, and tips for getting the best results |
| TECHNICAL_DOCUMENTATION.md | In-depth technical reference covering architecture, weight formats, quantization, model loading, and implementation details |
New to the project? Follow these steps:
# Create conda environment
conda create -n z-image-mlx python=3.12
conda activate z-image-mlx
# Install dependencies
pip install -r requirements.txt
# Convert model weights (auto-downloads from Hugging Face if not found)
cd src
# Convert Z-Image Base (recommended for fine-tuning)
python convert_to_mlx.py --model_type base
# Or convert Z-Image-Turbo (fast generation)
python convert_to_mlx.py --model_type turbo
The conversion script will automatically download the selected model from Hugging Face (~20GB) if it's not already present.
Launch the Gradio web interface:
python app.py
This opens a browser-based UI with:
cd src
python generate_mlx.py --prompt "A beautiful sunset over the ocean" --output sunset.png
# Z-Image Base (full control)
python src/generate_mlx.py \
--prompt "Your detailed prompt here" \
--negative_prompt "blurry, low quality" \
--output output.png \
--seed 42 \
--steps 28 \
--guidance_scale 4.0 \
--height 1024 \
--width 1024
# Z-Image-Turbo (fast)
python src/generate_mlx.py \
--prompt "Your detailed prompt here" \
--output output.png \
--seed 42 \
--steps 9 \
--height 1024 \
--width 1024 \
--cache medium
Use the --cache option for faster generation with minimal quality impact:
| Mode | Steps Computed | Speed Gain | Quality |
|---|---|---|---|
slow | 7/9 | ~14% faster | Highest |
medium | 6/9 | ~22% faster | Excellent |
fast | 5/9 | ~30% faster | Very Good |
# Fast mode for quick iterations
python src/generate_mlx.py --prompt "..." --cache fast
# Medium mode for balanced speed/quality
python src/generate_mlx.py --prompt "..." --cache medium
For comparison or on non-Apple hardware:
python src/generate_pytorch.py --prompt "Your prompt" --output output.png
Models are organized by platform:
models/
├── mlx/ # MLX-converted models (used for generation)
│ ├── Z-Image-MLX/ # Base model (recommended for fine-tuning)
│ ├── Z-Image-Turbo-MLX/ # Turbo model (fast generation)
│ └── RedCraft-AIO/ # Example: fine-tuned variant
└── pytorch/ # PyTorch/Diffusers format models
├── Z-Image/ # Base model
└── Z-Image-Turbo/ # Turbo model
If you're upgrading from a version that used the old directory structure (models/mlx_model/, models/Z-Image-Turbo/), run the migration script:
# Preview what will be migrated (dry run)
python migrate_models.py
# Apply the migration
python migrate_models.py --apply
The script will:
models/mlx/ and models/pytorch/ directoriesPlace pre-converted MLX models in models/mlx/<model_name>/. Each model folder should contain:
weights.safetensors - Transformer weightstext_encoder.safetensors - Text encoder weightsvae.safetensors - VAE decoder weightsconfig.json, vae_config.json, text_encoder_config.jsonDownload from Hugging Face and convert:
models/pytorch/<model_name>/python src/convert_to_mlx.pyThe app supports ComfyUI-style all-in-one .safetensors files for Z-Image-Turbo architecture:
diffusion_ prefix for transformer weightstext_encoders.qwen3_4b. prefixNote: Only Z-Image-Turbo architecture checkpoints are compatible. Other architectures (SDXL, SD1.5, Flux, Hunyuan) will be detected and show an error message.
username/model-name).safetensors fileUse the dropdown in Model Settings → Select Model to switch between available models. Click the refresh button (🔄) to rescan for newly added models.
LoRAs (Low-Rank Adaptations) allow you to customize the generation style without modifying the base model.
.safetensors LoRA files in models/loras/styles/, concepts/, characters/models/loras/
├── anime_style.safetensors
├── styles/
│ └── watercolor.safetensors
└── concepts/
└── cyberpunk.safetensors
| Feature | Description |
|---|---|
| Multiple LoRAs | Stack multiple LoRAs with independent weights |
| Per-LoRA Weights | Fine-tune each LoRA's influence (0.05 increments) |
| Trigger Words | Auto-displayed from LoRA metadata |
| Subfolder Support | Organize LoRAs in categories |
| Live Tags | See active LoRAs as <lora:name:weight> |
Note: Only Z-Image compatible LoRAs work. LoRAs trained for SDXL, SD1.5, Flux, etc. are NOT compatible. For training new LoRAs, the Base model is recommended.
LeMiCa (Lexicographic Minimax Path Caching) is a training-free acceleration technique that caches transformer residuals between denoising steps instead of recomputing from scratch.
output = input + cached_residual| Mode | Computed Steps | Speedup | Quality |
|---|---|---|---|
| None | 9/9 | Baseline | Reference |
| slow | 7/9 | ~14% faster | Highest |
| medium | 6/9 | ~22% faster | Excellent |
| fast | 5/9 | ~30% faster | Very Good |
GUI: Use the "⚡ LeMiCa Speed" dropdown below the Steps slider
CLI:
python src/generate_mlx.py --prompt "..." --cache medium
Based on LeMiCa: Lexicographic Minimax Path Caching (NeurIPS 2025 Spotlight). The Z-Image implementation uses optimized step schedules derived from the original research:
slow: Steps 0,1,2,3,5,7,8 compute (skip 4,6)medium: Steps 0,1,2,4,6,8 compute (skip 3,5,7)fast: Steps 0,1,2,5,8 compute (skip 3,4,6,7)You can permanently fuse loaded LoRAs into the base model and export to multiple formats:
models/mlx/)models/pytorch/)models/comfyui/)Combine multiple Z-Image-Turbo models to create novel blends using the Merge tab.
| Method | Formula | Use Case |
|---|---|---|
| Weighted Sum | (1-α)A + αB | Blend two models proportionally |
| Add Difference | A + α(B-C) | Extract fine-tune changes from B relative to C, apply to A |
((A⊕B)⊕C)⊕D...models/mlx/)models/pytorch/)models/comfyui/)The merged model will be saved in the selected format directories and can be used immediately.
z-image-turbo-mlx/
├── app.py # Gradio web UI (with LeMiCa & upscaling)
├── migrate_models.py # Migration script for directory structure
├── src/ # Core source files
│ ├── generate_mlx.py # MLX image generation (--cache for LeMiCa)
│ ├── generate_pytorch.py # PyTorch reference
│ ├── z_image_mlx.py # MLX transformer model (LeMiCa caching)
│ ├── text_encoder.py # MLX Qwen3-4B encoder
│ ├── vae.py # MLX VAE decoder
│ ├── lora.py # LoRA loading and application
│ ├── merge.py # Model merging algorithms
│ └── convert_to_mlx.py # Weight converter
├── models/ # Model weights
│ ├── mlx/ # MLX-converted models
│ ├── pytorch/ # PyTorch/Diffusers models
│ ├── loras/ # LoRA files (.safetensors)
│ └── upscalers/ # ESRGAN upscaler models
├── debugging/ # Debug & diagnostic tools
│ └── check_loras_import.py # Scan and validate LoRA files
└── requirements.txt
| Component | Details |
|---|---|
| Transformer | S3-DiT (Scalable Sparse DiT), 6B parameters |
| Text Encoder | Qwen3-4B (hidden_size=2560, 36 layers) |
| VAE | FLUX.1-dev compatible (16 latent channels) |
| Scheduler | FlowMatchEulerDiscreteScheduler (shift=3.0) |
| Resolution | 1024×1024 (128×128 latents) |
| Variant | HuggingFace ID | Steps | CFG | Negative Prompts |
|---|---|---|---|---|
| Base | Tongyi-MAI/Z-Image | 28-50 | 3.0-5.0 | ✅ Yes |
| Turbo | Tongyi-MAI/Z-Image-Turbo | 9 | 0.0 | ❌ No |
The Base model is recommended for fine-tuning/LoRA training. Turbo is distilled for fast inference.
| Device | Generation Time (9 steps) |
|---|---|
| M2 Ultra | ~XX seconds |
| M3 Max | ~XX seconds |
| M1 Max | ~XX seconds |
(Performance numbers to be updated)
The model requires significant RAM. If you encounter memory issues:
models/mlx/<model_name>/When importing a single-file checkpoint, you may see an error like:
This means the checkpoint is not a Z-Image-Turbo model. Only checkpoints fine-tuned from Z-Image-Turbo are compatible.
Ensure you're running from the correct directory:
cd z-image-turbo-mlx
python src/generate_mlx.py --prompt "..."
Or specify the model path explicitly:
python src/generate_mlx.py --model_path /full/path/to/models/mlx/mlx_model --prompt "..."
This project is for research and personal use. Please refer to the original Z-Image-Turbo model license for usage terms.
@article{team2025zimage,
title={Z-Image: An Efficient Image Generation Foundation Model with Single-Stream Diffusion Transformer},
author={Z-Image Team},
journal={arXiv preprint arXiv:2511.22699},
year={2025}
}
@inproceedings{gao2025lemica,
title={LeMiCa: Lexicographic Minimax Path Caching for Efficient Diffusion-Based Video Generation},
author={Huanlin Gao and Ping Chen and Fuyuan Shi and Chao Tan and Zhaoxiang Liu and Fang Zhao and Kai Wang and Shiguo Lian},
journal={Advances in Neural Information Processing Systems (NeurIPS)},
year={2025},
url={https://arxiv.org/abs/2511.00090}
}
@article{liu2025decoupled,
title={Decoupled DMD: CFG Augmentation as the Spear, Distribution Matching as the Shield},
author={Dongyang Liu and Peng Gao and David Liu and Ruoyi Du and Zhen Li and Qilong Wu and Xin Jin and Sihan Cao and Shifeng Zhang and Hongsheng Li and Steven Hoi},
journal={arXiv preprint arXiv:2511.22677},
year={2025}
}
@article{jiang2025distribution,
title={Distribution Matching Distillation Meets Reinforcement Learning},
author={Jiang, Dengyang and Liu, Dongyang and Wang, Zanyi and Wu, Qilong and Jin, Xin and Liu, David and Li, Zhen and Wang, Mengmeng and Gao, Peng and Yang, Harry},
journal={arXiv preprint arXiv:2511.13649},
year={2025}
}
51 commits
Python
100.0%
High-quality image generation on Apple Silicon using Z-Image models, ported to MLX.

This repository provides MLX implementations of the Z-Image family of 6B parameter diffusion transformer models, optimized for Apple Silicon Macs:
| Model | Steps | CFG | Negative Prompts | Best For |
|---|---|---|---|---|
| Z-Image (Base) | 28-50 | 3.0-5.0 | ✅ Yes | Fine-tuning, maximum quality |
| Z-Image-Turbo | 9 | 0.0 (disabled) | ❌ No | Fast generation |
Both models generate high-quality 1024×1024 images with the same architecture. The Base model offers more control with CFG and negative prompts, while Turbo is distilled for speed.
./logs/ for troubleshooting| Document | Description |
|---|---|
| WALKTHROUGH-DOCUMENTATION.md | Start here! Beginner-friendly guide covering installation, GUI usage, CLI commands, and tips for getting the best results |
| TECHNICAL_DOCUMENTATION.md | In-depth technical reference covering architecture, weight formats, quantization, model loading, and implementation details |
New to the project? Follow these steps:
# Create conda environment
conda create -n z-image-mlx python=3.12
conda activate z-image-mlx
# Install dependencies
pip install -r requirements.txt
# Convert model weights (auto-downloads from Hugging Face if not found)
cd src
# Convert Z-Image Base (recommended for fine-tuning)
python convert_to_mlx.py --model_type base
# Or convert Z-Image-Turbo (fast generation)
python convert_to_mlx.py --model_type turbo
The conversion script will automatically download the selected model from Hugging Face (~20GB) if it's not already present.
Launch the Gradio web interface:
python app.py
This opens a browser-based UI with:
cd src
python generate_mlx.py --prompt "A beautiful sunset over the ocean" --output sunset.png
# Z-Image Base (full control)
python src/generate_mlx.py \
--prompt "Your detailed prompt here" \
--negative_prompt "blurry, low quality" \
--output output.png \
--seed 42 \
--steps 28 \
--guidance_scale 4.0 \
--height 1024 \
--width 1024
# Z-Image-Turbo (fast)
python src/generate_mlx.py \
--prompt "Your detailed prompt here" \
--output output.png \
--seed 42 \
--steps 9 \
--height 1024 \
--width 1024 \
--cache medium
Use the --cache option for faster generation with minimal quality impact:
| Mode | Steps Computed | Speed Gain | Quality |
|---|---|---|---|
slow | 7/9 | ~14% faster | Highest |
medium | 6/9 | ~22% faster | Excellent |
fast | 5/9 | ~30% faster | Very Good |
# Fast mode for quick iterations
python src/generate_mlx.py --prompt "..." --cache fast
# Medium mode for balanced speed/quality
python src/generate_mlx.py --prompt "..." --cache medium
For comparison or on non-Apple hardware:
python src/generate_pytorch.py --prompt "Your prompt" --output output.png
Models are organized by platform:
models/
├── mlx/ # MLX-converted models (used for generation)
│ ├── Z-Image-MLX/ # Base model (recommended for fine-tuning)
│ ├── Z-Image-Turbo-MLX/ # Turbo model (fast generation)
│ └── RedCraft-AIO/ # Example: fine-tuned variant
└── pytorch/ # PyTorch/Diffusers format models
├── Z-Image/ # Base model
└── Z-Image-Turbo/ # Turbo model
If you're upgrading from a version that used the old directory structure (models/mlx_model/, models/Z-Image-Turbo/), run the migration script:
# Preview what will be migrated (dry run)
python migrate_models.py
# Apply the migration
python migrate_models.py --apply
The script will:
models/mlx/ and models/pytorch/ directoriesPlace pre-converted MLX models in models/mlx/<model_name>/. Each model folder should contain:
weights.safetensors - Transformer weightstext_encoder.safetensors - Text encoder weightsvae.safetensors - VAE decoder weightsconfig.json, vae_config.json, text_encoder_config.jsonDownload from Hugging Face and convert:
models/pytorch/<model_name>/python src/convert_to_mlx.pyThe app supports ComfyUI-style all-in-one .safetensors files for Z-Image-Turbo architecture:
diffusion_ prefix for transformer weightstext_encoders.qwen3_4b. prefixNote: Only Z-Image-Turbo architecture checkpoints are compatible. Other architectures (SDXL, SD1.5, Flux, Hunyuan) will be detected and show an error message.
username/model-name).safetensors fileUse the dropdown in Model Settings → Select Model to switch between available models. Click the refresh button (🔄) to rescan for newly added models.
LoRAs (Low-Rank Adaptations) allow you to customize the generation style without modifying the base model.
.safetensors LoRA files in models/loras/styles/, concepts/, characters/models/loras/
├── anime_style.safetensors
├── styles/
│ └── watercolor.safetensors
└── concepts/
└── cyberpunk.safetensors
| Feature | Description |
|---|---|
| Multiple LoRAs | Stack multiple LoRAs with independent weights |
| Per-LoRA Weights | Fine-tune each LoRA's influence (0.05 increments) |
| Trigger Words | Auto-displayed from LoRA metadata |
| Subfolder Support | Organize LoRAs in categories |
| Live Tags | See active LoRAs as <lora:name:weight> |
Note: Only Z-Image compatible LoRAs work. LoRAs trained for SDXL, SD1.5, Flux, etc. are NOT compatible. For training new LoRAs, the Base model is recommended.
LeMiCa (Lexicographic Minimax Path Caching) is a training-free acceleration technique that caches transformer residuals between denoising steps instead of recomputing from scratch.
output = input + cached_residual| Mode | Computed Steps | Speedup | Quality |
|---|---|---|---|
| None | 9/9 | Baseline | Reference |
| slow | 7/9 | ~14% faster | Highest |
| medium | 6/9 | ~22% faster | Excellent |
| fast | 5/9 | ~30% faster | Very Good |
GUI: Use the "⚡ LeMiCa Speed" dropdown below the Steps slider
CLI:
python src/generate_mlx.py --prompt "..." --cache medium
Based on LeMiCa: Lexicographic Minimax Path Caching (NeurIPS 2025 Spotlight). The Z-Image implementation uses optimized step schedules derived from the original research:
slow: Steps 0,1,2,3,5,7,8 compute (skip 4,6)medium: Steps 0,1,2,4,6,8 compute (skip 3,5,7)fast: Steps 0,1,2,5,8 compute (skip 3,4,6,7)You can permanently fuse loaded LoRAs into the base model and export to multiple formats:
models/mlx/)models/pytorch/)models/comfyui/)Combine multiple Z-Image-Turbo models to create novel blends using the Merge tab.
| Method | Formula | Use Case |
|---|---|---|
| Weighted Sum | (1-α)A + αB | Blend two models proportionally |
| Add Difference | A + α(B-C) | Extract fine-tune changes from B relative to C, apply to A |
((A⊕B)⊕C)⊕D...models/mlx/)models/pytorch/)models/comfyui/)The merged model will be saved in the selected format directories and can be used immediately.
z-image-turbo-mlx/
├── app.py # Gradio web UI (with LeMiCa & upscaling)
├── migrate_models.py # Migration script for directory structure
├── src/ # Core source files
│ ├── generate_mlx.py # MLX image generation (--cache for LeMiCa)
│ ├── generate_pytorch.py # PyTorch reference
│ ├── z_image_mlx.py # MLX transformer model (LeMiCa caching)
│ ├── text_encoder.py # MLX Qwen3-4B encoder
│ ├── vae.py # MLX VAE decoder
│ ├── lora.py # LoRA loading and application
│ ├── merge.py # Model merging algorithms
│ └── convert_to_mlx.py # Weight converter
├── models/ # Model weights
│ ├── mlx/ # MLX-converted models
│ ├── pytorch/ # PyTorch/Diffusers models
│ ├── loras/ # LoRA files (.safetensors)
│ └── upscalers/ # ESRGAN upscaler models
├── debugging/ # Debug & diagnostic tools
│ └── check_loras_import.py # Scan and validate LoRA files
└── requirements.txt
| Component | Details |
|---|---|
| Transformer | S3-DiT (Scalable Sparse DiT), 6B parameters |
| Text Encoder | Qwen3-4B (hidden_size=2560, 36 layers) |
| VAE | FLUX.1-dev compatible (16 latent channels) |
| Scheduler | FlowMatchEulerDiscreteScheduler (shift=3.0) |
| Resolution | 1024×1024 (128×128 latents) |
| Variant | HuggingFace ID | Steps | CFG | Negative Prompts |
|---|---|---|---|---|
| Base | Tongyi-MAI/Z-Image | 28-50 | 3.0-5.0 | ✅ Yes |
| Turbo | Tongyi-MAI/Z-Image-Turbo | 9 | 0.0 | ❌ No |
The Base model is recommended for fine-tuning/LoRA training. Turbo is distilled for fast inference.
| Device | Generation Time (9 steps) |
|---|---|
| M2 Ultra | ~XX seconds |
| M3 Max | ~XX seconds |
| M1 Max | ~XX seconds |
(Performance numbers to be updated)
The model requires significant RAM. If you encounter memory issues:
models/mlx/<model_name>/When importing a single-file checkpoint, you may see an error like:
This means the checkpoint is not a Z-Image-Turbo model. Only checkpoints fine-tuned from Z-Image-Turbo are compatible.
Ensure you're running from the correct directory:
cd z-image-turbo-mlx
python src/generate_mlx.py --prompt "..."
Or specify the model path explicitly:
python src/generate_mlx.py --model_path /full/path/to/models/mlx/mlx_model --prompt "..."
This project is for research and personal use. Please refer to the original Z-Image-Turbo model license for usage terms.
@article{team2025zimage,
title={Z-Image: An Efficient Image Generation Foundation Model with Single-Stream Diffusion Transformer},
author={Z-Image Team},
journal={arXiv preprint arXiv:2511.22699},
year={2025}
}
@inproceedings{gao2025lemica,
title={LeMiCa: Lexicographic Minimax Path Caching for Efficient Diffusion-Based Video Generation},
author={Huanlin Gao and Ping Chen and Fuyuan Shi and Chao Tan and Zhaoxiang Liu and Fang Zhao and Kai Wang and Shiguo Lian},
journal={Advances in Neural Information Processing Systems (NeurIPS)},
year={2025},
url={https://arxiv.org/abs/2511.00090}
}
@article{liu2025decoupled,
title={Decoupled DMD: CFG Augmentation as the Spear, Distribution Matching as the Shield},
author={Dongyang Liu and Peng Gao and David Liu and Ruoyi Du and Zhen Li and Qilong Wu and Xin Jin and Sihan Cao and Shifeng Zhang and Hongsheng Li and Steven Hoi},
journal={arXiv preprint arXiv:2511.22677},
year={2025}
}
@article{jiang2025distribution,
title={Distribution Matching Distillation Meets Reinforcement Learning},
author={Jiang, Dengyang and Liu, Dongyang and Wang, Zanyi and Wu, Qilong and Jin, Xin and Liu, David and Li, Zhen and Wang, Mengmeng and Gao, Peng and Yang, Harry},
journal={arXiv preprint arXiv:2511.13649},
year={2025}
}
51 commits
Python
100.0%