Run a 284B-parameter reasoning model on your own machine.
Connect it to a coding agent that edits code, runs commands, and
builds.
No cloud. No API bills. No privacy leaks.
Most AI coding workflows today ship your code, prompts, and conversation history to a remote API. A local harness flips the model: the LLM runs on your hardware, your agent talks to it over a local HTTP server, and nothing leaves your machine.
Your prompts, your code, your reasoning traces — all processed locally. No data leaves your Mac. No API logs. No training on your conversations.
One hardware purchase. No per-token pricing. No monthly subscription. Run unlimited agent sessions for the cost of electricity.
DeepSeek V4 Flash's MoE architecture activates only ~35B parameters per token. On a Mac Studio or M3 Max you get 26–36 t/s — faster than many hosted APIs.
284B parameters with chain-of-thought thinking. The model reasons before answering, and the thinking length scales with problem complexity — not a fixed overhead.
ds4-server speaks OpenAI and Anthropic wire protocols natively. Pi, Claude Code, and opencode connect with zero adapter code. Tool calling, streaming, reasoning effort — all built in.
Long agent sessions survive server restarts. The KV cache lives on SSD, keyed by token hash. Restart the server and your conversation resumes from the exact checkpoint — no re-prefill.
ds4 (DwarfStar) supports multiple backends: Metal on Apple Silicon, CUDA on NVIDIA (DGX Spark), and ROCm on AMD (Strix Halo). The model requires significant memory to run efficiently.
Primary target. Uses Apple's Metal Shading Language for GPU acceleration. Mac-native, no Docker, no CUDA.
64 GB machines can run q3 quantization (~63 GB) at reduced reasoning quality, or use SSD streaming for q2.
CUDA backend with special care for the DGX Spark (GB10). Runs the full q2 model at 13+ t/s.
make cuda-spark (DGX Spark) or
make cuda-generic
ROCm backend for AMD GPUs — supports the Framework Desktop and other Strix Halo systems with unified RAM design.
git clone https://github.com/antirez/ds4 -b
rocm
From zero to a running agent in about 10 minutes.
Clone the DwarfStar repository and download your chosen quantization. Multiple variants are available — imatrix-tuned quants are recommended for best quality.
# Clone DwarfStar and download your quantization
git clone https://github.com/antirez/ds4.c
cd ds4.c
# q2-imatrix (recommended) — 96/128 GB RAM machines, imatrix-tuned
./download_model.sh q2-imatrix
# q2-q4-imatrix — q2 with last 6 layers boosted to q4 for better quality
./download_model.sh q2-q4-imatrix
# q4-imatrix — for 256 GB+ machines, highest quality
./download_model.sh q4-imatrix
# PRO q2 — for 512 GB machines (DeepSeek V4 PRO)
./download_model.sh pro-q2-imatrix
curl -C - for resume support
and stores files under ./gguf/. The
--tensor-type flag lets you create custom
per-layer boosted quants.
Compile the inference engine for your platform. A single C codebase maps the model via mmap and executes on GPU through Metal Shading Language, CUDA, or ROCm.
# macOS (Metal) — default build, produces ds4 + ds4-server
make
# Linux CUDA — DGX Spark / GB10
make cuda-spark
# Linux CUDA — generic GPU
make cuda-generic
# CPU-only diagnostics build
make cpu
ds4 for interactive chat and
ds4-server for agent integration.
Launch the OpenAI-compatible HTTP server with disk KV persistence and optional SSD streaming. This is the bridge between the model and your agent.
# Standard mode — model fully resident in RAM (128 GB+ machines)
./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192
# SSD streaming mode — for 96 GB machines, experts served from SSD
./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192 --ssd-streaming
--ctx 100000 gives 100k token context.
--kv-disk-dir enables disk-backed KV cache:
checkpoints written to SSD as
<sha1>.kv files, keyed by token hash.
Agent sessions survive server restarts.
--ssd-streaming keeps non-routed weights
resident while serving routed MoE experts from the GGUF
file on cache miss — this lets the q2 model run on 96 GB
machines where it wouldn't otherwise fit.
Add ds4 as a provider in Pi's model registry. This tells Pi where to find your local model and how to talk to it.
{
"providers": {
"ds4": {
"name": "ds4 local",
"baseUrl": "http://127.0.0.1:8000/v1",
"api": "openai-completions",
"apiKey": "dsv4-local",
"compat": {
"supportsStore": false,
"supportsDeveloperRole": false,
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true,
"maxTokensField": "max_tokens",
"supportsStrictMode": false,
"thinkingFormat": "deepseek",
"requiresReasoningContentOnAssistantMessages": true
},
"models": [
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash (ds4 local)",
"reasoning": true,
"thinkingLevelMap": {
"off": null,
"minimal": "low",
"low": "low",
"medium": "medium",
"high": "high",
"xhigh": "xhigh"
},
"input": ["text"],
"contextWindow": 100000,
"maxTokens": 384000,
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
}
}
]
}
}
}
compat block is critical — it tells Pi that
this provider speaks OpenAI-compatible chat completions,
supports reasoning effort (thinking modes), and uses
DeepSeek's native thinking format. The
thinkingLevelMap maps Pi's abstract levels
(off/minimal/low/medium/high/xhigh) to ds4-server's
reasoning_effort values. Setting
cost to zero means Pi won't warn about
token budgets — because local inference is free.
Set ds4 as Pi's default provider and model so every session uses your local harness automatically.
{
"defaultProvider": "ds4",
"defaultModel": "deepseek-v4-flash"
}
pi command —
pi "refactor this module",
pi "explain this bug",
pi "write tests for this" — routes through
your local ds4-server. No cloud dependency. No API key
management. No rate limits.
Run a quick smoke test to confirm Pi can reach your local model and generate a response.
# Smoke test — Pi will print the model name and respond
pi "Hello from the local harness. What model are you running?"
ds4 local and a response, the harness is
working. The first request will include a cold prefill
(the server renders and processes your prompt), but
subsequent requests with overlapping prefixes reuse the
cached KV state — no re-prefill.
Understanding the moving parts helps you tune and debug your setup. Here's what happens under the hood.
Data flows from Pi (your agent) through ds4-server's HTTP API to the Metal GPU. KV checkpoints are persisted to SSD.
ds4-server keeps exactly one mutable GPU graph + KV checkpoint in memory. Concurrent requests queue behind a single worker. This isn't a limitation — it's the design: agent tools call the model sequentially anyway, and the single session means the KV cache is always hot for the active conversation.
When a new session replaces the live one, the old
checkpoint is written to SSD as a .kv file.
The key is a SHA1 of the exact token IDs. On the next
request with the same prefix, the server loads the
cached checkpoint and resumes from the exact token —
logits, attention state, and all.
Routed MoE experts are served from the GGUF file on SSD instead of staying resident in RAM. Non-routed weights, KV cache, and a hot expert cache stay in memory. Cache misses load from SSD at ~6 GB/s — fast enough for tolerable decode. This turns RAM from a hard cutoff into a continuous speed spectrum: 96 GB machines can run the full q2 model.
ds4-server renders OpenAI tool schemas into DeepSeek's
DSML format, and maps generated DSML tool calls back to
OpenAI tool calls. The exact-DSML replay map stores
verbatim sampled text for each tool call ID, so client
JSON history can be re-rendered byte-for-byte. The
server now recovers tool calls started inside unclosed
thinking blocks — the model sometimes opens
a DSML stanza without closing its reasoning first; the
server force-feeds a response marker and
lets the model continue cleanly.
Supports per-layer boosted quants (e.g., IQ2_XXS/Q2_K
everywhere with a few layers upcast to Q4_K via
--tensor-type). The q2-q4-imatrix variant
uses this: last 6 layers at Q4_K for better output
quality. SSD streaming handles non-uniform quant layers
automatically — boosted layers bypass the expert cache
and use the mapped-view path.
Every engine change is validated against official
DeepSeek API logprobs at multiple context sizes. The
test vectors capture greedy continuations with
top_logprobs from the hosted API. Local
--dump-logprobs output must match
token-by-token. Includes long-context story recall
regression and MTP speculative verify correctness tests.
A frank comparison of running DeepSeek V4 Flash locally vs. using hosted APIs.
| Dimension | Local (ds4 + pi) | Cloud API |
|---|---|---|
| Privacy | ✔ Your code never leaves your machine | ✖ Prompts & code uploaded to remote servers |
| Cost | ✔ One-time hardware, $0/token | ✖ Recurring per-token billing |
| Speed | ✔ 26–36 t/s on M3 Max/Ultra | ✔ Fast, but adds latency |
| Context Window | ✔ Up to 1M tokens (configurable) | ✔ Usually 128k–1M |
| Model Quality | ✔ Same 284B frontier model | ✔ Same model (may be newer) |
| Availability | ✔ Always on, no outages | ✖ Rate limits, outages, deprecations |
| Thinking | ✔ Native chain-of-thought, scales with complexity | ✔ Supported (but costs extra) |
| Tool Calling | ✔ Full OpenAI/Anthropic tool format | ✔ Native tool support |
| Setup Effort | ✖ One-time download + config (~10 min) | ✔ Just an API key |
| Hardware Required | ✖ Mac with 128 GB+ RAM | ✔ Nothing — runs on their servers |
The tradeoff is simple: you trade a one-time hardware investment and a 10-minute setup for total privacy, zero recurring cost, and always-available inference. For professional developers who spend all day in an agent, the ROI is immediate.
— The local-first philosophyHere's what a real harness session looks like — from starting the server to having Pi refactor code using your local model.
# ── 1. Start the server (terminal 1) ──
./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192
# ── 2. Configure Pi (done once) ──
# Edit ~/.pi/agent/models.json and settings.json as shown above
# ── 3. Use Pi with your local model (terminal 2) ──
pi "Read the current project structure and suggest a refactor."
# Pi will:
# 1. Read files using its built-in tools
# 2. Send the conversation to ds4-server at http://127.0.0.1:8000
# 3. ds4-server renders the prompt, runs inference on Metal
# 4. Streams the response back with tool call suggestions
# 5. Pi executes the tools (edit files, run commands)
# 6. Sends the results back to the model for the next turn
# All locally, all private, all free.
# ── 4. Check the KV cache (debugging) ──
ls /tmp/ds4-kv/ # See .kv checkpoint files
hexdump -C /tmp/ds4-kv/*.kv | head 20 # Inspect cached prompt text
This is the key insight: the agent (Pi) and the model (ds4) are separate processes communicating over HTTP. Pi doesn't know or care that the model is running locally — it just sees an OpenAI-compatible API. ds4-server doesn't know about Pi's tool system — it just generates tokens and maps tool calls. The harness is the glue between them.
— Loose coupling, local executionTips from running DwarfStar + Pi in production for real agent work.
With 128 GB RAM and q2 quant (~81 GB), you have ~47 GB
left for KV cache. At 1M tokens the compressed cache
uses ~26 GB. Use --ctx 100000 to
--ctx 300000 for a comfortable margin. On
96 GB machines with SSD streaming, limit to
--ctx 32768 to leave room for the expert
cache.
Always use --kv-disk-dir. Agent clients
resend the full conversation every request — without
disk cache, every new session re-prefills from scratch.
The cache directory is disposable: stop the server,
rm -rf /tmp/ds4-kv, restart.
With --ssd-streaming, the server keeps
non-routed weights and a hot expert cache in memory.
Cache misses load from the GGUF file on SSD. For best
performance, place the GGUF on your fastest internal
SSD. The expert cache automatically evicts cold entries
— no manual tuning needed, but larger
--kv-disk-space-mb helps if KV cache
pressure forces evictions.
Start the server with
--trace /tmp/ds4-trace.txt. The trace log
shows rendered prompts, cache decisions, generated text,
and tool-parser events. It's the single best debugging
tool for understanding what's happening under the hood.
Use --tensor-type to create custom
per-layer boosted quants. The
q2-q4-imatrix variant boosts the last 6
layers to Q4_K for better output quality. You can target
any layer range:
./download_model.sh q2-q4-imatrix for the
ready-made variant, or pass
--tensor-type to
quantize_model.sh for custom layer boosts.
Thinking mode produces better results for complex tasks
but uses more tokens. For simple edits, use
/nothink or set
reasoning_effort: "off". For architecture
or debugging, use reasoning_effort: "high".
The model's thinking length adapts to the problem.
Common issues and solutions.
--ssd-streaming to run the q2 model — experts
are served from SSD instead of RAM. If you have 64 GB, use
q3 quantization: ./download_model.sh q3. You
can also reduce --ctx to free up KV cache
memory: ./ds4-server --ctx 32768 ...
--trace /tmp/ds4-trace.txt to see the prefill
phase. After the cold start, ds4-server saves a checkpoint
and subsequent requests reuse it. For interactive work, keep
the server running rather than restarting between sessions.
~/.pi/agent/models.json should have ds4 as a
provider, and ~/.pi/agent/settings.json should
set defaultProvider to "ds4". Run
pi --debug "hello" to see which API endpoint Pi
is hitting. Check that ds4-server is running (curl http://127.0.0.1:8000/v1/models).
--trace /tmp/ds4-trace.txt and look for
cache HIT or cache MISS entries.
Ensure Pi is sending the same prompt format each time.
sudo mdutil -a -i off to disable Spotlight
indexing during inference. For sustained workloads, consider
raising --kv-disk-space-mb to keep more cache
on SSD.
~/.pi/agent/models.json has
"thinkingFormat": "deepseek" and
"requiresReasoningContentOnAssistantMessages":
true
in the compat block. Also run the server with
--trace to see the tool call mapping in action.
Recent versions recover tool calls started inside unclosed
thinking blocks — if the model opens a DSML
stanza mid-reasoning, the server force-feeds a
response marker to let it continue cleanly.
./download_model.sh q2-imatrix (recommended),
q2-q4-imatrix (boosted), q3,
q4, or q5 for higher quality if
you have more RAM. Stop the server, swap the file, restart.
Your Pi config stays the same — just restart ds4-server with
the new model file.
make cuda-spark or
make cuda-generic. For ROCm: clone the rocm
branch —
git clone https://github.com/antirez/ds4 -b rocm. Both backends support SSD streaming, distributed
inference, and MTP speculative decoding. The ROCm backend
uses fused GPU ops for better throughput. See the Hardware
section for detailed requirements.
./ds4 opens an interactive REPL with the model.
Useful for quick experiments and debugging. Run
./ds4 --help to see all flags. For programmatic
access, ./ds4-server exposes an HTTP API —
curl -X POST http://127.0.0.1:8000/v1/chat/completions
-d
'{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"Hello"}],"max_tokens":256}'