Запуск локальных LLM на Mac

Это руководство проведёт вас через запуск локального LLM-сервера на macOS с OpenAI-совместимым API. Вы получаете полную приватность, нулевые затраты на API и удивительно хорошую производительность на Apple Silicon.

Мы рассматриваем два бэкенда:

Бэкенд Установка Лучше всего Формат
llama.cpp brew install llama.cpp Самое быстрое время до первого токена, квантованный KV-кэш для малого потребления памяти GGUF
omlx omlx.ai Самая быстрая генерация токенов, нативная оптимизация Metal MLX (safetensors)

Оба предоставляют OpenAI-совместимый эндпоинт /v1/chat/completions. Hermes работает с любым из них — просто укажите http://localhost:8080 или http://localhost:8000.

info Только Apple Silicon Это руководство предназначено для Mac на Apple Silicon (M1 и новее). Intel Mac будут работать с llama.cpp, но без GPU-ускорения — ожидайте значительно более низкой производительности.


Выбор модели

Для начала мы рекомендуем Qwen3.5-9B — это мощная модель для рассуждений, которая комфортно помещается в 8+ ГБ унифицированной памяти с квантованием.

Вариант Размер на диске Требуется ОЗУ (контекст 128K) Бэкенд
Qwen3.5-9B-Q4_K_M (GGUF) 5.3 GB ~10 GB с квантованным KV-кэшем llama.cpp
Qwen3.5-9B-mlx-lm-mxfp4 (MLX) ~5 GB ~12 GB omlx

Эмпирическое правило памяти: размер модели + KV-кэш. Модель 9B Q4 занимает ~5 ГБ. KV-кэш при контексте 128K с Q4-квантованием добавляет ~4-5 ГБ. Со стандартным (f16) KV-кэшем это раздувается до ~16 ГБ. Флаги квантованного KV-кэша в llama.cpp — ключевой трюк для систем с ограниченной памятью.

Для более крупных моделей (27B, 35B) потребуется 32+ ГБ унифицированной памяти. 9B — оптимальный вариант для машин с 8-16 ГБ.


Вариант A: llama.cpp

llama.cpp — это наиболее портативная среда выполнения локальных LLM. На macOS он использует Metal для GPU-ускорения из коробки.

Установка

brew install llama.cpp

Это даёт вам команду llama-server глобально.

Загрузка модели

Вам нужна модель в формате GGUF. Проще всего скачать её с Hugging Face через huggingface-cli:

brew install huggingface-cli

Затем загрузите:

huggingface-cli download unsloth/Qwen3.5-9B-GGUF Qwen3.5-9B-Q4_K_M.gguf --local-dir ~/models

tip Модели с ограниченным доступом Некоторые модели на Hugging Face требуют аутентификации. Сначала выполните huggingface-cli login, если получаете ошибку 401 или 404.

Запуск сервера

llama-server -m ~/models/Qwen3.5-9B-Q4_K_M.gguf \\
  -ngl 99 \\
  -c 131072 \\
  -np 1 \\
  -fa on \\
  --cache-type-k q4_0 \\
  --cache-type-v q4_0 \\
  --host 0.0.0.0

Вот что означает каждый флаг:

Флаг Назначение
-ngl 99 Выгружает все слои на GPU (Metal). Используйте большое число, чтобы ничего не оставалось на CPU.
-c 131072 Размер окна контекста (128K токенов). Уменьшите, если не хватает памяти.
-np 1 Количество параллельных слотов. Оставьте 1 для одного пользователя — больше слотов разделяет ваш бюджет памяти.
-fa on Flash attention. Уменьшает использование памяти и ускоряет инференс с длинным контекстом.
--cache-type-k q4_0 Квантование кэша ключей до 4 бит. Это главный экономитель памяти.
--cache-type-v q4_0 Квантование кэша значений до 4 бит. Вместе с предыдущим это сокращает память KV-кэша на ~75% по сравнению с f16.
--host 0.0.0.0 Слушает на всех интерфейсах. Используйте 127.0.0.1, если не нужен сетевой доступ.

Сервер готов, когда вы видите:

main: server is listening on http://0.0.0.0:8080
srv  update_slots: all slots are idle

Оптимизация памяти для систем с ограничениями

Флаги --cache-type-k q4_0 --cache-type-v q4_0 — это самая важная оптимизация для систем с ограниченной памятью. Вот влияние при контексте 128K:

Тип KV-кэша Память KV-кэша (контекст 128K, модель 9B)
f16 (по умолчанию) ~16 GB
q8_0 ~8 GB
q4_0 ~4 GB

На Mac с 8 ГБ используйте KV-кэш q4_0 и уменьшите контекст до -c 32768 (32K). На 16 ГБ можно комфортно использовать контекст 128K. На 32+ ГБ можно запускать более крупные модели или несколько параллельных слотов.

Если памяти всё ещё не хватает, сначала уменьшите размер контекста (-c), затем попробуйте более сильное квантование (Q3_K_M вместо Q4_K_M).

Тестирование

curl -s http://localhost:8080/v1/chat/completions \\
  -H "Content-Type: application/json" \\
  -d '{
    "model": "Qwen3.5-9B-Q4_K_M.gguf",
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 50
  }' | jq .choices[0].message.content

Получение имени модели

Если вы забыли имя модели, запросите эндпоинт моделей:

curl -s http://localhost:8080/v1/models | jq '.data[].id'

Вариант B: MLX через omlx

omlx — это нативное macOS-приложение для управления и раздачи MLX-моделей. MLX — это собственный фреймворк машинного обучения Apple, оптимизированный специально для архитектуры унифицированной памяти Apple Silicon.

Установка

Скачайте и установите с omlx.ai. Он предоставляет графический интерфейс для управления моделями и встроенный сервер.

Загрузка модели

Используйте приложение omlx для просмотра и загрузки моделей. Найдите Qwen3.5-9B-mlx-lm-mxfp4 и скачайте его. Модели хранятся локально (обычно в ~/.omlx/models/).

Запуск сервера

omlx раздаёт модели на http://127.0.0.1:8000 по умолчанию. Запустите раздачу из интерфейса приложения или используйте CLI, если доступно.

Тестирование

curl -s http://127.0.0.1:8000/v1/chat/completions \\
  -H "Content-Type: application/json" \\
  -d '{
    "model": "Qwen3.5-9B-mlx-lm-mxfp4",
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 50
  }' | jq .choices[0].message.content

Список доступных моделей

omlx может раздавать несколько моделей одновременно:

curl -s http://127.0.0.1:8000/v1/models | jq '.data[].id'

Бенчмарки: llama.cpp vs MLX

Оба бэкенда протестированы на одной машине (Apple M5 Max, 128 ГБ унифицированной памяти) с одной и той же моделью (Qwen3.5-9B) на сопоставимых уровнях квантования (Q4_K_M для GGUF, mxfp4 для MLX). Пять разнообразных промптов, по три запуска каждый, бэкенды тестировались последовательно во избежание конкуренции за ресурсы.

Результаты

Метрика llama.cpp (Q4_K_M) MLX (mxfp4) Победитель
TTFT (среднее) 67 ms 289 ms llama.cpp (в 4.3x быстрее)
TTFT (p50) 66 ms 286 ms llama.cpp (в 4.3x быстрее)
Генерация (среднее) 70 tok/s 96 tok/s MLX (на 37% быстрее)
Генерация (p50) 70 tok/s 96 tok/s MLX (на 37% быстрее)
Общее время (512 токенов) 7.3s 5.5s MLX (на 25% быстрее)

Что это означает

Какой выбрать?

Сценарий использования Рекомендация
Интерактивный чат, инструменты с низкой задержкой llama.cpp
Длительная генерация, пакетная обработка MLX (omlx)
Ограниченная память (8-16 ГБ) llama.cpp (квантованный KV-кэш вне конкуренции)
Одновременная раздача нескольких моделей omlx (встроенная поддержка нескольких моделей)
Максимальная совместимость (включая Linux) llama.cpp

Подключение к Hermes

Когда ваш локальный сервер запущен:

hermes model

Выберите Custom endpoint и следуйте подсказкам. Будет запрошен базовый URL и имя модели — используйте значения из выбранного вами бэкенда.


Таймауты

Hermes автоматически определяет локальные эндпоинты (localhost, LAN IP) и ослабляет таймауты стриминга. Для большинства настроек не требуется конфигурация.

Если вы всё ещё получаете ошибки таймаута (например, очень большие контексты на медленном железе), вы можете переопределить таймаут чтения стриминга:

# In your .env — raise from the 120s default to 30 minutes
HERMES_STREAM_READ_TIMEOUT=1800
Таймаут По умолчанию Локальная автокорректировка Переопределение через переменную окружения
Чтение стрима (уровень сокета) 120 с Повышен до 1800 с HERMES_STREAM_READ_TIMEOUT
Обнаружение зависшего стрима 180 с Полностью отключён HERMES_STREAM_STALE_TIMEOUT
API-вызов (без стриминга) 1800 с Изменения не требуются HERMES_API_TIMEOUT

Таймаут чтения стрима — наиболее вероятная причина проблем. Это дедлайн на уровне сокета для получения следующего фрагмента данных. Во время префилла на больших контекстах локальные модели могут не выдавать вывод в течение нескольких минут, пока обрабатывается промпт. Автоопределение обрабатывает это прозрачно.