Core ML conversion of Qwen-Image-2.1 for Mac
Generate 1024 Γ 1024 images locally. Get 2.4β2.6Γ faster denoising than PyTorch MPS.
Generate your first image β Β· Download the packages Β· See example images
| 2.4β2.6Γ faster | 7.0Γ faster | 3.7β4.2 minutes |
|---|---|---|
| Median denoising step vs PyTorch bf16/MPS | Same two-block graph vs Core ML CPU + ANE | 40 denoising steps at 1024 Γ 1024 |
Measured on an M5 MacBook Pro, 32 GB unified memory, with Core ML FP16 and
cpu_and_gpu. The CPU + ANE comparison covers two transformer blocks;
the full GPU generation records cover all 32. Denoising timings exclude text
encoding, model loading, and prompt prefix computation.
Measurement details Β· Raw benchmark records
Best mode for measured speed: CPU + GPU (
cpu_and_gpu). Recommended for the tested M5 setup and already the default in the companion CLI and Python API. Use the recommended setting.
Download six preconverted FP16 packages here, then use the companion Python pipeline and its four included prompt embeddings to generate images locally. The denoiser and VAE decoder were converted by Devin Lai, based on Qwen's model. The complete pipeline requires macOS 15 or newer on Apple silicon and supports 1024 Γ 1024 text-to-image generation, batch size 1, and up to 64 encoded prompt tokens.
Performance on Apple silicon
2.4β2.6Γ faster denoising steps than PyTorch MPS. The recorded Core ML runs complete 40 denoising steps at 1024 Γ 1024 in 3.7β4.2 minutes, with the VAE adding about 1.9 seconds of warmed prediction time.
| Metric | Core ML fp16 (cpu_and_gpu) |
Reference or context |
|---|---|---|
| Median denoising step | 5.43β5.95 s | PyTorch bf16 on MPS: 14.25 s; 2.4β2.6Γ speedup |
| 40 denoising steps | 221β250 s | 1024 Γ 1024, seed 42; denoising only |
| VAE prediction | 1.91 s | 1024 Γ 1024 RGBA, GPU, warmed model |
| Noise-prediction PSNR vs fp32 | 71.55 dB | PyTorch bf16: 55.80 dB; 15.8 dB higher, about 6.1Γ lower RMS error |
| Transformer package size | 14.06 GB | Separate prefix/decode packages: 28.02 GB; 50% smaller through shared weights |
Measured on an M5 MacBook Pro with 32 GB unified memory, macOS 27.0,
coremltools 9.0, and PyTorch 2.11. The prompt has 31 tokens, padded to 64;
Core ML uses cpu_and_gpu.
Timings come from separate sessions on the same Mac and vary with system load.
They exclude text encoding and model loading. The prompt prefix adds 28β33 s
when it needs to be computed, then can be reused from cache. The precision
comparison is one denoising step at t = 1.0; it measures numerical agreement
with fp32. The full six-package download is 14.74 GB, including the timestep
embedding and VAE decoder.
Benchmark records and calculation details on GitHub
GPU vs Neural Engine
The optimization study compared the same two-block FP16 graph with fused attention, 4,096 image tokens, and the same input layout:
| Core ML compute setting | Median time for two blocks | Relative speed |
|---|---|---|
cpu_and_gpu β recommended default |
313.94 ms | 7.01Γ |
cpu_and_ne (CPU + Neural Engine) |
2,201.54 ms | 1.00Γ |
The ratio is 2,201.539 / 313.939 = 7.01Γ, from the ne and sdpa18
two-block measurements in the raw optimization study.
cpu_and_ne allows CPU execution as well as the ANE; the study does not record
per-operation device placement. Full-model ANE timings in that study are
projections. A full-pipeline GPU/ANE comparison has not been measured, and
results on other chips need benchmarking.
Use
Use Python 3.11β3.13:
git clone https://github.com/devin-lai/Qwen-Image-2.1-Coreml.git
cd Qwen-Image-2.1-Coreml
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python download_models.py
python generate.py --compute-units cpu_and_gpu --out neon.png
The example uses prompt embeddings included in the GitHub inference repository. The first run also compiles and loads the models and computes the prompt KV cache, so it takes longer than subsequent runs.
Best mode (default)
Use cpu_and_gpu for the best measured speed on the tested M5 Mac. The
companion CLI and Python API already use it when the compute setting is omitted;
the command above selects it explicitly. For the Python pipeline, pass
compute_units="cpu_and_gpu" to generate().
Compute units are selected when loading a Core ML package. For direct loading
with coremltools, set ct.ComputeUnit.CPU_AND_GPU:
import coremltools as ct
model = ct.models.MLModel(
"models/QwenImage21_Blocks_0of4.mlpackage",
function_name="decode",
compute_units=ct.ComputeUnit.CPU_AND_GPU,
)
This loads the first transformer chunk. The complete inference pipeline coordinates all six packages to generate an image.
For a new prompt, install the
optional text-encoding dependencies and run encode_prompt.py as described in
the GitHub README. The Qwen3-VL text encoder is not included in these packages.
Files
| Package | Purpose | Size |
|---|---|---|
QwenImage21_Embed.mlpackage |
Timestep embedding and modulation | 0.17 GB |
QwenImage21_Blocks_0of4.mlpackage |
Transformer blocks 0β7 | 3.56 GB |
QwenImage21_Blocks_1of4.mlpackage |
Transformer blocks 8β15 | 3.49 GB |
QwenImage21_Blocks_2of4.mlpackage |
Transformer blocks 16β23 | 3.49 GB |
QwenImage21_Blocks_3of4.mlpackage |
Transformer blocks 24β31 | 3.52 GB |
QwenImage21_VAEDecoder_1024x1024.mlpackage |
Latents to RGBA | 0.51 GB |
| Total | 14.74 GB |
Sizes are decimal GB. Each transformer package provides prefix and decode
functions sharing one set of weights. Prefix inference runs once per prompt;
decode inference runs at every denoising step. The denoiser uses the iOS 18 /
macOS 15 target. iOS execution has not been tested here.
The packages occupy 14.74 GB. Allow more disk space for Core ML compilation and dependencies. Minimum memory requirements below the tested 32 GB configuration have not been established.
Git LFS tracks the model programs and weights. SHA256SUMS contains checksums
for every distributed package file and the root license and notice. From the
root of a complete local checkout, verify them with:
shasum -a 256 -c SHA256SUMS
Limitations
Only the fp16 text-to-image packages are included. Other resolutions, longer prompts, image editing, and classifier-free guidance require additional conversion or inference work. Exact numerical output may vary across hardware and runtime versions. Use the reference checks and benchmark scripts in the GitHub repository to evaluate your setup.
License
These weights are derived from Qwen/Qwen-Image-2.1 and are governed by the Qwen Research License Agreement. Use is limited to non-commercial research and evaluation unless you obtain a separate commercial license from the upstream licensor. See Notice for the upstream attribution and changes made during conversion.
The Apache-2.0 license in the inference-code repository does not apply to these weights. This is an independent conversion, not an official Qwen release.
- Downloads last month
- 32
Model tree for devin-lai/Qwen-Image-2.1-Coreml
Base model
Qwen/Qwen-Image-2.1