ADG Оставить заявку
Блог Данные и аналитика 5 мин чтения

GPU-кластер для инференса LLM на отечественных серверах: архитектура, bottleneck'и и реальные цифры

Запустили первый production GPU-кластер на отечественных серверах под инференс LLM: делимся архитектурой, узкими местами и тем, что намерили в реальной нагрузке.

Контекст момента

Рост спроса на локальные GPU-кластеры для инференса LLM в корпоративном секторе в H1 2025

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

Железо и отправная точка

Под задачу выбрали серверы на базе отечественных материнских плат - не буду называть конкретного вендора, скажу только, что это была не розничная сборка, а поставка через интегратора с соответствующей документацией для КИИ. GPU - NVIDIA A100 80GB, по четыре карты на узел, три узла в кластере. Да, GPU не отечественный - пока альтернатив под такую задачу с нужными характеристиками по fp16-производительности на рынке нет, берём что есть.

Сеть между узлами - 25GbE на первом этапе, без InfiniBand. Это первое место, где мы наступили на грабли, - но об этом дальше.

Стек и оркестрация

Под инференс выбрали vLLM - на момент запуска это наиболее зрелое решение с поддержкой PagedAttention и continuous batching. Поверх - Kubernetes 1.33 с поддержкой GPU через NVIDIA device plugin. Оркестрацию развернули на Deckhouse, как и на других наших кластерах.

Схема упрощённо выглядит так:

клиент -> nginx (балансировщик) -> vLLM serving pods -> GPU workers

Модели хранятся на локальном S3-совместимом хранилище (Ceph) и монтируются в поды при старте. Это добавляет задержку при холодном старте пода - загрузка модели на 70B занимает несколько минут, - поэтому под production-модели поды не скейлятся в ноль.

Автоматизацию инфраструктуры через AWX уже описывали в посте про AWX 25, кластер вписался в тот же подход с Execution Environments.

Где оказались реальные bottleneck'и

Первое - память, не вычисления. Интуитивно кажется, что GPU-кластер будет упираться в FLOPS. На деле при инференсе главный ресурс - HBM-память. 70B-модель в fp16 занимает примерно 140 ГБ только для весов, плюс KV-cache под активные сессии. Четыре A100 по 80 ГБ - 320 ГБ суммарно, и это уже не так просторно, как кажется при планировании. Модели меньшего размера (13B, 34B) умещаются удобнее, там KV-cache получает ощутимо больше места.

Второе - сеть между узлами при tensor parallelism. Когда модель не помещается в GPU одного узла и нужно раскидывать слои по нескольким картам разных серверов (pipeline или tensor parallelism) - 25GbE становится узким горлом. Задержки на межузловой коммуникации начинают ощутимо влиять на время ответа. Мы это видели на 70B с tensor_parallel_size=8 поверх двух узлов: latency первого токена заметно выросла по сравнению с конфигурацией, где всё умещается на одном узле. Вывод: если есть возможность - берите InfiniBand или хотя бы 100GbE для межузловых линков под такие задачи. Экономия на сети отыгрывается неудобством потом.

Третье - прогрев KV-cache. vLLM реализует PagedAttention, который хорошо работает при повторяющихся prefix-последовательностях. У заказчика оказалась типичная RAG-архитектура: системный промпт + документ + вопрос пользователя. Системный промпт один и тот же почти всегда. После того как включили prefix caching в vLLM, время до первого токена на повторных запросах с тем же системным промптом упало существенно - кэш начинает работать уже через несколько минут после старта под реальной нагрузкой.

Четвёртое - мониторинг GPU. Стандартный Prometheus + Grafana работает, но NVIDIA DCGM exporter на отечественных серверах потребовал возни с драйверами и версиями CUDA. Не всё встало из коробки - пришлось чинить совместимость. Зато когда заработало - метрики нормальные: gpu_utilization, memory_used, sm_active, nvlink_bandwidth.

Что по производительности

Без конкретных цифр конкретного заказчика (NDA), но порядки такие: на задаче суммаризации документов средней длины с моделью ~34B на двух A100 получаем десятки токенов в секунду на запрос при умеренной конкурентности. При росте числа одновременных пользователей throughput растёт до определённой точки, потом упирается в память и KV-cache. Continuous batching vLLM здесь реально помогает - пропускная способность при batched-режиме заметно лучше, чем при naive подходе по одному запросу.

Отечественные серверы: что было неожиданным

Сами серверы по стабильности претензий не вызвали - железо работает. Неожиданности были в другом. Документация от вендора на русском и местами неполная - некоторые BIOS-параметры, критичные для производительности GPU (PCIe Gen5, NUMA topology), пришлось выяснять опытным путём и через поддержку. Драйвера тоже потребовали внимания: не все версии NVIDIA driver проходили без проблем на конкретных версиях ядра, которые поставляются с сертифицированной ОС заказчика.

В целом - работаемо, но без опыта с Linux-серверами под GPU-задачи первый запуск занял бы значительно больше времени.

Где находимся сейчас

Кластер работает в production несколько недель, заказчик гоняет через него свою RAG-систему. Следующий шаг - добавить автоматическое масштабирование на уровне vLLM реплик в зависимости от очереди запросов и поработать над cold start при добавлении новых моделей (снизить время загрузки за счёт предзагрузки весов в RAM).

Если вас интересует похожая задача - запуск LLM-инференса на своём железе в рамках managed-сопровождения - мы готовы обсудить архитектуру под ваши требования.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.