В предыдущей статье мы разобрали, зачем нужна ферма из Mac Mini, какую скорость она показывает и когда выгоднее серверов с NVIDIA. Теперь — практика. Эта инструкция проведёт от распаковки четырёх Mac Mini до момента, когда вы отправите первый запрос к модели с 235 миллиардами параметров и получите ответ.
Целевая аудитория — ИТ-специалист, который умеет работать с терминалом, SSH и знает, что такое IP-адрес. Если вы руководитель — передайте эту статью вашему системному администратору.
Что понадобится: чеклист перед стартом
Железо
| Компонент | Минимум | Рекомендация |
|---|---|---|
| Mac Mini | 2x M4 Pro (24 ГБ) | 4x M4 Pro (64 ГБ) |
| Кабели Thunderbolt | 2 шт. (для пары) | 4 шт. (для кольца из 4 узлов) |
| Ethernet-коммутатор | гигабитный | 10 GbE (для управления) |
| Ethernet-кабели | Cat5e | Cat6a |
| Клавиатура + монитор | для первоначальной настройки | можно один комплект на все узлы |
Кабели Thunderbolt 5 и обычные USB-C выглядят одинаково. Убедитесь, что на кабеле есть значок молнии (Thunderbolt). Обычный USB-C кабель не обеспечит нужную скорость и не поддерживает RDMA. Для Thunderbolt 5 нужны именно TB5-сертифицированные кабели — пассивные длиной до 1 метра или активные до 3 метров.
Порты Mac Mini M4 Pro: что куда подключать
На задней панели — 3 порта Thunderbolt 5 (USB-C). Все три равноценны для RDMA и сетевого соединения.
На передней панели — 2 порта USB-C. Это USB 3, не Thunderbolt. Подключать к ним кабели кластера бесполезно — скорость будет в 20 раз ниже.
Софт
| Компонент | Версия |
|---|---|
| macOS | Tahoe 26.2+ (для RDMA) или Sequoia (без RDMA) |
| Python | 3.13+ |
| uv | 0.8.6+ |
| Node.js | 18+ |
| Rust | nightly |
| Xcode | последняя версия |
Шаг 1 — Подготовка macOS: SSH, энергосбережение, headless
Подключите монитор и клавиатуру к первому Mac Mini. Пройдите стандартную настройку macOS. Повторите для каждого узла. После первоначальной настройки монитор больше не понадобится.
1.1. Включите SSH (Remote Login)
System Settings > General > Sharing > включите Remote Login > выберите «Administrators Only».
Или через терминал:
sudo systemsetup -setremotelogin on
1.2. Настройте SSH-ключи (с управляющей машины)
ssh-keygen -t ed25519 -C "cluster-admin"
ssh-copy-id user@mac-mini-01
ssh-copy-id user@mac-mini-02
ssh-copy-id user@mac-mini-03
ssh-copy-id user@mac-mini-04
Проверьте — вход без пароля:
ssh user@mac-mini-01 'hostname'
1.3. Настройте энергосбережение для серверного режима
На каждом узле:
sudo pmset -a sleep 0
sudo pmset -a displaysleep 1
sudo pmset -a disksleep 0
sudo pmset -a hibernatemode 0
sudo pmset -a powernap 0
sudo pmset -c autorestart 1
sudo pmset -c womp 1
Эти команды: запрещают сон, отключают экран через минуту, автоматически перезапускают Mac после сбоя питания и включают Wake-on-LAN.
1.4. Отключите лишнее
sudo mdutil -a -i off
sudo networksetup -setairportpower en1 off
sudo tmutil disable
Spotlight-индексация, Wi-Fi и Time Machine — три процесса, которые расходуют ресурсы на серверной машине без пользы.
1.5. Серверный режим производительности (опционально)
sudo nvram boot-args="serverperfmode=1"
Увеличивает выделение памяти под сетевые сервисы. Требует перезагрузки.
Если включён FileVault, после каждого сбоя питания Mac потребует физический ввод пароля перед тем, как SSH станет доступен. Для серверного режима FileVault лучше отключить или обеспечить физический доступ к машинам при перезагрузках.
Шаг 2 — Соединяем кабелем: Thunderbolt Bridge и топология
2.1. Физическое подключение
Для 2 узлов: один кабель Thunderbolt 5 между любыми задними портами двух Mac Mini.
Для 4 узлов (кольцо): каждый Mac соединён с двумя соседями. Используются 2 из 3 задних портов, один остаётся свободным.
Mac A [порт 1] ---- [порт 1] Mac B
Mac B [порт 2] ---- [порт 1] Mac C
Mac C [порт 2] ---- [порт 1] Mac D
Mac D [порт 2] ---- [порт 2] Mac A
Дополнительно подключите каждый Mac к Ethernet-коммутатору обычным кабелем — это управляющая сеть для SSH, обновлений и интернета.
2.2. Настройка Thunderbolt Bridge
На каждом Mac:
- System Settings > Network
- Найдите Thunderbolt Bridge (появится автоматически после подключения кабеля)
- Если не появился: нажмите «...» > Add Service > Interface: Thunderbolt Bridge > Create
- Нажмите Details... рядом с Thunderbolt Bridge
- В боковом меню выберите TCP/IP
- Измените «Configure IPv4» на Manually
2.3. Назначьте статические IP-адреса
Используйте подсеть, отличную от вашей Ethernet-сети:
| Узел | Thunderbolt IP | Маска | Ethernet IP (управление) |
|---|---|---|---|
| mac-mini-01 | 10.66.2.11 | 255.255.255.0 | 192.168.1.51 |
| mac-mini-02 | 10.66.2.12 | 255.255.255.0 | 192.168.1.52 |
| mac-mini-03 | 10.66.2.13 | 255.255.255.0 | 192.168.1.53 |
| mac-mini-04 | 10.66.2.14 | 255.255.255.0 | 192.168.1.54 |
Или через терминал на каждом узле:
sudo networksetup -setmanual "Thunderbolt Bridge" 10.66.2.11 255.255.255.0
2.4. Проверьте соединение
ping -c 10 10.66.2.12
Ожидаемый результат: 0% потерь, задержка менее 1 мс.
Проверьте пропускную способность:
# На втором узле (сервер):
iperf3 -s
# На первом узле (клиент):
iperf3 -c 10.66.2.12
Первый ping между свежеподключёнными узлами может не пройти — подождите 5–10 секунд. macOS использует Spanning Tree Protocol для предотвращения петель в сети, и ему нужно время на обучение MAC-адресов.
Шаг 3 — Включаем RDMA (macOS 26.2+)
RDMA снижает задержку обмена данными между узлами с 300 микросекунд до 3–14. Если у вас macOS старше 26.2 или Mac Mini без Thunderbolt 5 — пропустите этот шаг. Кластер будет работать через TCP/IP, но медленнее.
3.1. Включите RDMA в Recovery Mode
Это нужно сделать физически на каждом Mac. Удалённо через SSH не получится.
- Полностью выключите Mac
- Зажмите кнопку питания на 10 секунд до появления меню загрузки
- Выберите Options > Continue
- В Recovery Mode: Utilities > Terminal
- Выполните:
rdma_ctl enable
- Перезагрузитесь в обычный macOS
3.2. Проверьте, что RDMA включён
rdma_ctl status
ibv_devices
Команда ibv_devices должна показать интерфейсы rdma_en2, rdma_en3, rdma_en4 — по одному на каждый порт Thunderbolt.
3.3. Удалите Thunderbolt Bridge и настройте интерфейсы
RDMA и Thunderbolt Bridge — взаимоисключающие режимы. Нужно удалить Bridge и назначить IP каждому порту отдельно.
- System Settings > Network > удалите Thunderbolt Bridge
- Для каждого Thunderbolt-порта (en2, en3, en4): Add Service > выберите интерфейс
- Назначьте каждому IP через DHCP или вручную
Проверьте, что каждый интерфейс получил IP:
ifconfig en2
ifconfig en3
ifconfig en4
Если интерфейсы показывают status: inactive без IP-адресов, RDMA не заработает. Типичная ошибка: [jaccl] Changing queue pair to RTR failed with errno 22 — это значит, что интерфейсам не назначены адреса.
Шаг 4 — Установка фреймворка распределённого инференса
4.1. Установите зависимости на каждом узле
# Homebrew (если ещё нет)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# uv и Node.js
brew install uv node
# Rust (nightly toolchain)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup toolchain install nightly
4.2. Клонируйте и соберите фреймворк
git clone https://github.com/exo-explore/exo.git
cd exo
uv sync --all-packages
# Соберите веб-панель управления
cd dashboard && npm install && npm run build && cd ..
# Оптимизируйте под Apple Silicon GPU
./configure_mlx.sh
4.3. Проверьте запуск
uv run exo
В терминале должно появиться сообщение о запуске и адрес веб-панели — http://localhost:52415.
Шаг 5 — Запуск кластера и первый запрос
5.1. Запустите фреймворк на каждом узле
На каждом Mac Mini:
cd exo
uv run exo
Фреймворк использует mDNS для автоматического обнаружения соседних узлов. Никакой ручной регистрации не требуется — узлы найдут друг друга сами.
5.2. Проверьте состояние кластера
curl -sS http://localhost:52415/state | python3 -m json.tool
В ответе вы увидите все узлы кластера, их память и доступные ресурсы.
5.3. Скачайте модель
Откройте веб-панель http://localhost:52415 в браузере или используйте API:
curl "http://localhost:52415/models?status=downloaded"
Для скачивания модели — выберите её в веб-панели или создайте инстанс:
curl -X POST http://localhost:52415/instance \
-H "Content-Type: application/json" \
-d '{"model_id": "llama-3.2-1b", "sharding": "Pipeline"}'
Модель автоматически распределится между узлами пропорционально их памяти.
5.4. Отправьте первый запрос
curl -N -X POST http://localhost:52415/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.2-1b",
"messages": [
{"role": "user", "content": "Что такое unified memory в Apple Silicon?"}
],
"stream": true
}'
5.5. Совместимые API
Фреймворк предоставляет сразу несколько API-эндпоинтов:
| Эндпоинт | Совместимость |
|---|---|
/v1/chat/completions | OpenAI SDK |
/v1/messages | Anthropic SDK |
/v1/responses | OpenAI Responses API |
Это значит, что любое приложение, которое работает с API OpenAI или Anthropic, можно перенаправить на ваш локальный кластер — достаточно заменить URL на http://10.66.2.11:52415.
Шаг 6 — Проверяем что всё работает: бенчмарки и мониторинг
6.1. Бенчмарк скорости генерации
uv run bench/exo_bench.py \
--model mlx-community/1B-Instruct-4bit \
--pp 128,256,512 \
--tg 128,256
6.2. Мониторинг температуры и памяти
# Температура и частоты
sudo powermetrics -n 1
# Использование памяти
vm_stat
# Пропускная способность между узлами
iperf3 -c 10.66.2.12
6.3. Логи фреймворка
tail -f ~/.exo/exo_log/exo.log
Типичные ошибки и как их решить
1. Узлы не видят друг друга
Симптом: в веб-панели отображается только один узел.
Решение: проверьте, что файервол не блокирует UDP-порт 8888 (используется для mDNS-обнаружения). Проверьте статус файервола:
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
2. Фреймворк выбирает Ethernet вместо Thunderbolt
Симптом: скорость генерации значительно ниже ожидаемой.
Решение: измените приоритет сетевых интерфейсов. System Settings > Network > перетащите Thunderbolt Bridge выше Ethernet в списке сервисов. Фреймворк выберет интерфейс с наибольшим приоритетом.
3. Обычный USB-C кабель вместо Thunderbolt
Симптом: Thunderbolt Bridge не появляется в настройках сети.
Решение: замените кабель. Ищите значок молнии на разъёме. Обычный кабель для зарядки не подойдёт.
4. Передние порты вместо задних
Симптом: соединение работает, но со скоростью USB 3 (~5 Гбит/с).
Решение: подключайте кабели только к трём портам на задней панели. Два передних порта — USB 3, не Thunderbolt.
5. Mac засыпает через несколько часов
Симптом: узел пропадает из кластера ночью или в выходные.
Решение: убедитесь, что выполнены все команды pmset из шага 1.3. Проверьте текущие настройки:
pmset -g
6. RDMA не работает: errno 22
Симптом: ошибка [jaccl] Changing queue pair to RTR failed with errno 22.
Решение: каждому RDMA-интерфейсу (en2, en3, en4) нужен IP-адрес. Проверьте ifconfig en2 — если нет строки inet, назначьте адрес.
7. FileVault блокирует SSH после перезагрузки
Симптом: после сбоя питания SSH недоступен до ручного ввода пароля на физическом экране.
Решение: отключите FileVault для серверных узлов или обеспечьте физический доступ.
8. Модель не помещается в память
Симптом: ошибка загрузки модели или экстремально низкая скорость (1–2 tok/s).
Решение: проверьте суммарную память кластера. Модель в 4-bit квантизации требует примерно 0,5 ГБ на миллиард параметров. Для 70B — минимум 35 ГБ, для 235B — минимум 120 ГБ.
9. Jumbo frames не работают
Симптом: попытка включить MTU 9000 на Thunderbolt Bridge не даёт эффекта.
Решение: Thunderbolt Bridge фиксированно работает с MTU 1500. Jumbo frames не поддерживаются — это ограничение macOS.
10. Все версии macOS должны совпадать
Симптом: RDMA работает между двумя узлами, но не между всеми четырьмя.
Решение: проверьте sw_vers на каждом узле. Для RDMA все Mac должны работать на одной версии macOS.
Что дальше
Кластер работает. Модель отвечает. Вот что имеет смысл сделать следующим шагом:
Автоматизация. Ansible позволяет применить все настройки из шагов 1–4 на десяток узлов одной командой (кроме RDMA — он требует физического доступа к Recovery Mode).
Мониторинг. Настройте оповещения о недоступности узлов, температуре выше 95 градусов и загрузке памяти выше 90%.
Изоляция кластеров. Если в сети несколько кластеров, используйте переменную окружения EXO_LIBP2P_NAMESPACE — она изолирует группы узлов друг от друга.
Безопасность. По умолчанию API-эндпоинт открыт без аутентификации. Для продакшн-среды настройте reverse proxy с TLS и авторизацией.
Четыре Mac Mini, четыре кабеля, полчаса настройки — и у вас локальный ИИ-сервер, который запускает модели, недоступные даже топовым видеокартам NVIDIA.
Не хотите настраивать сами? Закажите готовую ферму с настройкой — от покупки до работающего кластера.
Источники
- Exo — фреймворк распределённого инференса (GitHub)
- Apple TN3205 — RDMA через Thunderbolt (документация)
- Jeff Geerling — кластер из 4 Mac Studio с RDMA
- MEWR Creative — Mac Mini AI Cluster Guide (англ.)
- Twocanoes — схема портов Mac Mini M4 (англ.)
- Stabilise.io — революция RDMA от Apple (англ.)
- Pawel Oljasz — гибридный кластер Mac Mini (англ.)
- MLX Distributed — документация Apple (англ.)