--- license: other license_name: qwen-research license_link: LICENSE base_model: Qwen/Qwen-Image-2.1 library_name: mlx pipeline_tag: text-to-image tags: - mlx - mlx-vlm - apple-silicon - quantized - image-to-image - rgba --- # Image21-MLX-8bit **Built with Qwen.** An independent native MLX quantization of Qwen-Image-2.1 for Apple Silicon, by ixim / iximbox. **Non-commercial research and evaluation only** under the original Qwen Research License. This is not an official Qwen release. The complete checkpoint is approximately **18.68 GiB**. DiT attention/MLP and language-encoder attention/MLP linears use **8-bit affine weights, group size 64**, with BF16 activations. The full vision tower, token embeddings, language head, norms and DiT input/output/timestep/modulation layers retain floating-point precision. The VAE retains its original **FP32** weights. See the exact 476 quantized modules in conversion.json. Supports text-to-image, native reference-image editing and RGBA transparency through the included scripts. The wrapper preserves the sampler's alpha channel, which the pinned upstream text-to-image convenience method otherwise slices away. The runtime also enables the upstream fixed-prefix KV cache for text-to-image. Components are loaded and released by phase to reduce unified-memory use. See scripts/mlx_pipeline.py and its retained MIT attribution. Only the **128GB M4 Max** has been tested at 1024px. With phase loading, the six text-to-image cases have nearly the same MLX active-allocation peak: BF16 up to **16.44 GiB**, Q8 up to **16.20 GiB**. Editing peaks at 18.68 vs 16.20 GiB. A separate, cold two-step phase diagnostic found that the unquantized FP32 VAE decoder peaks near **16.19 GiB in both precisions**; unused MLX cache reached about **42 GiB** on the tested 128GB Mac. Cached buffers can be reclaimed and are not a minimum-memory requirement, but the active peak alone cannot certify 32GB or 48GB devices. For planning without device-specific validation, **64GB+ is a conservative budget, not a tested minimum**. Smaller Macs need a complete 1024px trial with system-memory and swap monitoring. See [phase-memory-diagnostic.json](evaluation/phase-memory-diagnostic.json). 2048px and 10-reference editing have not been benchmarked. Allow roughly **50GB free disk space** for ordinary inference; rebuilding also needs the original source and baseline checkpoints. ## Visual findings / 视觉检查 Assistant inspection of all seven paired cases found no obvious severe quality regression in this small sample. English and Chinese text are correct in both precisions; cup count/order and sweater recoloring succeed; real RGBA transparency is retained. The English poster changes visibly in typeface and lamp structure, and the dragon changes expression/details. Other pairs are closer. Both portraits are cropped more tightly than requested, and both transparency samples contain slight near-zero background alpha. This is an unblinded, single-seed visual check, not evidence of lossless quantization or statistical equivalence. ## Download / 下载 On an Apple Silicon Mac with [uv](https://docs.astral.sh/uv/) installed: ```bash uvx --from huggingface-hub==1.33.0 hf download ixim/Image21-MLX-8bit --local-dir Image21-MLX-8bit cd Image21-MLX-8bit ``` ## Reproducible inference ```bash uv venv --python 3.13 .venv uv pip install --python .venv/bin/python -r requirements.lock.txt .venv/bin/python -m scripts.infer --model . \ --prompt 'A natural portrait in soft window light' --output outputs/portrait.png ``` ```bash .venv/bin/python -m scripts.infer --model . --input input.png \ --prompt 'Change only the blue sweater to a red sweater. Preserve the person and background.' \ --source-seed 42 --seed 1000042 --output outputs/edit.png ``` Transparent generation prompt: `This is an RGBA image with transparency. A cute cartoon dragon sticker. The image has alpha channel and the background is transparent.` ## Measurements / 实测 Apple M4 Max, 40 GPU cores, 128 GiB unified memory, macOS 26.6.2, MLX 0.32.2. Both models use the same pinned MLX runtime and internal SSD; 1024×1024, 40 steps, CFG=1, no VAE tiling, one full warm-up per process, seven cases, one seed per case. Sequential component loading is enabled in both models. Per-image time includes component loading, prompt encoding, denoising and VAE decoding; PNG writing is excluded. This is a desktop session with other applications open. BF16 ran before Q8; there were no repeated or interleaved trials to control order and thermal effects. | Case | BF16 seconds | 8-bit seconds | BF16 peak GiB | 8-bit peak GiB | |---|---:|---:|---:|---:| | portrait | 440.91 | 568.86 | 16.41 | 16.19 | | english_text | 464.32 | 566.88 | 16.43 | 16.20 | | chinese_text | 474.14 | 567.43 | 16.44 | 16.20 | | composition | 480.91 | 562.52 | 16.44 | 16.20 | | texture | 487.64 | 445.07 | 16.43 | 16.20 | | rgba | 485.45 | 557.30 | 16.42 | 16.20 | | edit | 606.29 | 665.00 | 18.68 | 16.20 | Six-case text-to-image mean / 六类文生图平均:BF16 **7.87 min**, Q8 **9.08 min**. Q8 generation time relative to BF16 / Q8 相对耗时:**+15.3%** in this run. Peak figures measure MLX allocations, not minimum physical RAM. Full raw records, original RGBA samples and the visual review are in [evaluation](evaluation/report.md). These are informal measurements, not an official benchmark. The BF16 baseline is the same MLX implementation; cross-runtime CUDA equivalence is not claimed. One seed per case is insufficient to establish statistical quality equivalence. There is no claim of lossless quantization or a guaranteed speedup. ![All seven paired samples](evaluation/comparison.png) ## Provenance - Source: `Qwen/Qwen-Image-2.1@b3179ad355be050328e483a9dfdd9e60cd62adfa`. - Runtime: `Blaizzy/mlx-vlm@95b01ccad2d9f65a9e87f6a87bd1c5df69626261`. - Native MLX affine packed weights; not CUDA bitsandbytes INT8, FP8, GGUF or an MFLUX checkpoint. - All three components passed exact tensor round-trip verification. - [conversion.json](conversion.json), [modifications](CHANGES.md), [Notice](Notice), [license](LICENSE), [file hashes](MANIFEST.json). To rebuild, first download the original source snapshot at the revision above to `source-bf16` (requires additional disk space), then run from this repository: ```bash .venv/bin/python -m scripts.audit --source source-bf16 --manifest evaluation/source-files.json .venv/bin/python -m scripts.convert --source source-bf16 --bits 8 --output rebuilt-8bit ``` The audit verifies the original source file hashes before conversion. Rebuilding uses the original floating-point weights, never a dequantized CUDA INT8 checkpoint. To repeat the paired evaluation after the source audit, create a native baseline and run each precision in its own process. This is a lengthy research workflow and needs extra memory and disk space beyond ordinary inference: ```bash .venv/bin/python -m scripts.convert --source source-bf16 --bits 16 --output rebuilt-bf16 .venv/bin/python -m scripts.benchmark --model rebuilt-bf16 --output artifacts/eval/bf16 .venv/bin/python -m scripts.benchmark --model . --output artifacts/eval/8bit --edit-input artifacts/eval/bf16/portrait-s42.png .venv/bin/python -m scripts.report ```