Я поднял нейросеть на 284 миллиарда параметров — 13 миллиардов активных на токен — на обычном MacBook Pro.

Звучит дико: квант весит 81 ГБ, а в моём Mac всего 64 ГБ памяти. Веса не помещаются в RAM.

Но модель работает.

Я использовал ds4 — движок, который держит базовые веса и часть MoE-экспертов в оперативной памяти, а остальных на лету читает с SSD.

RAM перестал быть потолком. Вопрос теперь не в том, запустится ли модель, а в том, сколько придётся ждать ответа.


Требования к железу⌗

  • 8 ГБ — скорее для проверки возможности запуска: 1–2 t/s из-за постоянного своппинга;
  • 16 ГБ — минимум: контекст 4K, кэш 8 ГБ;
  • 32 ГБ — рабочий вариант: контекст 32K, кэш 12–16 ГБ;
  • 64 ГБ — контекст 64K, кэш 20 ГБ.

Модель должна лежать на внутреннем SSD. Нужно минимум 100–120 ГБ свободного места: 81 ГБ под веса, остальное — под своппинг.


Установка и загрузка модели⌗

xcode-select --install
git clone https://github.com/antirez/ds4.git && cd ds4 && make
./download_model.sh ds4f-q2

Запуск для Mac с 16 ГБ RAM:

DS4_METAL_ENABLE_STREAMING_EXPERT_PER_LAYER_QUOTA=1 \
DS4_METAL_ENABLE_STREAMING_EXPERT_QUOTA_BORROW=1 \
DS4_METAL_DISABLE_STREAMING_EXPERT_HOTLIST=1 \
./ds4 \
  -m ./ds4flash.gguf \
  --ssd-streaming \
  --ssd-streaming-cache-experts 8GB \
  --ctx 4096 \
  --prefill-chunk 256 \
  --nothink \
  -p "Привет! Расскажи о себе." \
  -n 128

Скорость и узкое место⌗

Замеры на M1 Max с 64 ГБ RAM и кэшем 20 ГБ:

Контекст Prefill Generation
4K 74 t/s 3 t/s
16K 71 t/s 5 t/s
64K 63 t/s 5 t/s

Главное узкое место — prefill. Перед первым словом модель проглатывает весь контекст.

Мой стартовый запрос в OpenCode — скиллы, системный промпт и MCP — занимает около 16 тысяч токенов.

При скорости 74 t/s prefill занимает примерно:

  • 4K контекста — 55 секунд;
  • 16K — почти 4 минуты;
  • 64K — 17 минут.

Генерация идёт со скоростью 3–5 t/s. Для сравнения, GPT Luna в облаке выдаёт около 58 t/s — в 12–18 раз быстрее.


Размер кэша экспертов⌗

Я проверил, что произойдёт, если увеличить кэш экспертов до 40 ГБ:

Кэш 4K 16K 64K
4 ГБ 3 3 3 t/s
8 ГБ 3 3 3 t/s
16 ГБ 3 2 4 t/s
20 ГБ 3 5 5 t/s
32 ГБ 2 2 1 t/s
40 ГБ 4 3 0,1 t/s

При кэше 40 ГБ и контексте 64K генерация упала до 0,1 t/s: macOS ушла в своппинг. Оптимум для Mac с 64 ГБ — около 20 ГБ.

Скорость упирается не в размер кэша, а в структуру MoE-маршрутизации. У DeepSeek V4 Flash 43 слоя, и на каждом свой банк из 256 экспертов. Наборы независимы и не пересекаются между слоями.

На каждом слое свой router выбирает шесть экспертов почти случайно, без связи с выбором на предыдущих слоях. Один токен за проход делает 43 таких независимых выбора — 258 обращений к экспертам. Всего в модели 43 × 256 = 11 008 уникальных экспертов.

Каждый следующий токен снова обращается к новому набору. Расширение кэша с 20 до 40 ГБ добавляет всего пару тысяч слотов против этих 11 008, поэтому cache hit rate растёт медленно и быстро выходит на плато.


Подключение к OpenCode⌗

Сначала собираем и поднимаем сервер:

make ds4-server
mkdir -p ~/.ds4/server-kv-64k

DS4_METAL_ENABLE_STREAMING_EXPERT_PER_LAYER_QUOTA=1 \
DS4_METAL_ENABLE_STREAMING_EXPERT_QUOTA_BORROW=1 \
DS4_METAL_DISABLE_STREAMING_EXPERT_HOTLIST=1 \
DS4_METAL_STREAMING_EXPERT_PREAD_THREADS=18 \
./ds4-server \
  --metal \
  --model ./ds4flash.gguf \
  --ssd-streaming \
  --ssd-streaming-cache-experts 20GB \
  --ctx 65536 \
  --tokens 8192 \
  --prefill-chunk 256 \
  --kv-disk-dir ~/.ds4/server-kv-64k \
  --kv-disk-space-mb 8192 \
  --host 127.0.0.1 \
  --port 8003

В ~/.config/opencode/opencode.jsonc добавляем провайдера:

{
  "provider": {
    "ds4": {
      "name": "DS4 (local)",
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "baseURL": "http://127.0.0.1:8003/v1",
        "timeout": false
      },
      "models": {
        "deepseek-v4-flash": {
          "name": "DeepSeek V4 Flash",
          "reasoning": true,
          "tool_call": true,
          "limit": {
            "context": 65536,
            "output": 8192
          }
        }
      }
    }
  }
}

После перезапуска OpenCode можно выбрать модель ds4/deepseek-v4-flash.