DeepSeek V4-Flash on Apple Silicon
DeepSeek's V4 family — Channel-Sparse Attention (CSA) plus
Hierarchical-Cluster Attention (HCA) — at 2-bit, makes the
previously server-only V-family architecture run on a single
256 GB M3 Ultra workstation. rapid-mlx shipped day-0 support
(PR #168) and the dedicated deepseek tool parser.
pip install rapid-mlx && rapid-mlx serve deepseek-v4-flash-2bit
runs V4-Flash at 2-bit on a 256 GB M3 Ultra Mac Studio.
4-bit and 8-bit variants are wired for larger memory tiers.
Headline tok/s: TODO — bench pending on M3 Ultra.
Why V4-Flash matters
The V4 family is DeepSeek's first generation built around CSA + HCA sparse attention — instead of full O(n²) attention, each query head attends only to a learned subset of channels (CSA) grouped into hierarchical clusters (HCA). The result is a model that scales context length without the usual quadratic KV blow-up and serves at meaningfully higher throughput than a dense V3 of comparable parameter count. V4-Flash is the smaller member of the family, sized to fit the unified-memory envelope of a workstation Mac rather than a datacenter rack.
Engineering notes — what we shipped
-
PR #168 (41686016) —
feat: day-0 DeepSeek-V4-Flash support (vendored from mlx-lm #1192). We vendored the CSA / HCA kernels off the upstream mlx-lm PR before it merged, so V4-Flash worked on rapid-mlx the day the weights dropped on Hugging Face. -
PR #297 (cf71deec) —
feat(guardrail): warn at load time on MoE+MXFP4+multi-device cliff (mlx#3402). Bug: MoE models in MXFP4 quant silently corrupt when sharded across multiple MLX devices, per mlx#3402. Fix: we don't fix the upstream bug, but we surface it loudly at boot so a user trying that configuration hits a clear warning instead of garbled tokens. V4-Flash 4bit and 8bit are unaffected — this is a guardrail for the wider MoE-MXFP4 surface. -
PR #874 (eacc7e48) —
fix(tool-parser): add deepseek_v3 variant for R1-0528 family. Upstream parser story split when DeepSeek shipped the R1-0528 refresh — we kept a cleandeepseekparser for V4 and a versioneddeepseek_v3for the older lineage, and added a guardrail (PR #887) so the V3 parser doesn't accidentally bind to a non-V3 Qwen2 distill. -
PR #893 / #903 (f3d02be7) —
fix(model_auto_config): align V4/V5 routing with classifier. The auto-classifier was occasionally routing a V4-Flash checkpoint to V5 defaults, breaking the rope-scaling config. Fixed and regression-tested. - PR #409 (243e5083) — review hardening on the V4-Flash JANGTQ tokenizer path so the BPE merges load cleanly when the safetensors and tokenizer arrive in non-canonical order from HF.
Upstream status
Upstream mlx-lm support landed in
mlx-lm #1192
but you'd still need to wire the tokenizer + tool parser yourself
to serve V4 over an OpenAI-compatible API. rapid-mlx ships all of
that in the alias config.
MoE + MXFP4 + multi-device caveat (mlx#3402). If you go for an MXFP4 quant on a multi-Mac setup, rapid-mlx will print a warning at boot. V4-Flash at 2/4/8-bit is not affected because those quants don't trigger the MXFP4 path.
Pick your quant
| Alias | Bits | Approx. disk | Unified-memory floor | HF repo |
|---|---|---|---|---|
deepseek-v4-flash-2bit |
2 (DQ) | ~110 GB | 192 GB (256 GB comfortable) | DeepSeek-V4-Flash-2bit-DQ |
deepseek-v4-flash-4bit |
4 | ~210 GB | 256 GB Mac Studio | DeepSeek-V4-Flash-4bit |
deepseek-v4-flash-8bit |
8 | ~390 GB | Cluster — exceeds single-Mac envelope | DeepSeek-V4-Flash-8bit |
The 2-bit DQ build is the headline result — it's the smallest
quant the team is comfortable putting next to the
DeepSeek name without quality regressions on the
published evals. If you have a 256 GB Mac Studio, start here.
Recommended settings
V4-Flash inherits the DeepSeek-R1 reasoning lineage. The alias
ships with the deepseek tool parser and the
deepseek_r1 reasoning parser, so
/v1/responses exposes a structured
reasoning_content field. Sampling defaults to
temperature=0.6, top_p=0.95 per the
model card.
rapid-mlx serve deepseek-v4-flash-2bit \
--port 8000 \
--host 127.0.0.1
Tutorial — chat + tool call
curl http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "deepseek-v4-flash-2bit",
"messages": [{"role": "user", "content": "What is the weather in Tokyo?"}],
"tools": [
{"type": "function", "function": {
"name": "get_weather",
"description": "Look up current weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}}
]
}'
Python via the OpenAI client, using the reasoning surface:
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="none")
resp = client.responses.create(
model="deepseek-v4-flash-2bit",
input="Plan a three-step approach to optimizing a slow SQL query.",
reasoning={"effort": "high"},
)
print(resp.output_text)
for item in resp.output:
if item.type == "reasoning":
for chunk in item.summary:
print("[reasoning]", chunk.text)
Performance
TODO — M3 Ultra 256 GB headline decode tok/s and TTFT pending. We'll publish 2-bit-DQ, 4-bit, and a 64K-context curve with the next release.
Known limitations
- 2-bit DQ is the right starting point on a 256 GB Mac Studio, but the model is still big — leave room for system memory or you'll page. Don't run another LLM next to it.
- Sparse attention pays off most at long context. At 1-2K prompt + short decode you won't see the throughput edge over a comparably-sized dense model.
- 8-bit is listed for completeness — it won't fit a single Mac. Multi-device sharding is possible but you'll hit the mlx#3402 guardrail if you also use an MXFP4 dependency.