- BrainTools - https://www.braintools.ru -

Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели

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

Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 1

Начну с того, какие ИИ-инструменты мы в YADRO разрабатываем в помощь коллегам:

  • сервис транскрибации и конспектирования встреч,

  • ассистент для написания кода,

  • умный поиск по внутренней документации,

  • автоматизированная техническая поддержка,

  • прямые чаты с моделями для выполнения различных задач.

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

Модели в кластере и взаимодействие с ними

В кластере мы развернули следующие LLM.

Модель

Размер контекста в токенах

Сфера применения

DeepSeek-R1-Distill-Qwen-32B

128k

– автоматизация техподдержки
– чат-бот для разных задач

Qwen2.5-32B-Instruct

128k*

– суммаризация митингов
– чат-бот для разных задач

Qwen2.5-Coder-32B-Instruct

32k

– чат-бот для ассистента по написанию кода

Qwen2.5-Coder-7B-Instruct

32k

– автодополнения для ассистента по написанию кода

T-lite-it-1.0

32k

– чат-бот для разных задач

T-pro-it-1.0

128k*

– суммаризация митингов
– чат-бот для разных задач

multilingual-e5-large

512

– эмбеддинги для поиска по векторной БД общего содержания

bge-m3

8k

– эмбеддинги для поиска по векторной БД общего содержания

nomic-embed-text-v1

8k

– эмбеддинги поиска по векторной БД для ассистента по написанию кода

bge-reranker-v2-m3

8k

– ранжирование результатов поиска по векторной БД

* Размер контекста модели увеличен с 32k до 128k с помощью YARN в настройках запуска инференс-сервера

В контуре YADRO с моделями можно работать через веб-оболочки. Пообщаться с некоторыми в режиме диалога — на «LLM-арене» на базе платформы Open WebUI [2]. Для продвинутых пользователей развернут сервис Dify [3], где можно создавать свои приложения в визуальном редакторе. Разработчики могут использовать модели через код-ассистент Continue.Dev [4], доступный как плагин для VS Code с нашим кастомизированным конфигом.

Сервисы взаимодействуют с кластером через стандартный OpenAI-подобный REST API. Вот пример эндпойнта для работы с LLM:

Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 2

Через него можно посылать сырые запросы в наш кластер. Либо использовать библиотеки, предоставляющие более удобные API для взаимодействия с LLM, — OpenAI SDK [5] или LiteLLM [6].

Архитектура кластера

LLM инференс-кластер работает на общей MLOps инфраструктуре компании и представляет собой набор сервисов в Kubernetes. Аппаратная основа кластера — ноды с GPU NVIDIA: RTX 4090 для легких и H100 для более тяжелых моделей.

Для запуска и инференса моделей мы используем популярный, активно разрабатываемый фреймворк vLLM [7] с открытым исходным кодом и большим комьюнити. Фреймворк поддерживает мультимодальные модели, модели с рассуждением, включает много разных техник оптимизации LLM и вообще очень функционален. При этом, что немаловажно, vLLM прост в использовании по сравнению с некоторыми аналогами, не требует конвертации модели в свой формат, а читает их напрямую в формате Hugging Face. Это облегчает развертывание моделей. Фреймворк умеет работать с GPU не только NVIDIA, но и других производителей — пока нам это не нужно, но в перспективе может пригодиться.

Модели мы стараемся запускать при точности FP8, если аккуратность в наших задачах нас устраивает. Используем либо готовые квантованные версии с Hugging Face (например, из репозитория RedHatAI [8]), либо динамическую квантизацию vLLM [9]. Так мы достигаем компромисса между качеством и скоростью работы, а также экономим память [10], чтобы запускать на доступном железе больше инстансов моделей. Некоторые небольшие модели работают на одном GPU, более крупные запускаются на двух или на четырех в режиме tensor parallel inference. Последний вариант используется на серверах с NVIDIA H100, связанных через NVLink, что обеспечивает эффективный обмен данными между видеокартами. Модели с Hugging Face мы заранее скачиваем во внутреннее хранилище, откуда их уже загружают vLLM-сервера.

Второй компонент инференс-кластера – это сервер LLM Gateway на базе прокси-сервера LiteLLM [11]. На него возложено несколько задач:

  • Сбор информации по всем запущенным инференс-серверам: каждый инстанс vLLM отвечает за одну модель.

  • Роутинг и проксирование запросов от вызывающих сервисов к серверам моделей.

  • Унифицированный API для вызывающих сервисов.

  • Контроль доступа по API-ключам. 

В кластере предусмотрено и масштабирование: часть моделей, в том числе для код-ассистентов, имеет заранее установленное число запущенных инстансов. Мы подбирали его на основе требований по масштабированию и результатов бенчмаркинга.

Для остальных моделей число инстансов определяется автоматически — в Kubernetes это называется horizontal pod autoscaling [12]. Автоматическое масштабирование инференс-серверов моделей ориентируется на метрику загрузки GPU, а масштабирование сервера LLM Gateway — на загрузку процессора.

Запуск новых инстансов сервером vLLM занимает некоторое время, так как серверу нужно загрузить большой объем весов в память GPU и сконвертировать модель во внутреннее представление. Именно по этой причине для особо критичных моделей мы используем статически заданное число инстансов — чтобы при увеличении нагрузки не тратить время на развертывание новых серверов. 

Мониторинг кластера

Для мониторинга доступности моделей настроены сторожевые таймеры (watchdogs), причем на сервисах поверх инференс-кластера. Доступность всех инстансов LLM по времени, их метрики [13] и нагрузку на оборудование мы отслеживаем с помощью Grafana. Валидация аккуратности именно на уровне инференс-кластера сейчас не предусмотрена — она работает на базе приложений, которые используют кластер (RAG-пайплайн, сервис суммаризации и т. д.).

Трудности и альтернативные решения

Расскажу про некоторые трудности, с которыми мы столкнулись, а также об альтернативных технологиях, которые мы использовали раньше или рассматриваем на будущее.

До фреймворка vLLM мы использовали NVIDIA Triton в паре с TensorRT LLM бэкендом. Но перешли на vLLM, потому что с ним оказалось намного проще добавлять новые модели. Да и по стабильности vLLM показал себя лучше: нормально работал под нагрузками там, где связка Triton и TensorRT начинала сбоить и падать. К тому же инференс-сервер vLLM изначально предоставляет OpenAI-совместимые REST API, что упрощает его использование в других продуктах. А инференс-сервер Triton работает с более обобщенным KServe REST API, который сложнее интегрировать в другие продукты.

Не обошлось без проблем и с vLLM: на наших валидационных тестах модель давала неконсистентные ответы даже с нулевой температурой. Оказалось, что это известная особенность vLLM, даже упомянутая в документации. Мы нашли несколько советов, как минимизировать этот эффект: отключать prefix caching опцией –no-enable-prefix-caching и фиксировать random seed опцией –seed. Это помогало при одном запущенном инстансе модели, но при нескольких, даже работающих на одном железе и версии софта, проблема всплывала снова. Также неконсистентность ответов возникает при больших нагрузках — например, когда тесты запускаются одновременно с бенчмарком.

Еще один вызов — это накладные расходы от litellm-proxy и его масштабирование под нагрузками. LLM Gateway, в качестве которого мы используем LiteLLM, превращается в боттлнек кластера, так как все другие сервисы взаимодействуют с кластером именно через него. То есть именно на него идет суммарная нагрузка от всех возможных пользователей, которая потом распределяется между разными моделями и их инференс-серверами.

Эксперименты, о которых я расскажу далее, показали, что начиная с некоторой нагрузки накладные расходы LiteLLM начинают расти почти экспоненциально, причем на каждый генерируемый токен. Это приводит к существенному замедлению ответа модели. Пока мы боремся с этим двумя способами:

  • Минимизация работы litellm-proxy с БД. По умолчанию litellm-proxy логирует в свою базу данных информацию о каждом запросе. Как следствие — неограниченное увеличение размера БД и деградация операций по работе с ней.

  • Увеличение максимального числа запущенных инстансов сервиса.

Кроме того, мы экспериментируем с альтернативными решениями для LLM Gateway — например, с дошедшим в этом году до релиза vLLM Production Stack [14] и входящим в его состав vllm-router [15]. Переход на другое решения для LLM Gateway усложняется тем, что мы изначально стали использовать LiteLLM для авторизации и контроля доступа по ключам. Это сильно привязывает нас к LiteLLM, и сейчас мы рассматриваем вариант переноса этой функциональности на отдельный API Gateway, который будет стоять над LLM Gateway.

Производительность кластера

Для анализа производительности кластера мы используем инструмент бенчмаркинга от vLLM [16]. Результаты ниже были получены на датасете philschmid/mt-bench [17]. В нем собраны небольшие запросы на разные тематики — в среднем около 70 токенов. Ответы модели в среднем занимают около 200 токенов. Графики ниже показывают производительность моделей при различных нагрузках:

Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 3
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 4
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 5
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 6

Теперь сравним работу модели T-lite-it-1.0 [18] при разном числе запущенных инстансов:

Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 7
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 8
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 9
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 10

А на этих графиках — сравнение разных режимов работы LLM Gateway под нагрузками при одном инференс-сервере:

Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 11
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 12
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 13
Где живут LLM: разбираем инференс-кластер YADRO и гоняем в нем модели - 14

Видно, что после определенной нагрузки (более 50 одновременных запросов) четыре инстанса LiteLLM перестают справляться и накладные расходы от них начинают расти. Десять же инстансов с подобной нагрузкой справляются. При этом vllm-router держит подобные нагрузки даже с одним запущенным инстансом.

Выводы

LLM-кластер YADRO начинался с одной небольшой LLM и одной модели эмбеддингов для экспериментов с RAG, запущенных на одном инференс-сервере NVIDIA Triton. Теперь у нас в кластере есть целый набор ИИ-сервисов и моделей под разные задачи. Коллегам интересна наша работа, приходят запросы на добавление новых и обновление существующих моделей. Растет число пользователей и нагрузка на кластер.

Поделюсь важными выводами, которые мы сделали за время развития кластера:

  • Под разные задачи модели нужно сравнивать и внимательно подбирать. Например, для техподдержки в нашем случае DeepSeek-R1-Distill-Qwen-32B показала себя лучше, чем аналоги. В задачах суммаризации митингов отличились модели семейства Qwen (Qwen2.5-32B-Instruct и T-pro-it-1.0). При этом, судя по результатам опросов, лучше справлялась с русским языком T-pro-it-1.0. Что неудивительно, так как под русский язык ее и шлифовали.

  • Важно понимать требования моделей и рассчитывать использование доступных ресурсов с учетом планируемых нагрузок.

  • Необходимо проводить нагрузочное тестирование для анализа пропускной способности кластера и поиска боттлнеков в нем.

  • Нужно четко определить требования к компонентам кластера. Например, использование LLM Gateway для авторизации привязало нас к конкретному решению и затруднило переход на альтернативные.

Надеюсь, наш опыт [19] окажется полезным, если вы решите развертывать подобные решения в своей компании.

Автор: jet-47

Источник [20]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/17782

URLs in this post:

[1] YADRO: https://yadro.com?utm_source=habr&utm_medium=referral&utm_campaign=llm-cluster-300725

[2] Open WebUI: https://openwebui.com/

[3] Dify: https://dify.ai/

[4] Continue.Dev: http://Continue.Dev

[5] OpenAI SDK: https://openai-docs.ru/docs/quickstart

[6] LiteLLM: https://docs.litellm.ai/docs/

[7] фреймворк vLLM: https://docs.vllm.ai/en/latest/

[8] RedHatAI: https://huggingface.co/RedHatAI

[9] динамическую квантизацию vLLM: https://docs.vllm.ai/en/latest/features/quantization/fp8.html#online-dynamic-quantization

[10] память: http://www.braintools.ru/article/4140

[11] прокси-сервера LiteLLM: https://www.litellm.ai/

[12] horizontal pod autoscaling: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

[13] метрики: https://docs.vllm.ai/en/latest/usage/metrics.html

[14] vLLM Production Stack: https://docs.vllm.ai/en/stable/deployment/integrations/production-stack.html

[15] vllm-router: https://docs.vllm.ai/projects/production-stack/en/latest/dev_guide/dev_api/router-logic.html

[16] инструмент бенчмаркинга от vLLM: https://github.com/vllm-project/vllm/blob/main/benchmarks/benchmark_serving.py

[17] philschmid/mt-bench: https://huggingface.co/datasets/philschmid/mt-bench

[18] T-lite-it-1.0: https://huggingface.co/t-tech/T-lite-it-1.0

[19] опыт: http://www.braintools.ru/article/6952

[20] Источник: https://habr.com/ru/companies/yadro/articles/930304/?utm_source=habrahabr&utm_medium=rss&utm_campaign=930304

www.BrainTools.ru

Rambler's Top100