ds4 от antirez: локальный coding agent на DeepSeek V4 Flash, который работает на MacBook
Создатель Redis за две недели написал инференс-движок только для одной модели — DeepSeek V4 Flash. 1M контекст, 26 t/s на M3 Max, KV-кэш на диске. Как это запустить и подключить к Claude Code.
Garry Tan и Bindu Reddy 9 мая 2026 одновременно расшарили одну и ту же новость: создатель Redis Salvatore Sanfilippo (antirez) выложил
ds4— инференс-движок на C+Metal, который запускает DeepSeek V4 Flash (284B MoE, 1M контекста) на ноутбуке. Не «технически возможно», а «работает с coding-агентами на 26 t/s». Я разобрался, что под капотом, и как использовать это как локальный backend для Claude Code.
1. Что произошло за две недели
24 апреля 2026 DeepSeek выпустил серию V4. V4 Flash — efficiency-модель: 284 миллиарда параметров суммарно, 13 миллиардов активных (MoE), контекст 1 миллион токенов. Раньше модели такого размера жили только в облаке.
Antirez посмотрел на это и сделал ставку, которую универсальные раннеры сделать не могут. Он форкнул llama.cpp, две недели возился внутри него, понял геометрию V4 Flash, выкинул всё лишнее и написал с нуля движок на 4 файлах: ds4.c (~ инференс), ds4_metal.m (Metal kernels), ds4_server.c (HTTP-сервер), ds4_cli.c (REPL). Снаружи всё это говорит на двух протоколах одновременно: OpenAI Chat Completions (/v1/chat/completions) и Anthropic Messages (/v1/messages). То есть подключается к любому агенту, который умеет один из них.
Результаты, которые автор замерил сам:
| Машина | Квант | Промпт | Prefill | Generation |
|---|---|---|---|---|
| MacBook Pro M3 Max, 128 GB | q2 | короткий | 58.52 t/s | 26.68 t/s |
| MacBook Pro M3 Max, 128 GB | q2 | 11709 токенов | 250.11 t/s | 21.47 t/s |
| Mac Studio M3 Ultra, 512 GB | q2 | короткий | 84.43 t/s | 36.86 t/s |
| Mac Studio M3 Ultra, 512 GB | q4 | 12018 токенов | 448.82 t/s | 26.62 t/s |
26 токенов в секунду генерации — это не «можно посмотреть», это рабочая скорость для coding-агента, который пишет, читает файлы, вызывает инструменты. На длинном промпте генерация падает до 21 t/s, но за счёт KV-кэша на диске это окупается уже на третьем запросе той же сессии.
2. Три инженерных трюка, которые делают это возможным
Я внимательно прочитал README и AGENT.md репозитория, и ниже — самое существенное, без чего ds4 не работал бы.
2.1. Асимметричное 2-битное квантование
Стандартный подход к 2-битному кванту — давить всё подряд до 2 бит, и тогда модель начинает галлюцинировать в tool calling, путать аргументы и забывать схему. Antirez сделал иначе: квантованы только MoE-эксперты на routed-пути (up/gate в IQ2_XXS, down в Q2_K) — потому что они занимают большую часть веса (модель — 284B, и почти всё это — эксперты). Shared-эксперты, проекции, роутинг — остаются в Q8. Это компоненты, в которых потеря точности дорого стоит.
Эффект: 2-битный квант весит 81 GB и помещается в 128 GB унифицированной памяти MacBook Pro M3 Max, при этом надёжно работает в coding-агентах (что валидируется тестами против официальных логитов API DeepSeek).
2.2. KV-кэш как first-class disk citizen
Главная боль stateless API-протоколов вроде Chat Completions: клиент каждый раз присылает всю историю, и сервер обязан пре-фильнуть её с нуля. Claude Code, например, на старте шлёт ~25K токенов системного промпта. На локальном железе это десятки секунд до первого токена.
Ds4 решает это лобово: после успешного prefill стейт сессии (KV-чекпоинт) сериализуется в файл, ключ — SHA1 от token IDs. Когда приходит следующий запрос с тем же префиксом, сервер берёт чекпоинт с диска и пропускает prefill. Из README:
The KV cache is actually a first class disk citizen. <…> Modern MacBooks have fast SSDs and compressed KV caches like the one of DeepSeek v4.
На практике это означает разницу между «4 секунды до первого токена при повторном вызове» и «60 секунд». Диск тут — не своп под давлением, а логичное хранилище: SSD достаточно быстрые, KV у DeepSeek V4 хорошо сжимается, а характеристика «один и тот же системный промпт + меняющийся хвост» точно описывает работу coding-агента.
2.3. Metal-only и одна модель за раз
Никакого CUDA, никакого CPU-фоллбэка для прода (CPU-путь существует только для correctness-чеков и сейчас падает на уровне ядра macOS из-за бага в VM — antirez об этом честно пишет). Никакой попытки сделать «универсальный раннер». Только Apple Silicon, только эта одна модель, и так до тех пор, пока не появится новая версия V4 Flash или сильно лучшая модель того же класса.
Цена — narrow bet. Выгода — тебе не нужно поддерживать матрицу (модель × железо × квант), и ты можешь оптимизировать Metal-ядра под точную геометрию слоёв этой конкретной модели.
3. Что мне понадобится: железо, модель, час времени
Я планирую разворачивать это на MacBook Pro M3 Max, 128 GB (минимально жизнеспособная конфигурация по README). У меня его пока нет, и в этом разделе — честный план, что я буду делать, когда железо приедет; цифры взяты из бенчмарков antirez’а, но я хочу их перепроверить на своём экземпляре.
Минимальные требования по моим прикидкам:
- macOS на актуальной версии (там же баг VM в CPU-пути, но Metal-путь не задет).
- Apple Silicon с 128 GB+ унифицированной памяти. M3 Max или M3 Ultra.
- ~100 GB свободного места: 81 GB сама модель Q2 + место под KV-кэш на диске. Под Q4-квант — 256 GB+ RAM и ~150 GB на диске.
- Xcode Command Line Tools (для clang/Metal headers).
- ~30–60 минут на скачивание модели (зависит от канала).
То, чего может не хватить начинающим: 128 GB unified memory — это уровень MBP M3 Max в топовой комплектации или Mac Studio. На 64-гиговом Mac Q2 не заработает: модель просто не влезет в RAM. Это не «медленно», это «никак».
4. Установка пошагово
Команды ниже — то, что я сделаю в первый же день, опираясь на инструкции README. Где описание скучает за конкретикой — я добавил собственные комментарии.
4.1. Сборка
# 1. Склонировать репозиторий
git clone https://github.com/antirez/ds4.git
cd ds4
# 2. Скачать 2-битный квант (81 GB; для 128 GB MBP)
./download_model.sh q2
# Скрипт качает с huggingface.co/antirez/deepseek-v4-gguf,
# поддерживает резюм через curl -C - — можно прервать и продолжить.
# Если нужен 4-битный квант (для Mac Studio 256+ GB), используй ./download_model.sh q4.
# 3. Собрать
make
# Проверить, что собралось:
./ds4 --help
./ds4-server --help
Сборка — обычный make, никаких CMake, никаких pkg-config. Это намеренно: зависимостей за пределами Apple SDK у проекта нет.
4.2. Первый запуск в REPL
./ds4 -p "Объясни Redis streams в одном абзаце."
Без -p запускается интерактивная сессия с командами /help, /think, /think-max, /nothink, /ctx N, /read FILE, /quit. Это хорошо для проверки, что движок жив, и для сравнения скорости генерации против заявленных 26 t/s.
4.3. Запуск как HTTP-сервер
Это режим, в котором ds4 становится локальным backend’ом для агентов:
./ds4-server \
--ctx 100000 \
--kv-disk-dir /tmp/ds4-kv \
--kv-disk-space-mb 8192
Параметры:
--ctx 100000— контекстное окно в 100K токенов. Полный 1M-контекст ест ~26 GB только на индексер; на 128 GB Mac, где 81 GB уже занято моделью, это не оставит места для KV-кэша. 100–300K — разумный компромисс.--kv-disk-dir /tmp/ds4-kv— каталог для disk KV-кэша. Я бы вынес его на быстрый SSD (внешний или встроенный — оба ок).--kv-disk-space-mb 8192— лимит на размер кэша. 8 GB для одного-двух активных проектов хватит; для сессий побольше — увеличивай.
Сервер слушает 127.0.0.1:8000. Эндпоинты:
| Endpoint | Протокол |
|---|---|
POST /v1/chat/completions | OpenAI Chat Completions (+ tools) |
POST /v1/completions | OpenAI legacy completions |
POST /v1/messages | Anthropic Messages (для Claude Code) |
GET /v1/models | список моделей |
Аутентификация по статичному API-ключу (по умолчанию принимается любой; в README рекомендуется dsv4-local).
5. Подключение как coding agent
Это та часть, ради которой я вообще копал тему. Все три приведённых ниже способа работают одновременно — каждый агент ходит в один и тот же ds4-server.
5.1. Claude Code → Anthropic-совместимый эндпоинт
Claude Code умеет говорить с любым backend’ом, который выставляет Anthropic Messages API. Создаём обёртку ~/bin/claude-ds4:
#!/bin/sh
unset ANTHROPIC_API_KEY
export ANTHROPIC_BASE_URL="${DS4_ANTHROPIC_BASE_URL:-http://127.0.0.1:8000}"
export ANTHROPIC_AUTH_TOKEN="${DS4_API_KEY:-dsv4-local}"
export ANTHROPIC_MODEL="deepseek-v4-flash"
# Подменяем все алиасы Sonnet/Haiku/Opus на локальную модель —
# чтобы /model в Claude Code не дёрнул облачный fallback.
export ANTHROPIC_DEFAULT_SONNET_MODEL="deepseek-v4-flash"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="deepseek-v4-flash"
export ANTHROPIC_DEFAULT_OPUS_MODEL="deepseek-v4-flash"
export CLAUDE_CODE_SUBAGENT_MODEL="deepseek-v4-flash"
# Отключаем телеметрию и не-стриминговый fallback.
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
export CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1
export CLAUDE_STREAM_IDLE_TIMEOUT_MS=600000
exec "$HOME/.local/bin/claude" "$@"
chmod +x ~/bin/claude-ds4 — и запускаешь Claude Code как claude-ds4 вместо claude. Все запросы пойдут на локальный ds4-сервер. Тонкость, на которую обращает внимание сам antirez:
Claude Code may send a large initial prompt, often around 25k tokens, before it starts doing useful work. Keep
--kv-disk-direnabled.
Без disk KV-кэша запуск Claude Code на холодную будет занимать минуту и больше; с кэшем — после первого старта последующие будут восстанавливаться с диска.
5.2. opencode
opencode конфигурируется через ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ds4": {
"name": "ds4.c (local)",
"npm": "@ai-sdk/openai-compatible",
"options": {
"baseURL": "http://127.0.0.1:8000/v1",
"apiKey": "dsv4-local"
},
"models": {
"deepseek-v4-flash": {
"name": "DeepSeek V4 Flash (ds4.c local)",
"limit": { "context": 100000, "output": 384000 }
}
}
}
},
"agent": {
"ds4": {
"description": "DeepSeek V4 Flash served by local ds4-server",
"model": "ds4/deepseek-v4-flash",
"temperature": 0
}
}
}
limit.context: 100000 обязательно совпадает с --ctx, с которым стартует ds4-server — иначе сервер обрежет, а opencode об этом не узнает и пошлёт следующее сообщение, ожидая нерабочую длину.
5.3. Pi (мини-агент antirez’а)
Если используешь Pi — формат немного другой, конфиг в ~/.pi/agent/models.json:
{
"providers": {
"ds4": {
"name": "ds4.c 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",
"thinkingFormat": "deepseek",
"requiresReasoningContentOnAssistantMessages": true
},
"models": [
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash (ds4.c local)",
"reasoning": true,
"contextWindow": 100000,
"maxTokens": 384000,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}
cost: 0 — это не маркетинг, это правда. Каждый запрос обходится в электричество и износ SSD, не в токены.
6. Где это сломается (важные грабли)
Реальные ограничения, на которые я наткнусь, и то, как их обходить.
Окно контекста должно быть согласовано везде. Стартуешь сервер с --ctx 100000, ставишь в opencode limit.context: 100000, в Claude Code не лезешь в системный промпт сверх этого. Если у Claude Code init-prompt ~25K, то на проект остаётся 75K — реально хватает на средний codebase, но не на огромные репозитории.
Disk KV-кэш «привязан» к точному префиксу. Любая правка в системном промпте, в CLAUDE.md, в первых сообщениях — инвалидирует чекпоинт. Это не баг, это by design: матчинг идёт по SHA1 от token IDs. Если ты часто редактируешь CLAUDE.md, ожидай холодные старты. Решение — закоммитить системный контракт и не править его в каждой сессии.
MTP/спекулятивное декодирование пока не даёт большого выигрыша. В README прямо написано: «currently provides at most a slight speedup». Не закладывайся на удвоение скорости от MTP — текущая реализация correctness-gated и на сложных промптах часто триггерит партиал-аксепт.
Один live KV-кэш в памяти. Сервер сейчас не батчит независимые запросы. Если два агента ходят одновременно — второй ждёт первого. Это нормальный trade-off для локального single-user setup, но если ты хочешь параллельный multi-tenancy на одном Mac — ds4 пока не для этого.
CPU-режим падает на свежих macOS. Это про debug-путь, не про прод (Metal-only — основной таргет), но если по привычке захочешь сравнить инференс на CPU — не делай этого: kernel-panic, надо ребутиться.
7. Что это значит: vertical inference engines как тренд
Главное — не ds4 сам по себе, а паттерн, который antirez формализовал.
Локальный inference сейчас выглядит как «универсальный раннер + тысяча моделей в GGUF + обёртки разной свежести». Это работает, но движётся со скоростью наименее популярной модели: ускорять Llama 3.1 в llama.cpp проще, чем добавить эффективную поддержку DeepSeek V4 — потому что в первом случае структура слоёв совпадает с двадцатью другими моделями, а во втором — appears once.
Antirez показывает противоположный путь. Один движок — одна модель — один сценарий (coding agent). Дальше нужно три вещи, и все три — в продукте:
- Inference engine с HTTP API.
- GGUF, специально подготовленный под этот движок и его допущения.
- Тесты и валидация на сцепке с конкретными агент-клиентами.
Если эта ставка работает (и бенчмарки говорят, что да), будущее локального inference — не «ещё одна абстракция поверх абстракции», а «у каждой важной модели — свой ds4-подобный проект». Когда выходит V4.1 или V5, кто-то из community делает новый движок, новый GGUF, новые тесты, и через две недели у пользователей уже работающая локальная установка. Старые движки уходят на покой вместе со старыми моделями.
И второе. В README antirez явно пишет:
This software is developed with strong assistance from GPT 5.5 and with humans leading the ideas, testing, and debugging.
Две недели от форка llama.cpp до production-ready узкого движка с серверным API — без AI это не сделать, и antirez это прямо говорит. Вот это переключение — «один человек + AI = инфраструктура для целой модели за две недели» — на мой взгляд интереснее, чем сами цифры t/s.
Итог
ds4 от antirez — это не «ещё один локальный инференс». Это узкая ставка: один движок, одна модель (DeepSeek V4 Flash), одна архитектура железа (Apple Silicon с Metal), один сценарий (coding agent). За счёт асимметричного 2-битного кванта 284B-модель влезает в 128 GB MacBook, за счёт disk KV-кэша работает с агентами, которые гоняют 25K-токенные системные промпты, за счёт OpenAI/Anthropic-совместимости подключается к Claude Code, opencode и Pi из коробки.
Если у вас есть Mac с 128 GB+ — это рабочий локальный backend для серьёзной коммерческой работы с приватным кодом. Если нет — ждать DDR5 и unified memory на Linux/CUDA, или смотреть, кто следующий повторит этот паттерн под свою связку «модель + железо».
В любом случае стоит наблюдать. Я ставлю на то, что через год так будут собирать половину серьёзных локальных установок.
Источники:
- github.com/antirez/ds4 — README, бенчмарки, конфиги
- Garry Tan — пост в X (9 мая 2026)
- Bindu Reddy — пост в X (9 мая 2026)
- QbitAI / 36kr: Redis Father Steps In to Build Dedicated Inference Engine for DeepSeek V4
- HN: DeepSeek 4 Flash local inference engine for Metal
- huggingface.co/antirez/deepseek-v4-gguf
FAQ
Зачем отдельный движок под одну модель, если есть llama.cpp?
Универсальные раннеры обязаны абстрагироваться: один и тот же код должен загрузить Llama, Qwen, DeepSeek, Mistral. Абстракция = компромисс. ds4 знает геометрию DeepSeek V4 Flash на уровне Metal-ядер, делает асимметричную 2-битную квантизацию (квантуются только MoE-эксперты, остальное в Q8), и валидирует логиты против официального API. Цена — узкая ставка на одну модель: появится V4.1 или V5 — нужно переписывать. Но для текущего поколения это даёт быстрый прирост, который универсальному раннеру технически недоступен.
Какой Mac реально нужен?
Минимум — 128 GB унифицированной памяти и Apple Silicon (M3 Max или старше). На таком железе работают 2-битные кванты Q2 (вес ~81 GB), 32K контекст, 26 t/s генерации. Для 4-битных квантов и больших контекстов нужен M3 Ultra с 256 GB+ (комфортно — 512 GB Mac Studio). На 64 GB MacBook ничего не запустится: модель не влезет в RAM.
Можно ли запустить на Linux/CUDA?
Сейчас — нет. Проект Metal-only, и автор честно пишет: «возможно, добавлю CUDA, но обещаний не даю». CPU-путь существует только как correctness-чек и в текущих macOS падает на уровне ядра из-за бага виртуальной памяти. Если у вас не Mac — ds4 не для вас, смотрите на vLLM/llama.cpp с DeepSeek V4 Flash GGUF.
Что такое asymmetric quantization и почему 2 бита не убивают качество?
В обычной 2-битной квантизации все веса сжимаются до 2 бит — модель теряет точность и часто перестаёт надёжно вызывать tools. ds4 делает иначе: 2-битно квантуются только MoE up/gate (IQ2_XXS) и down (Q2_K), которые занимают большую часть веса. Shared-эксперты, проекции и роутинг остаются в Q8 — это чувствительные части, где потеря точности дороже. На практике 2-битный Q2 надёжно работает с coding-агентами, что и подтверждается в тестах против официальных логитов API.
Disk KV cache — это просто свопинг?
Нет. Стейт inference-сессии (KV-чекпоинт) сериализуется в файл с SHA1 от token IDs в качестве ключа. Когда агент-клиент присылает следующий запрос с тем же префиксом (а Claude Code типично шлёт ~25K токенов системного промпта каждый раз), сервер не делает пре-фил с нуля — он восстанавливает чекпоинт с диска. Это разница между «4 секунды до первого токена» и «60 секунд до первого токена» на длинном промпте.
Чем это лучше OpenAI/Anthropic API?
Не лучше — а другое. Облачный API всегда быстрее, надёжнее, и модели поверх него умнее (текущая фронтир-планка — Sonnet 4.6, Opus 4.6, GPT 5.5). ds4 на DeepSeek V4 Flash — это «квази-фронтир» с тремя выгодами: ноль рублей за токены, полный контроль данных, оффлайн-работа. Подходит для приватных проектов, экспериментов с агентами и работы в самолёте. Не подходит, если вам нужна максимальная точность или работа с контекстом, который не влезет в ваш Mac.