Changelog / release

0.11.6 — DeepSeek V4 gets its own drafter, and a guard against runaway output

Released 2026-08-02 · full changelog · GitHub releases

Upgrade: pip install -U rapid-mlx  ·  brew upgrade rapid-mlx  ·  or grab the desktop app.

Four DeepSeek V4 changes that compound: the checkpoint's native speculative-decoding heads are finally used, its reasoning is parsed by a parser that understands it, a repeated prompt stops re-prefilling from scratch — and a model that falls into a loop is stopped instead of running until the client gives up.

  • DSpark — DeepSeek V4's checkpoint-native speculative decoding. DeepSeek ships three MTP stages plus low-rank Markov heads inside the V4 Flash 0731 checkpoint; rapid-mlx now drafts and verifies with them instead of ignoring them. Turn it on with --speculative-config '{"method":"dspark","num_speculative_tokens":5}'. Detection is fail-closed: the block geometry is read from the checkpoint's own inference/config.json, and every required tensor is checked against the safetensors index — so a stripped conversion refuses to start rather than decoding wrong. num_speculative_tokens must equal the checkpoint's dspark_block_size (5 on the 0731 checkpoint); a partial block is rejected. On real Codex /v1/responses tool rounds, 2.6–2.9 tokens were accepted per round. One limitation worth knowing before you try it: DSpark reads the checkpoint directory directly, so today it needs a local path — rapid-mlx serve /path/to/DeepSeek-V4-Flash-0731-MXFP4-MLX — not the deepseek-v4-flash-0731-mxfp4 alias, which resolves to a Hugging Face id. See perf flags (PR #1379).
  • A DeepSeek V4 reasoning parser. V4 was being parsed by the generic DeepSeek-R1 parser, which does not understand V4's protocol — so part of the model's internal scratch reasoning was emitted as user-visible content. reasoning_parser: deepseek_v4 now backs all four V4 aliases, wired request-aware through Chat, Anthropic and Responses. An explicit-thinking stream keeps its reasoning in the reasoning channel with no <think> leakage into raw SSE, reasoning or content (PR #1383).
  • Warm TTFT on a repeated prompt: ~24.6 s → 0.318 s. An exact-repeat 8,131-token prompt was still paying almost the full cold cost, because an unusable full-length cache snapshot masked a usable 8,113-token message-boundary one. An exact non-trimmable hit now falls back to the longest usable strict prefix instead of silently full-prefilling. Measured on the real MXFP4 checkpoint, with byte-identical output:
DeepSeek V4 Flash 0731 · MXFP4 · 8,131-token prompt, 124 completion tokensTTFTDecode
Cold25.830 s25.81–26.11 tok/s
Warm — before~24.6 s—
Warm — after0.318 s (81.2× vs cold)25.81–26.11 tok/s
  • The prefix cache survives a restart. Persisted V4 prefixes are reloaded and reused across server restarts, so the warm path above is warm on the first request after a restart rather than the second.
  • A runaway agent no longer generates until the client gives up. A real Codex + DeepSeek V4 Flash session repeated the same investigation sentence for 4,922 tokens over 234 seconds, until the client disconnected — the existing post-completion coherence telemetry can only notice that after the fact, never stop it mid-flight. A token-level guard now checks a bounded suffix every eight decode tokens and stops exact periodic output, exposing rapid_mlx_repetition_loop_stops_total. It is deliberately conservative — at least 72 repeated tokens, and restricted to tool-bearing agent requests, so plain chat is untouched (PR #1377). A follow-up made the copy threshold adaptive to loop length: a long periodic block stops after three copies while a short phrase still needs proportionally more, because a real 61-token paragraph loop was letting 424–464 tokens reach the UI before the guard fired (PR #1378). In 0.11.9 this guard stops reporting success — see above.