一个窄到极致的 DeepSeek V4 Flash 本地推理引擎
ds4.c 的核心价值不在于“又一个 LLM runtime”,而在于它故意不做通用框架:只押一个模型、一个权重布局、一个 Metal 快路径、一套面向本地长上下文 agent 的 KV 复用策略。读完后,我更愿意把它理解成“模型专用系统工程样板”,而不是 llama.cpp 或 vLLM 的替代品。
一页结论
ds4.c 是 antirez 为 DeepSeek V4 Flash 写的本地推理引擎。它的设计不是横向兼容更多模型,而是纵向打穿一个具体模型:GGUF 加载、固定 tensor layout、Metal graph、tokenizer/chat rendering、KV session、OpenAI/Anthropic API、工具调用、长上下文 cache 和官方向量验证都在一个小型 C/Objective-C/Metal 代码库里闭环。
它是一种“窄模型专用 runtime”路线
项目明确拒绝成为通用 GGUF runner。好处是能为 DeepSeek V4 Flash 的压缩 KV、MoE、thinking 模式、DSML 工具调用和 Metal 图执行做非常专门的工程决策;代价是可移植性、模型覆盖和长期维护都绑定在这个模型族上。
KV cache 被当成磁盘公民
本地 agent 客户端经常每轮重发完整上下文。ds4-server 用一个 live Metal session 处理当前会话,再把可复用前缀写成磁盘 checkpoint。换会话、重启或长 prompt 追加时,服务器可以从磁盘恢复前缀,不必从 token zero 重新 prefill。
项目主张:为什么不是通用框架
README 的反复强调点可以压缩成三句话:只做 DeepSeek V4 Flash;权重、runtime 和 agent 验证一起设计;本地长上下文必须把磁盘纳入 KV cache 策略。
项目认为本地推理生态经常追逐新模型,导致每个模型只是“能跑”。ds4 选择用官方 logits/vector、长上下文测试和 agent 集成来证明一个模型真的能用。
起点是 128GB 内存的 MacBook/Mac Studio,不追求低端设备,也不追求数据中心吞吐。q2 权重约 81GB,q4 约 153GB。
作者的理想组合是:专用推理引擎、专门制作的 GGUF、面向 coding agent 的验证和 API glue。ds4 不想只交付一个“模型能加载”的二进制。
为什么 DeepSeek V4 Flash 被单独服务
作者给出的理由包括:激活参数更少,thinking 输出更短且与问题复杂度相关,模型有 1M token 上下文,284B 级别知识容量带来更强边缘知识表现,英语和意大利语生成质量好,KV cache 压缩程度高,并且特定 2-bit 量化在 coding agent 和工具调用下仍可用。
架构:一条从 GGUF 到 HTTP 的垂直路径
代码布局很直接:ds4.c 拥有模型加载、tokenizer、CPU reference、Metal graph scheduling、session 和磁盘 payload;ds4_server.c 拥有 HTTP、OpenAI/Anthropic 兼容、工具映射、worker queue 和磁盘 KV 策略;ds4_metal.m 与 metal/*.metal 是 Metal runtime 和内核。
源码里写死了 DS4 的关键维度:43 层、4096 hidden、129280 vocab、64 attention heads、1 KV head、512 head dim、256 routed experts、每 token 选择 6 个 experts、128 raw sliding window、indexer top-k 512。这让后续执行路径可以少做抽象,但也使 arbitrary GGUF 直接不成立。
生产路径是 whole-model Metal graph。CPU 后端保留为 reference/debug,用来验证 attention、KV、logits 漂移;README 明确警告不要把 CPU path 当生产目标。
关键源文件阅读
磁盘 KV Cache:项目最有辨识度的系统设计
ds4-server 的前提是:本地 coding agent 每轮通常重发完整消息历史,长上下文首轮 prefill 昂贵;而 DeepSeek V4 Flash 的 KV 压缩程度高,现代 Mac SSD 又快,所以 KV checkpoint 不必只活在内存里。
只有一个 live Metal session,适合当前活跃会话继续延伸。
不同会话切换、服务重启、旧前缀恢复时,从 .kv 文件恢复 DS4 session payload。
使用精确 token IDs 的 SHA1,而不是 raw text。token 以 little-endian u32 进入 hash。
| 机制 | 说明 | 设计动机 |
|---|---|---|
| cold | 长首 prompt 到达稳定前缀时保存。 | 避免后续追加文本时从头预填充。 |
| continued | 活跃会话增长超过配置间隔时保存。 | 长 agent 会话中途也能复用。 |
| evict | 一个无关请求替换 live session 前保存当前状态。 | 内存只有一个 session,不能默默丢掉旧会话。 |
| shutdown | 服务正常退出时保存。 | 重启后恢复最后一个可用前缀。 |
KVC 文件里有什么
server 负责外层 KVC header、可读渲染文本、hit count、quant bits、context size、save reason 和可选工具映射;engine 负责 DS4-specific payload。payload 不是通用 graph dump,而是为了让“下一 token 分布”与刚刚 prefill 到该前缀的 session 一致。
KVC header
rendered token text for inspection
DS4 session payload:
checkpoint token IDs
next-token logits
per-layer compressed row counts
raw sliding-window KV rows
compressed attention rows
compressor/indexer frontier tensors
optional tool-id -> exact DSML map
一个很细的工程点是 cold save 会默认剪掉 32 个尾部 token,并向下对齐到 2048 token chunk。原因是 BPE 可能在追加文本时跨边界合并 token;对齐到 prefill chunk 也能让 compressor row finalization 更接近冷启动完整 prefill。
模型、量化与性能数字
ds4 只支持项目发布的 DeepSeek V4 Flash GGUF,不支持任意 DeepSeek 或任意 GGUF。权重下载脚本把默认软链 ds4flash.gguf 指向选择的 q2/q4 模型。
| 目标 | 大小/机器 | 说明 |
|---|---|---|
| q2 | 约 81GB,128GB RAM 机器 | 2-bit routed experts。只量化 routed MoE experts,up/gate 用 IQ2_XXS,down 用 Q2_K;shared experts、projections、routing 等保留更高精度。 |
| q4 | 约 153GB,256GB+ RAM 机器 | 更高内存版本,README 给出 Mac Studio M3 Ultra q4 的 short/long 性能。 |
| MTP | 约 3.5GB,可选 | speculative decoding 试验组件,需要显式 --mtp,当前只应期待轻微加速。 |
README 性能快照
作者给出的是单次 Metal CLI 测试,参数为 --ctx 32768、--nothink、greedy、生成 256 tokens。M3 Max 128GB q2 short 约 58.52 t/s prefill、26.68 t/s generation;M3 Ultra 512GB q2 long prompt prefill 约 468.03 t/s、generation 约 27.39 t/s;M3 Ultra q4 long prompt prefill 约 448.82 t/s、generation 约 26.62 t/s。
CLI 与 Server:为本地 agent 服务
真实多轮 REPL
./ds4 进入交互模式。REPL 维护渲染后的 chat transcript 和 live Metal KV checkpoint,因此多轮对话是继续同一条 session 时间线,而不是每轮重跑。可用命令包括 /think、/think-max、/nothink、/ctx N、/read FILE。
OpenAI + Anthropic 兼容
ds4-server 提供 /v1/chat/completions、/v1/completions、/v1/messages、模型列表 endpoint,支持 SSE streaming、工具 schema、tool_choice、reasoning/thinking 控制和 usage streaming。
服务器并发模型
HTTP 解析和 socket 在 client 线程中做;推理通过一个 Metal worker 串行执行。当前不做多个独立请求 batching。这个设计牺牲吞吐型并发,但保证 graph/KV mutation 集中在一个地方,便于 session reuse、磁盘 checkpoint 和未来 batching 决策。
./download_model.sh q2
make
./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192
作者特别强调 Claude Code 风格客户端的初始 prompt 可能很大,磁盘 KV 对这种“重发完整历史”的本地 agent 很重要。/v1/messages 也是为了 Anthropic-compatible 客户端准备的。
测试与正确性:小仓库里的严肃部分
ds4 的质量策略是先防止模型语义漂移,再考虑性能。项目包含官方 DeepSeek V4 Flash API 抓取的 continuation/top-logprobs vectors,本地用 --dump-logprobs 生成结果并比较 token bytes 和 top-logprob slice。
tests/test-vectors 保存 short/long prompt、official JSON 和紧凑 C fixture。
C runner 覆盖 server API、工具 checkpoint、KV cache boundary、eviction 等行为。
--dump-tokens、--dump-logprobs、--trace 分别定位 tokenizer、logit 和 agent session 问题。
我在本机对当前 clone 执行了 make,ds4 和 ds4-server 编译通过。由于未下载大模型权重,没有运行真实推理或官方向量测试。
限制与风险
| 限制 | 具体表现 | 影响 |
|---|---|---|
| 模型特化 | 只支持项目给出的 DS4 GGUF layout。 | 不能当通用本地模型运行器。 |
| Metal-only | 生产路径只支持 Apple Metal;CUDA 只是未来可能性。 | 非 Mac 高端机器无法获得目标体验。 |
| 单 worker | 多个请求并发时排队,当前不 batching。 | 不适合多租户高吞吐 serving。 |
| 内存门槛 | q2 约 81GB 权重,完整 1M context 额外内存也很大。 | 128GB 机器要谨慎设置 100k~300k context。 |
| alpha 质量 | README 明说还没达到“finished end to end”。 | 适合实验和高水平用户,不适合无监控直接托管关键业务。 |
| CPU 路径风险 | README 警告大 CPU inference 在当前 macOS VM 下可能触发内核问题。 | 不要用 CPU backend 跑大模型推理。 |
| MTP 仍实验 | 正确性门控,速度收益目前有限。 | 不要把 speculative decoding 当主要性能依赖。 |
实践建议
- 有 128GB 或 256GB+ Apple Silicon 机器。
- 目标是本地 coding agent、长上下文、隐私或离线工作流。
- 愿意接受单模型专用 runtime,并能读 C/Metal 日志排障。
- 关心磁盘 KV 对长 agent 会话的实际收益。
- 需要服务多种模型或随时切模型。
- 需要 Linux/CUDA 生产部署。
- 需要高并发 batching、多用户隔离和成熟运维控制面。
- 没有足够 RAM/SSD 或不想管理超大 GGUF 权重。
如果要试跑,我会这样做
先从 q2 开始,context 不要直接拉满 1M,而是选择 100k 或 200k,开启 --kv-disk-dir 和足够磁盘预算;用自己的 agent 工作流反复重启/切换 session,观察 trace 里的 cache source、cached tokens、prefill 时间变化。只有当磁盘 KV 的命中带来可感知收益,再扩大 context 或尝试 q4。
阅读来源
主要来源是 GitHub 页面、本地 clone 后的 README、AGENT notes、Makefile、头文件、server/engine/Metal 源码和测试说明。