# Maple on mlx-lm Maple is a 20B-A1B ternary MoE with 24 layers, 256 experts, top-8, 512-token sliding window on 3 of every 4 layers. Weights are 2-bit packed `{-α, 0, +α}`, one α per row. ## Setup On an Apple Silicon Mac running macOS 26.2 or later, install [uv](https://docs.astral.sh/uv/) and run: ```sh git clone git@github.com:deepgrove-ai/mlx-lm-deepgrove.git cd mlx-lm-deepgrove ./setup.sh source .venv/bin/activate hf download deepgrove/maple-preview-2bit-mlx --local-dir maple-2bit-mlx ``` `./setup.sh` installs everything needed. No Xcode or manual build is required. ## Run ```sh python -m mlx_lm generate --model ./maple-2bit-mlx --trust-remote-code --flash-head \ --prompt "Write a haiku about a grove." --temp 1.0 --top-p 0.95 --top-k 20 python -m mlx_lm chat --model ./maple-2bit-mlx --trust-remote-code --max-tokens -1 \ --temp 1.0 --top-p 0.95 ``` Enable flash head for extra speed. ```sh python -m mlx_lm chat --model ./maple-2bit-mlx --trust-remote-code --max-tokens -1 \ --temp 1.0 --top-p 0.95 --flash-head ``` | chip | head | decode tok/s | prefill tok/s | peak | | --- | --- | --- | --- | --- | | M4 | exact (default) | 169 | 1075 | 6.51 GB | | M4 | `--flash-head` | **218** | 1075 | 6.69 GB | | M5 Pro | exact (default) | 387 | 3511 | 6.96 GB | | M5 Pro | `--flash-head` | **477** | 3513 | 6.99 GB | M5 Pro: standard setup, 20-core GPU, 48 GB, macOS 26.4, MLX 0.32.0; battery power, default scheduling. 512-token prompt / 256 generated, temp 1.0, top-p 0.95, 512 FlashHead probes; median of 6 runs. Peak measured separately per head, including model loading. M4 results are from the previous version. ## Convert ```sh python -m mlx_lm.ternary /path/to/maple-bf16 -o maple-2bit-mlx --flash-head ``` Streams and converts shard by shard, so the 38 GB bf16 source is never fully resident. - `--flash-head` — ~2 min of k-means, score 4748 vocabulary-cluster centroids, then compute exact logits only for the top 512 clusters (special tokens always scored). Greedy is exact whenever the true argmax is in a probed cluster. Attach to an already-converted directory with `python -m mlx_lm.ternary maple-2bit-mlx --flash-head-only` (rewrites in place; point it at a real directory, not hardlinks). - `--group-scales` — repeat each row's α across every group (+0.6 GB), only for tools that read MLX quantized checkpoints generically. Default stores the row scale once as `row_alpha`; `sanitize()` expands it at load. ## Diff vs upstream mlx-lm | file | what | | --- | --- | | `mlx_lm/models/maple.py` | the model (also copied into every converted checkpoint) | | `mlx_lm/ternary.py` | bf16 → ternary converter + FlashHead generator | | `tests/test_maple_kernels.py` | kernel + precision self-check — `pytest tests/test_maple_kernels.py -v` | | `generate.py`, `chat.py`, `server.py`, `benchmark.py` | support for `--flash-head` flag | | `setup.sh` | uv venv + editable install |