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.
- Dual model support: Both Z-Image Base and Z-Image-Turbo with automatic parameter adjustment
- Negative prompting: Full support for negative prompts (Base model only)
- Classifier-free guidance: Adjustable CFG scale 0.0-10.0 (Base model)
- Fast generation: 9 inference steps for Turbo, 28-50 for Base
- LeMiCa speed acceleration: Training-free caching for up to 30% faster generation
- Apple Silicon optimized: Native MLX implementation for M1/M2/M3/M4 Macs
- Bit-perfect accuracy: MLX output matches PyTorch within 1 pixel per channel
- Model management: Support for multiple models and fine-tuned variants
- LoRA support: Apply style and concept customizations with adjustable weights
- LoRA fusion: Permanently fuse LoRAs and export to MLX, PyTorch, or ComfyUI formats
- Model merging: Combine multiple models using Weighted Sum or Add Difference methods
- Latent upscaling: Upscale in latent space for enhanced detail before decoding
- ESRGAN upscaling: 4× pixel-space resolution enhancement with RRDB-based models
- Random prompt generation: Auto-generates creative prompts when input is empty
- Comprehensive logging: Detailed logs in
./logs/for troubleshooting - Scrollable LoRA list: Browse all installed LoRAs with improved UI
- Gradio UI: User-friendly web interface for image generation
- LoRA fine-tuning: Train custom LoRAs (Base model recommended)
| 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:
- Read the Installation section below
- Follow the User Walkthrough Guide for step-by-step usage instructions
- Consult the Technical Documentation if you need to understand the internals or debug issues
- macOS 12.3+ with Apple Silicon (M1/M2/M3/M4)
- Python 3.10+
- ~20GB disk space for model weights
# 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 turboThe 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.pyThis opens a browser-based UI with:
- Generation Tab: Create images with full control over parameters
- Model Settings Tab: Manage, import, and switch between models
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 mediumUse 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 mediumFor comparison or on non-Apple hardware:
python src/generate_pytorch.py --prompt "Your prompt" --output output.pngModels 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 --applyThe script will:
- Create the new
models/mlx/andmodels/pytorch/directories - Move existing models to the correct locations
- Validate that models are still accessible after migration
Place 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.json
Download from Hugging Face and convert:
- Place in
models/pytorch/<model_name>/ - Run
python src/convert_to_mlx.py
The app supports ComfyUI-style all-in-one .safetensors files for Z-Image-Turbo architecture:
- These use
diffusion_prefix for transformer weights - Text encoder weights use
text_encoders.qwen3_4b.prefix - Import via Model Settings → Import Single-File Checkpoint
Note: Only Z-Image-Turbo architecture checkpoints are compatible. Other architectures (SDXL, SD1.5, Flux, Hunyuan) will be detected and show an error message.
- Go to Model Settings → Import from Hugging Face
- Enter the repository ID (e.g.,
username/model-name) - Select format: "Diffusers (requires conversion)" or "Pre-converted MLX"
- Click Download Model
- Go to Model Settings → Import Single-File Checkpoint
- Click Browse and select your
.safetensorsfile - The app will validate compatibility before import
- Enter a name for the model and click Import
Use 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.
- Place
.safetensorsLoRA files inmodels/loras/ - Optionally organize in subfolders:
styles/,concepts/,characters/
models/loras/
├── anime_style.safetensors
├── styles/
│ └── watercolor.safetensors
└── concepts/
└── cyberpunk.safetensors
- In the Generate tab, expand 🎨 LoRA Settings
- Enable desired LoRAs with the checkbox
- Adjust weight (0.0-2.0) using the spinner
- Include trigger words in your prompt if the LoRA has them
| 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.
- On "compute" steps, the full transformer forward pass runs and stores the residual
- On "skip" steps, the cached residual is reused:
output = input + cached_residual - The schedule determines which steps compute vs skip
| 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 mediumBased 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:
- Configure your LoRAs with desired weights in the LoRA Settings panel
- Enter a name for your fused model
- Select output formats:
- MLX: Ready for use in this app (
models/mlx/) - PyTorch: Diffusers format for sharing (
models/pytorch/) - ComfyUI: Single-file checkpoint (
models/comfyui/)
- MLX: Ready for use in this app (
- Click Save Fused Model
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 |
- Sequential merging for 3+ models:
((A⊕B)⊕C)⊕D... - Memory-safe mode: Auto-chunked processing for systems with <32GB RAM
- Base model integration: Uses Generate tab's selected model (with fused LoRAs) as Model A
- FP16+ only: Excludes FP8 quantized models from merging
- Select your base model in the Generate tab
- Go to the Merge tab
- Choose a merge method (Weighted Sum or Add Difference)
- Enable models to merge and set their weights (0.0-1.0)
- For Add Difference: Also select Model C (the original model B was fine-tuned from)
- Enter an output model name
- Select output formats:
- MLX: Ready for use in this app (
models/mlx/) - PyTorch: Diffusers format for sharing (
models/pytorch/) - ComfyUI: Single-file checkpoint (
models/comfyui/)
- MLX: Ready for use in this app (
- Click Merge Models
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:
- Close other applications
- Use a smaller resolution (e.g., 512×512)
- Consider using CPU offloading (PyTorch only)
- Ensure the model is in
models/mlx/<model_name>/ - Check that all required files are present (weights.safetensors, etc.)
- Click the refresh button (🔄) to rescan
When importing a single-file checkpoint, you may see an error like:
- "SDXL checkpoint detected"
- "Flux model detected"
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.
- Original Z-Image-Turbo model from Tongyi-MAI
- MLX framework by Apple
- Diffusers library by Hugging Face
- LeMiCa acceleration from UnicomAI
@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}
}