Reference · rapid-mlx 0.12.18 · ← Back to README

Performance flags reference

Speculative decoding, long-prompt compression, and KV-cache compression — the rapid-mlx-native performance techniques and the flags that turn them on. Every row below is verifiable against the rapid-mlx serve --help output of the shipped 0.11.3 build.

Feature-detect before you enable. Speculative decoding modes are alias-gated. Run rapid-mlx info <alias> for the per-alias eligibility grid — it tells you which of MTP / DFlash / DDTree / SuffixDecoding actually apply to that model.

MTP · native Multi-Token Prediction heads

For models with built-in MTP heads (Qwen 3.5 / 3.6 native checkpoints per the 0.9.13 blueprint, and DeepSeek V3 / V4). Uses cache snapshot / restore for speculative generation.

FlagDefaultPurpose
--speculative-config '{"method":"mtp",…}' Single JSON knob that drives MTP. Fields: num_speculative_tokens (draft tokens per step) and disable_auto_k. This is the only way to configure MTP.
--force-spec-decode / --no-spec-decode alias-driven Override eligibility gating: force-enable spec decode on an alias the grid would skip, or force-disable it entirely.
$ rapid-mlx serve qwen3.6-35b-8bit \
    --speculative-config '{"method":"mtp","num_speculative_tokens":3,"disable_auto_k":false}' --force-spec-decode

Empirical: 0.9.13 gemma-4-12b-it MTP shipped +14.4% structured throughput with 5/5 determinism gates PASS. K histogram was balanced across the tested prompt classes — see specdecoding.md for the latest MTP validation memo (2026-07-06: Gemma 4 assistant-sidecar MTP is not supported after greedy-lossless correctness failed on 3 of 4 prompts).

DSpark · DeepSeek V4's checkpoint-native drafter

DeepSeek ships the drafter inside the V4 Flash 0731 checkpoint — three MTP stages plus low-rank Markov heads. There is no sidecar to download and no separate draft model to configure: if you have the checkpoint, you have the drafter. Added in 0.11.6.

FlagDefaultPurpose
--speculative-config '{"method":"dspark",…}' Single JSON knob that drives DSpark. Field: num_speculative_tokens, which must equal the checkpoint's dspark_block_size — 5 on the 0731 checkpoint. A partial block is refused at boot.
# Point serve at the local checkpoint directory, not the alias — see below.
$ rapid-mlx serve /path/to/DeepSeek-V4-Flash-0731-MXFP4-MLX \
    --speculative-config '{"method":"dspark","num_speculative_tokens":5}' --port 8000
It needs a local path, not an alias. DSpark reads the checkpoint directory directly — its block geometry comes from the checkpoint's own inference/config.json. The deepseek-v4-flash-0731-mxfp4 alias resolves to a Hugging Face repository id, which is not a directory on disk, so serving the alias with "method":"dspark" exits with a detection error. Serve the downloaded snapshot path instead. The published MXFP4 conversion does carry the full DSpark payload — the three mtp.* stages, both Markov heads and inference/config.json — so no re-download is needed, only a path.

Detection is fail-closed. The geometry (n_mtp_layers, dspark_block_size, dspark_target_layer_ids, dspark_markov_rank) is read from the checkpoint, and every required tensor is verified against model.safetensors.index.json — so a conversion that stripped the MTP weights refuses to start rather than quietly decoding without a drafter. Observed acceptance on real Codex /v1/responses tool rounds during development: 2.6–2.9 accepted tokens per round.

DFlash · block-diffusion drafter

Block-diffusion speculative drafter, built on the block-diffusion language-modelling line of work — Arriola et al., "Block Diffusion: Interpolating Between Autoregressive and Diffusion Language Models" (arXiv 2503.09573, ICLR 2025). Single-user serial mode. Requires a DFlash-eligible alias — check with rapid-mlx info <alias>.

Measured effect: 1.4× pooled on qwen3.5-27b-8bit, verified lossless. An earlier 3.5× figure came from a broken bench and was retracted. You may also find a 2.6–3.2× community result on qwen3.6-35b-a3b-8bit (issue #472) — that was a single run, and it is not reachable today: the alias is MoE, and MoE models do not pass the eligibility gates below.

FlagDefaultPurpose
--speculative-config '{"method":"dflash"}' Single JSON knob that drives DFlash. Still requires the pip install 'rapid-mlx[dflash]' extra; the per-alias drafter path resolves through vllm_mlx.spec_decode.dflash.drafter_registry.
--force-spec-decode / --no-spec-decode alias-driven Override eligibility gating: force-enable spec decode on an alias the grid would skip, or force-disable it entirely.

Eligibility gates surfaced by rapid-mlx info: declared support, non-MoE, precision ≥ 8-bit, drafter declared, mlx-vlm 0.5.0+ present. The 0.11.3 rapid-mlx info qwen3.5-27b-8bit shows DFlash-eligible; the same output for gemma-4-12b-4bit shows ineligible (4-bit precision + no declared drafter).

DDTree · draft tree verification (experimental)

DFlash draft-tree verification, single-user serial mode. Requires a DDTree-eligible alias and the external dtree-mlx runtime.

FlagDefaultPurpose
--speculative-config '{"method":"ddtree"}' Single JSON knob that drives experimental DDTree. Fails loud if the alias isn't declared eligible or if dtree-mlx isn't importable.
--force-spec-decode / --no-spec-decode alias-driven Override eligibility gating: force-enable spec decode on an alias the grid would skip, or force-disable it entirely.

SuffixDecoding · drafter-free statistical drafts

Model-free speculative decoding using suffix trees built from past outputs (NeurIPS 2025 Spotlight, arXiv 2411.04975). Explicit opt-in — useful for long high-overlap workloads (prompt-copy, code editing, repeated tool XML) on validated aliases; local benches showed regressions on gpt-oss / Qwen families under mixed chat traffic. Auto-disabled on hybrid models (Qwen 3.5 / 3.6 A3B / A10B, Granite 4, Mamba / Jamba / RWKV).

FlagDefaultPurpose
--speculative-config '{"method":"suffix",…}' Single JSON knob that drives SuffixDecoding. Field: num_speculative_tokens (max draft tokens per verify step; verify forward cost grows linearly with this). This is the only way to configure suffix decoding.
--force-spec-decode / --no-spec-decode alias-driven Override eligibility gating: force-enable spec decode on an alias the grid would skip, or force-disable it entirely.
$ rapid-mlx serve gemma-4-12b-4bit \
    --speculative-config '{"method":"suffix","num_speculative_tokens":8}' --force-spec-decode

Per-alias suffix tier is surfaced by rapid-mlx info <alias> (values: validated, rejected, unknown). "Unknown" means the bench scripts/bench_suffix_decoding.py hasn't been run for the alias yet — it's safe to try but not guaranteed.

PFlash · long-prompt prefill compression

Scores 32K+ prompts and only prefills the sink + recent tail + query-relevant middle blocks. Default-on for verified Qwen 3.5 / 3.6 aliases (per PR #287), off elsewhere. Bench-validated profile (PR #649): TTFT 3.87×–8.5× faster, needle-in-haystack recall 5/5 across tested cells. Read that recall figure for what it is — five trials with zero failures, which bounds the failure rate only loosely (95% upper bound ≈ 45%). It is evidence that PFlash is not grossly lossy, not evidence that retrieval is safe on your workload. PFlash discards ~80% of middle-prompt tokens, so if exact mid-document recall matters to you, benchmark it before relying on it — or set --pflash off.

FlagDefaultPurpose
--pflash {off,auto,always} always on verified aliases, off elsewhere Master switch. auto respects the threshold; always compresses every prompt over the threshold.
--pflash-threshold N 32768 Minimum prompt tokens before auto compresses.
--pflash-keep-ratio F 0.20 Fraction of prompt tokens to keep when compressing. Matches the bench-validated profile.
--pflash-min-keep-tokens N 2048 Minimum tokens to keep when compressing.
--pflash-sink-tokens N 256 Leading prompt tokens always kept.
--pflash-tail-tokens N 2048 Trailing prompt tokens always kept.
--pflash-block-size N 128 Middle-token scoring block size.
--pflash-query-window N 512 Trailing query window used to score middle blocks.
--pflash-stride-blocks N 8 Keep every Nth middle block as an anchor during scoring (0 disables anchors).
--pflash-include-tools off Allow PFlash compression on prompts with tool definitions. By default tool prompts are skipped for tool-call reliability.

TurboQuant · KV-cache compression

Post-quantization KV-cache compression. v4 is V-only 3–4 bit Lloyd-Max with K in FP16; k8v4 is the R15 Phase 4 mix — K at 8-bit Walsh-Hadamard + V at 4-bit Lloyd-Max (~4.6× KV compression on dense models, ~1/2.4 = ~58% savings on the shipped MoE cells). k8v4 is default-on for 9 verified Qwen 3.5 / 3.6 MoE aliases per the 0.9 changelog.

FlagDefaultPurpose
--kv-cache-turboquant {v4,k8v4,none} alias-driven (k8v4 on 9 verified Qwen 3.5 / 3.6 MoE) Master switch. none is the explicit off-switch.
--kv-cache-turboquant-bits {3,4} auto (3 for head_dim≥96, 4 for head_dim=64) V-side bit width. Ignored on k8v4 (V pinned to 4-bit).
--kv-cache-turboquant-group-size N 32 Group size for V-side quantization.

Prompt & response caching

Two opt-in caches added in 0.10.12, both default-OFF and byte-for-byte inert until you pass their flag. The response cache short-circuits a completely repeated greedy request and decodes nothing; trim-free prefix reuse keeps a stable prefix warm for hybrid / sliding-window models so a new suffix each turn skips re-prefilling the prefix. These two rows are verified against the rapid-mlx serve --help of the 0.10.12 build.

Separately, the prefix cache is on by default and is what makes a repeated prompt cheap. Its measured effect scales with prompt length, so there is no single multiplier: a short prompt saves little, while an exact-repeat 8,131-token DeepSeek V4 prompt went from ~24.6 s to 0.318 s (81.2× vs cold) with byte-identical output in 0.11.6. That number is one prompt on one machine — see the changelog for the conditions. Cross-family cached-TTFT gains against upstream mlx-lm are much smaller, typically 1.2×–2.1×.

FlagDefaultPurpose
--response-cache-entries N 0 (off) Retain up to N fully-computed greedy (temperature 0 / top_k 1) chat completions; a completely repeated request returns the stored completion verbatim with zero GPU decode. Sampled requests are never short-circuited. Distinct from and complementary to the prefix / KV cache.
--hybrid-cache-entries N 0 (off) Retain up to N non-trimmable prefix-cache entries for prefix-extension reuse (stable prefix + a new suffix each turn). Covers both hybrid recurrent-state (GatedDeltaNet / Mamba) and sliding-window (Gemma 4, GPT-OSS) models. Best for stable-system-prompt / long-context agent workloads.

Eligibility check

rapid-mlx info <alias> is the source of truth for what applies to a given model. Example output for gemma-4-12b-4bit in the shipped 0.11.3 build:

$ rapid-mlx info gemma-4-12b-4bit
  Alias: gemma-4-12b-4bit → mlx-community/gemma-4-12B-it-4bit

┌──────────────────────────────────────────────────────────────┐
│ Model: mlx-community/gemma-4-12B-it-4bit                     │
│ Tool format      : gemma4                                    │
│ Reasoning parser : gemma4                                    │
│ Architecture     : pure attention                            │
│ Spec decode      : ✓ supported                               │
│ Suffix tier      : unknown — run scripts/bench_suffix_decod… │
└──────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────┐
│ DFlash eligibility: ✗ ineligible                             │
│ Declared support  : ✗ no                                     │
│ Not MoE           : ✓ yes (dense)                            │
│ Precision ≥8-bit  : ✗ no (4-bit/mxfp4/nvfp4)                 │
│ Drafter declared  : ✗ no (dflash_draft_model unset)          │
└──────────────────────────────────────────────────────────────┘

See also