Instructions to use KaedeTai/dflash2-mlx-quantized-draft with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use KaedeTai/dflash2-mlx-quantized-draft with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir dflash2-mlx-quantized-draft KaedeTai/dflash2-mlx-quantized-draft
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
| license: mit | |
| library_name: mlx | |
| tags: | |
| - mlx | |
| - speculative-decoding | |
| - dflash2 | |
| - apple-silicon | |
| - quantization | |
| - benchmark | |
| base_model: | |
| - Qwen/Qwen3.8-27B | |
| # DFlash2 on Apple Silicon β quantized-draft loader + M5 Max measurements | |
| Two things this repo provides, neither of which is model weights: | |
| 1. **`load_draft_q4.py`** β a drop-in loader that lets the | |
| [`cfontes/qwen3.8-27b-mlx-dflash2`](https://huggingface.co/cfontes/qwen3.8-27b-mlx-dflash2) | |
| server and benchmarks use a **quantized** DFlash2 drafter. The upstream loader builds a | |
| bf16 skeleton and calls `load_weights` directly, so a 4-bit draft fails on shape | |
| mismatch. | |
| 2. **`config.json`** β the draft config that | |
| [`ProCreations/Qwen3.8-27B-DFlash2-MLXFast-Q4`](https://huggingface.co/ProCreations/Qwen3.8-27B-DFlash2-MLXFast-Q4) | |
| ships without. That repo contains only `model.safetensors`, so no standard loader can | |
| instantiate it. | |
| Plus the measurements that motivated both. | |
| ## Headline: quantizing the *drafter* is close to free throughput | |
| Apple **M5 Max**, 128 GB, macOS 26.4.1, MLX 0.32.0 / mlx-lm 0.31.3. Target: | |
| `tozp/Qwen3.8-27B-OBLITERATED-V2-mlx-4bit`. Greedy, 300 tokens, K=4, interleaved A/B with a | |
| 90 s cooldown before each measurement, two rounds. | |
| | drafter | size | tok/s | accept | | |
| |---|---:|---:|---:| | |
| | `z-lab/Qwen3.8-27B-DFlash2` (bf16) | 3.85 GB | 59.8 / 60.3 | 87.9% | | |
| | `ProCreations/...-MLXFast-Q4` (affine-4 g64) | **1.27 GB** | **76.1 / 76.0** | 86.9% | | |
| | | β2.6 GB | **+26%** | β1.0 pp | | |
| The drafter runs a forward pass every block, so shrinking it by 2.6 GB removes real | |
| bandwidth from the hot loop. The prediction quality it costs β one point of acceptance β is | |
| nowhere near enough to offset that. | |
| Stacked against no speculation at all, on the same target and machine: | |
| | configuration | tok/s | vs dense | | |
| |---|---:|---:| | |
| | dense (`mlx_lm.stream_generate`) | 33.3 | 1.00Γ | | |
| | + bf16 drafter | 61.4 | 1.84Γ | | |
| | **+ Q4 drafter** | **76.1** | **2.29Γ** | | |
| A 27B **dense** model at 76 tok/s in **16.1 GB resident** (measured RSS with the server | |
| loaded and generating; 14 GB target + 1.2 GB drafter on disk, plus KV cache β it grows | |
| with context). | |
| ## Target-model comparison (same protocol) | |
| | target | dense | DFlash2 (bf16 draft) | speedup | accept | greedy token-exact vs dense | | |
| |---|---:|---:|---:|---:|---| | |
| | `mlx-community/Qwen3.8-27B-mxfp4` | 35.4 | 54.0 | 1.52Γ | 82% | yes | | |
| | Qwen3.8-27B abliterated w/ [Heretic](https://github.com/p-e-w/heretic) | 33.3 | 62.2 | 1.87Γ | 89% | one near-tie flip | | |
| | `tozp/...-OBLITERATED-V2` | 33.3 | 61.4 | 1.84Γ | 88% | yes | | |
| Round-to-round spread under 2% on every cell. | |
| **The drafter transfers across quantization schemes and weight surgery.** It is trained | |
| against the stock model; both alternatives are abliterated by unrelated methods (Optuna | |
| search vs SVD+LEACE blend) *and* quantized differently (affine-4 g64 vs mxfp4 g32). | |
| Acceptance went **up** 6β7 points rather than down. Two independent methods landing in the | |
| same place suggests the cause is removing refusal directions as such β plausibly lower | |
| next-token entropy, which is testable and untested here. | |
| ## Measurement traps on this hardware | |
| - **Thermal drift.** Running targets back-to-back without cooldowns, the same mxfp4 | |
| measurement read 34.9 t/s at the start and 26.8 t/s three minutes later β **β23%**, enough | |
| to invert a model-vs-model conclusion. Interleaving with 90 s cooldowns took spread from | |
| 23% to under 2%. | |
| - **Cold start.** The first model load of a session measures far below steady state; one run | |
| produced `dense 1.9 t/s / speedup 18.00x`. Warm up before timing. | |
| - **`ioreg` "Device Utilization %" is useless here** β it reads 100% at rest. Check GPU | |
| memory in use and whether other engines hold models instead. A 37 GB workload on the GPU | |
| went undetected this way and produced a full set of wrong numbers. | |
| ## Usage | |
| ```bash | |
| git clone https://huggingface.co/cfontes/qwen3.8-27b-mlx-dflash2 dflash2 | |
| cd dflash2 | |
| hf download ProCreations/Qwen3.8-27B-DFlash2-MLXFast-Q4 --local-dir models/draft-q4 | |
| cp /path/to/this/repo/config.json models/draft-q4/config.json | |
| cp /path/to/this/repo/load_draft_q4.py bench/extra/load_draft_q4.py | |
| # point the server at the quantized draft | |
| python dflash2_mlx_server/server.py --main-dir models/<target> --draft-dir models/draft-q4 | |
| ``` | |
| `server.py` calls `dflash_port.local_load.load_draft_from_dir`; swap that import for | |
| `load_draft_any` from `load_draft_q4.py`. The loader detects a `quantization` block and | |
| falls back to the original function when there isn't one, so bf16 drafts keep working. | |
| Verified end-to-end: server loads in 0.9 s and reports `accept_rate 0.917, tok_per_s 75.4`. | |
| ## How the loader works | |
| `nn.quantize` is applied to the draft skeleton **before** `load_weights`, with a predicate | |
| that quantizes exactly the modules that have a `.scales` entry in the weight file β the same | |
| test `mlx_lm` uses. It also normalizes the candidate-selector codebook keys, which the two | |
| published drafts spell differently (`candidate_selector.predecessor_codebook` vs | |
| `...codebook.weight`); the upstream rename raises `KeyError` on the Q4 layout. | |
| ## Credits | |
| - [z-lab](https://huggingface.co/z-lab/Qwen3.8-27B-DFlash2) β the DFlash2 drafter | |
| - [cfontes](https://huggingface.co/cfontes/qwen3.8-27b-mlx-dflash2) β the MLX port and server this patches (MIT) | |
| - [ProCreations](https://huggingface.co/ProCreations/Qwen3.8-27B-DFlash2-MLXFast-Q4) β the affine-4 quantization measured here | |
| - [tozp](https://huggingface.co/tozp/Qwen3.8-27B-OBLITERATED-V2-mlx-4bit) and [Heretic](https://github.com/p-e-w/heretic) β the abliterated targets | |
| No model weights are redistributed here. `config.json` is derived from z-lab's draft config | |
| with a quantization block added. | |