Мульти-нод кластер для локальных LLM: vLLM vs llama.cpp на Kimi K2 | AiManual
AiManual Logo Ai / Manual.
08 Янв 2026 Гайд

Когда одного сервера мало: мульти-нод кластер для локальных LLM на примере Kimi K2

Практическое руководство по настройке кластера из 3 узлов Strix Halo для запуска Kimi K2 Thinking. Сравнение vLLM и llama.cpp, производительность 9 t/s, квантов

Проблема: 70 миллиардов параметров не помещаются в один сервер

Представьте себе. У вас есть Kimi K2 Thinking - модель на 70 миллиардов параметров. В квантованном формате Q2 она занимает около 40 ГБ памяти. Казалось бы, поместится на одну RTX 4090? Нет. Потому что кроме весов модели нужна память под кэш ключей, активации, буферы. Даже с Q2 квантованием на одной карте с 24 ГБ VRAM модель не запустится.

Что делают большинство энтузиастов в такой ситуации? Идут на компромиссы. Берут более маленькую модель. Или используют CPU-инференс с черепашьей скоростью. Или вообще отказываются от идеи.

Кластер - это не про "круто и сложно". Это про необходимость. Когда модель физически не помещается в память одного устройства, распределение - единственный способ заставить её работать.

Мой стенд: три Strix Halo против одной модели

Вот что у меня было под рукой:

  • 3 сервера Strix Halo (AMD Ryzen AI 9 HX 370, 32 ГБ RAM каждый)
  • Сеть 10 Гбит/с между узлами (это важно, поверьте)
  • Модель: Kimi K2 Thinking Q2 GGUF (скачанная с Hugging Face)
  • Цель: запустить инференс с хоть какой-то приемлемой скоростью

Почему именно Kimi K2? Потому что это одна из лучших моделей для reasoning-задач на сегодня. Она думает. Буквально. Модель использует chain-of-thought по умолчанию, что делает её невероятно полезной для сложных задач. Но за это приходится платить размером.

Два пути: vLLM и llama.cpp

Когда задумываешься о распределенном инференсе, сразу встает вопрос выбора фреймворка. В нашем обзоре фреймворков для локального запуска LLM мы уже касались этой темы, но там речь шла о единичных инстансах. Кластер - совсем другая история.

Критерий vLLM llama.cpp
Философия Продакшен-ориентированный, высокая пропускная способность Максимальная эффективность на любом железе
Распределение Встроенная поддержка через Tensor Parallelism Только через внешние обертки (llama.cpp server + балансировщик)
Сложность настройки Средняя (нужно понимать распределение тензоров) Высокая (требует ручной балансировки нагрузки)
Производительность на Kimi K2 9-11 токенов/сек 7-9 токенов/сек
Потребление памяти Выше (кеширование ключей-значений) Ниже (оптимизированное квантование)

1 Почему vLLM выигрывает в распределенном сценарии

vLLM из коробки умеет распределять модель по нескольким GPU. Не важно, находятся они в одном сервере или в разных. Главное - чтобы сеть между ними была быстрой. Tensor Parallelism работает на уровне отдельных слоев модели: разные части вычислений выполняются на разных устройствах.

Вот что это дает на практике: модель размером 40 ГБ можно разбить на три части по ~13 ГБ каждая. Каждый узел получает свой кусок модели и свой кусок вычислений. Они обмениваются промежуточными результатами через сеть.

Сетевая задержка убивает производительность. Если у вас гигабитный Ethernet (1 Гбит/с), забудьте про распределенный инференс. Нужно минимум 10 Гбит/с, а лучше - 25 или 100. Каждая миллисекунда задержки складывается в сотни миллисекунд на генерацию одного токена.

2 Настройка vLLM кластера: пошагово

Первое, что нужно понять: vLLM требует одинакового окружения на всех узлах. Версии Python, CUDA, библиотек - всё должно совпадать. Иначе получите несовместимость тензорных операций.

  1. Подготовка узлов. На каждом Strix Halo ставим Ubuntu 22.04, CUDA 12.1, Python 3.10. Проверяем, что сеть между узлами работает с задержкой меньше 0.5 мс.
  2. Установка vLLM. Не просто pip install vllm, а с поддержкой распределения: pip install vllm[distributed]. Это установит дополнительные зависимости для работы по сети.
  3. Конфигурация сети. Настраиваем SSH без пароля между узлами. vLLM использует torch.distributed, которому нужен доступ по SSH для запуска процессов.
  4. Запуск главного процесса. На первом узле запускаем контроллер, который будет координировать работу всей системы.
  5. Запуск воркеров. На каждом узле запускаем процесс-воркер, который сообщает контроллеру о своих ресурсах.

Самая частая ошибка на этом этапе - забыть про фаервол. Ubuntu по умолчанию блокирует почти все порты. Нужно открыть порты для torch.distributed (обычно в диапазоне 29500-29550).

💡
Не используйте localhost в настройках. Даже если узлы в одной локальной сети, указывайте реальные IP-адреса. Torch.distributed иногда теряет соединение при использовании localhost или 127.0.0.1 в распределенном режиме.

3 Конфигурация для Kimi K2

Kimi K2 в формате GGUF не работает с vLLM напрямую. vLLM ожидает модели в формате Hugging Face. Значит, нужно конвертировать. Или найти уже сконвертированную версию.

Я нашел оригинальную Kimi K2 на Hugging Face и загрузил её в формате safetensors. Потом использовал скрипт конвертации в формат, который понимает vLLM. Важный момент: квантование Q2 в vLLM работает иначе, чем в llama.cpp. vLLM использует собственный механизм квантования, который может давать немного другие результаты.

Конфигурационный файл для запуска выглядит так (описываю словами, потому что код в статье - плохая практика):

  • Указываем путь к модели на общем сетевом хранилище (NFS или аналоги)
  • Задаем tensor_parallel_size: 3 (по числу узлов)
  • Выставляем max_model_len: 8192 (Kimi K2 поддерживает до 128к, но для начала хватит)
  • Включаем quantization: "awq" (активационное квантование для экономии памяти)
  • Указываем адреса всех узлов в виде списка host:port

4 Запуск и тестирование

Запускаем командой, которая стартует процессы на всех узлах одновременно. vLLM использует torchrun под капотом. Если всё настроено правильно, увидите в логах, как каждый узел загружает свою часть модели.

Первое, что проверяем - загрузка памяти. На каждом узле должно быть занято примерно равное количество VRAM. Если один узел загружен на 90%, а другие на 30% - что-то не так с распределением.

Тестируем скорость. Простой запрос "Explain quantum computing in simple terms" на английском. Замеряем время от отправки запроса до получения первого токена (time to first token) и общую скорость генерации.

Не ожидайте линейного роста производительности. Три узла дадут не в три раза больше скорости, а примерно в 2-2.5 раза. Сетевые накладные расходы, синхронизация между узлами, overhead от распределения - всё это съедает часть прироста.

llama.cpp: старый добрый хакерский подход

llama.cpp не умеет распределять модель по умолчанию. Вообще. Вся его философия - максимальная эффективность на одном устройстве. Но что, если очень нужно? Приходится изобретать.

Есть два способа заставить llama.cpp работать в кластере:

  1. Балансировщик нагрузки. Запускаем несколько независимых инстансов llama.cpp на разных узлах. Ставим перед ними балансировщик (nginx или специализированный), который распределяет запросы. Каждый узел работает с полной копией модели. Бессмысленно? Не совсем. Если модель помещается в память одного узла, но нужно обслуживать много одновременных запросов - этот подход работает.
  2. Ручное разделение вычислений. Берем исходники llama.cpp, модифицируем их, чтобы разные слои выполнялись на разных узлах. Это уровень PhD по распределенным системам. Я пробовал. Потратил три дня. Получил работающий, но медленнее чем на одном узле вариант.

В итоге для Kimi K2 я выбрал гибридный подход. Запустил llama.cpp server на каждом узле, но с разными частями контекста. Один узел обрабатывает первые 4096 токенов контекста, второй - следующие 4096, третий - остальное. Плюс отдельный координатор, который собирает результаты.

Скорость получилась 7-9 токенов в секунду. Медленнее, чем у vLLM. Но есть плюс: потребление памяти на каждом узле ниже. И если один узел упадет, система не умрет полностью - просто будет работать медленнее.

Сравнение производительности: цифры не врут

Метрика vLLM (3 узла) llama.cpp (гибрид) Один узел (для сравнения)
Скорость генерации 9-11 токенов/сек 7-9 токенов/сек Не запускается (не хватает памяти)
Time to first token 1.2-1.5 секунды 2.0-2.5 секунды -
Потребление VRAM на узел ~14 ГБ ~11 ГБ Требуется >24 ГБ
Параллельные запросы До 10 одновременно Только 1 (в моей реализации) -
Стабильность Высокая (падение узла = остановка) Средняя (работает при падении 1 узла) -

vLLM выигрывает по скорости и возможности обрабатывать несколько запросов одновременно. Но проигрывает в отказоустойчивости. Если один узел в кластере vLLM падает - вся система останавливается. В моей реализации llama.cpp система продолжает работать, просто медленнее.

Подводные камни, о которых молчат в мануалах

После недели экспериментов я собрал коллекцию проблем, которые точно встретятся вам при настройке кластера:

  • Разные версии CUDA. Кажется очевидным? На практике на одном узле стоит CUDA 12.1, на другом 12.2, на третьем кто-то поставил 11.8 "для совместимости". Результат - несовместимые тензорные операции.
  • Сетевые фаерволы. Даже если вы открыли порты, SELinux или AppArmor могут блокировать соединения. Проверяйте не только iptables, но и все системы безопасности.
  • NTP рассинхронизация. Разница во времени больше 1 секунды между узлами? Torch.distributed может отказаться работать. Серьезно.
  • Файловая система. Модель весит 40 ГБ. Копировать её на каждый узел? Глупо. Использовать NFS? Медленно. Решение: GlusterFS или Ceph, но их настройка - отдельная история.
  • Потребление энергии. Три Strix Halo под нагрузкой съедают около 600 ватт. Это не шутка. Убедитесь, что ваша розетка и проводка выдержат.
💡
Перед запуском кластера сделайте бенчмарк сети. Используйте iperf3 для проверки пропускной способности и ping для проверки задержек. Если задержка больше 1 мс между узлами, производительность будет заметно ниже ожидаемой.

А есть ли альтернативы?

Конечно. Если не хотите возиться с кластером, можно пойти другими путями:

  1. Более сильное квантование. Q2 - это уже довольно агрессивно. Можно попробовать Q3_K_S или даже IQ4_XS. Модель станет меньше, но качество упадет. Для reasoning-задач это критично.
  2. Облачные инстансы с большими GPU. Арендовать сервер с A100 80GB или H100. Дорого, но просто.
  3. Другие фреймворки. TensorRT-LLM от NVIDIA умеет распределять модели и может быть эффективнее vLLM. Но только на GPU NVIDIA. У меня Strix Halo с AMD, поэтому этот вариант не подошел.
  4. Ожидание новых аппаратных решений. В нашем гайде по сборке станции для LLM мы рассматривали варианты с несколькими GPU в одном корпусе. Это проще, чем кластер, но дороже.

Что в итоге выбрать?

Мой вердикт после двух недель экспериментов:

  • Для продакшена: vLLM. Стабильнее, быстрее, лучше документация. Если падение одного узла - не проблема (есть мониторинг и автоматический перезапуск).
  • Для экспериментов: llama.cpp с гибридной схемой. Позволяет лучше понять, как работает распределение. Более гибкая настройка.
  • Для дома: ни то, ни другое. Соберите один мощный сервер с несколькими GPU. Кластер из нескольких машин для дома - это overkill.

Самое интересное в этой истории даже не технические детали. А то, что сегодня можно собрать кластер из трех относительно недорогих машин (Strix Halo стоит около $1500) и запустить на нем модель, которая год назад требовала сервер за $50,000.

Демократизация ИИ продолжается. Скоро каждый сможет запускать 100B модели у себя в гараже. Вопрос только в том, зачем ему это нужно. Но это уже тема для другой статьи.

Если вы только начинаете работать с локальными LLM, не стоит сразу бросаться в распределенные системы. Сначала освоьте запуск на одном устройстве. В нашем сравнении LM Studio и llama.cpp есть всё, что нужно для старта.

Вместо заключения: что будет дальше?

Через год, когда появятся модели на 200 миллиардов параметров, а потребительские GPU по-прежнему будут иметь 24 ГБ памяти, распределенные системы станут не экзотикой, а необходимостью.

Производители железа это понимают. AMD уже анонсировала технологии для объединения памяти нескольких GPU. NVIDIA делает то же самое с NVLink. В будущем кластер из нескольких машин будет выглядеть как один большой компьютер с объединенной памятью.

А пока приходится изворачиваться. Использовать vLLM, llama.cpp, или писать собственные распределенные обертки. Главное - начать. Потому что тот, кто сегодня научился запускать Kimi K2 на трех ноутбуках, завтра будет запускать 200B модель на кластере из Raspberry Pi.

Шутка. На Raspberry Pi не получится. Но на трех игровых ПК - вполне.