Привет, Хабр! Меня зовут Данила Гудынин, я DevOps-инженер направления Evolution ML Inference в Cloud.ru. В мире машинного обучения GPU — главный актив, но что делать, когда ваши дорогостоящие видеокарты используются всего на 50%? Мы у себя столкнулись именно с такой проблемой и, чтобы наши клиенты не платили за простаивающие ресурсы, разработали собственную технологию виртуализации GPU.

В этой статье пробежимся по верхам и расскажем, какие подходы рассматривали, и что в итоге позволило нам даже в условиях очень дорогого железа снизить цены до уровня западных облаков без просадки в производительности. А во второй части, которую опубликуем позже для тех, кто готов к глубокому погружению в оптимизацию GPU, мы поделимся готовыми алгоритмами для каждого из способов оптимизации и дадим «списать» немножко кода. Можете подписаться, чтобы не пропустить.

А в чем проблема?

Анализ существующих решений

SMS vs MMS: краткое сравнение

Технологии NVIDIA и их ограничения

Программные фреймворки (Model Mesh, vLLM Production)

Наш подход — Cloud.ru Shared GPU

Выводы и планы

А в чем проблема?

Представьте себе ситуацию: у вас есть топовый графический процессор GPU H100 за 30 000 долларов, вы запускаете на нем модель, карта обрабатывает тысячи запросов в секунду — все довольны. Но есть нюанс — GPU простаивает на 90%. Модель использует 8 ГБ из 80 ГБ доступной памяти, остальные 72 ГБ просто не используются. В итоге платили вы за полную мощность, а получаете копейки от реальных возможностей железа — несправедливо! А если вы при этом провайдер, то вы еще и упускаете прибыли, ведь карта могла бы обрабатывать нужды еще 10 клиентов. 

Мы проанализировали использование GPU у наших клиентов и вот результаты:

Смотреть результаты
  • 96% компаний используют меньше 50% GPU

  • Средняя утилизация составляет всего 23%

  • Потери бюджета на неиспользуемые ресурсы — до 77%

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

Анализ существующих решений

Model Serving — это процесс развертывания обученных ML-моделей в прод для обработки реальных запросов. Звучит просто, но на деле это самый коварный этап в жизни любой модели.

На практике это выглядит так: Data Scientist обучил модель в Jupyter, показал красивые метрики валидации, сказал: «Ну вот, модель готова!» и… тут начинается веселье. Как это теперь запустить в проде так, чтобы оно работало 24 часа в сутки, 7 дней в неделю, не падало и не съедало весь бюджет на GPU?

SMS vs MMS: краткое сравнение

Жизненный цикл ML-модели
Жизненный цикл ML-модели

В мире ML идет непрекращающаяся война между двумя философами. И от того, какую сторону вы выберете, зависит не только архитектура системы, но и ваш сон в последующие месяцы.

Как выглядит главная дихотомия в мире Model Serving
Как выглядит главная дихотомия в мире Model Serving

Обслуживание одной модели (SMS): классический подход

При таком подходе каждая модель получает персональную виллу с собственным бассейном (GPU), даже если плавать не умеет.

Плюсы SMS:

  • Предсказуемость: каждая модель имеет гарантированные ресурсы.

  • Простота отладки: легко определить источник проблем.

  • Полная изоляция: сбой одной модели не влияет на другие.

  • Простое масштабирование: добавляем реплики по мере необходимости.

  • Безопасность: модели не могут влиять друг на друга.

Минусы SMS:

  • Неэффективное использование ресурсов: GPU может простаивать 70-90% времени.

  • Высокая стоимость: каждая модель требует отдельных ресурсов.

  • Фрагментация памяти: маленькие модели не могут объединить ресурсы.

  • Холодный старт: каждая реплика требует времени на инициализацию.

Мультимодальное обслуживание (MMS): оптимизированный подход

Эта концепция похожа на коммунальную квартиру для моделей. Все живут вместе, делят общую ванную (GPU), иногда ругаются и стоят в очереди, но зато счета не такие кусачие и ни у кого не возникает вопросов, зачем в этой квартире вообще ванная.

Плюсы MMS:

  • Высокая утилизация ресурсов: GPU используется более эффективно.

  • Экономичность: меньше железа для того же количества моделей.

  • Быстрое масштабирование: новые модели добавляются без выделения новых ресурсов.

  • Адаптивность: система сама оптимизирует размещение моделей.

Минусы MMS:

  • Сложность архитектуры: требует тонкой системы управления.

  • Непредсказуемость производительности: время ответа может варьироваться.

  • Ограниченная изоляция: модели могут влиять друг на друга.

  • Сложная отладка: трудно выявить источник проблем, если что-то пойдет не так. 

Различия в архитектуре SMS и MMS наглядно
Различия в архитектуре SMS и MMS наглядно

Если коротко: SMS проще в эксплуатации, MMS экономичнее. Выбор зависит от ваших приоритетов — стабильность или экономия. Нам как всегда хотелось сильных сторон и от одного, и от другого подходов, а слабых не хотелось вовсе. Мы стали смотреть, а какие пограничные решения уже существуют для контроля утилизации GPU и насколько они похожи на наш светлый идеал. 

Генерально пути оказалось тоже два:

  1. Программные фреймворки. Работают на уровне приложений и оркестрации, перехватывают запросы уже после загрузки моделей в память. Распределяют ресурсы через внутренние шедулеры, которые решают, какую модель куда разместить и когда переместить. Типичные представители: IBM Model Mesh, vLLM Production Stack.

  2. Аппаратно-драйверные решения. Работают на системном уровне — между драйвером и приложением, контролируют доступ к железу еще до того, как приложение получит GPU-ресурсы. Распределяют ресурсы через низкоуровневые механизмы: временные слайсы, физические партиции GPU или виртуальные контексты CUDA. Работают с любыми приложениями универсально. Представители: CUDA Streams, Time Slicing, MPS, MIG, vGPU.

Но не дайте себя обмануть, поскольку работают они на разных уровнях, вопрос не стоит о том, чтобы использовать только одно из двух: эти решения можно и нужно комбинировать вместе на разных уровнях стека. Сам же «слоеный пирог» стека выглядит как-то так: 

Уровень

Что на нем происходит

Категория инструментов

Конкретные примеры

Уровень управления моделями

Определяется где и какие модели запустить, автоматическое размещение и миграция моделей между GPU

Программные фреймворки оркестрации

Model Mesh (IBM), vLLM Production Stack

Уровень серверов инференса

Обработка запросов к моделям, оптимизация вычислений, управление батчингом и кешированием

Inference-серверы и рантаймы

vLLM, Triton Inference Server, TensorRT, ONNX Runtime

Уровень виртуализации GPU

Разделение физических GPU на виртуальные экземпляры, контроль доступа к ресурсам памяти и вычислений

Аппаратно-драйверные решения

MIG, MPS, Time Slicing, vGPU, CUDA Streams

Уровень системного драйвера

Трансляция высокоуровневых команд в низкоуровневые инструкции для GPU, управление контекстами CUDA

Системные драйверы

NVIDIA Driver, CUDA Runtime

Аппаратный уровень

Выполнение вычислений на физических процессорах GPU, управление памятью на кристалле

GPU-оборудование

H100, A100, V100, RTX 4090

Кто-то, например, использует MIG + Model Mesh, а кто-то Time Slicing + vLLM Production. Мы стали изучать, что и в каких компонентах нас устраивает на каждом из уровней, чтобы не просто найти «достаточно хороший» компромисс, а собрать инженерное решение, которое идеально подходило бы конкретно под наши представления о прекрасном и суровые российские реалии. А именно: чтобы эффективность по части экономии ресурсов была как у MMS, простота управления как у SMS, чтобы между моделями можно было обеспечить надежную изоляцию, чтобы все это добро работало без иностранных лицензий и адаптировалось к любым задачам инференса (комбинации типа и размера модели, объема требуемых ресурсов, используемых фреймворков и необходимой заказчику бизнес-модели).

Технологии NVIDIA и их ограничения

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

Увеличивайте картинку, здесь подробно сравнили всё, что предлагает NVidia и пункты, по которым каждое из этих решений нам не подошло
Увеличивайте картинку, здесь подробно сравнили всё, что предлагает NVidia и пункты, по которым каждое из этих решений нам не подошло

CUDA Streams — параллелизм внутри приложения

Уровень: CUDA API / приложение

Метод оптимизации: Асинхронные очереди команд

CUDA Streams позволяют одному приложению параллельно выполнять разные операции на GPU: копирование данных, вычисления и операции с памятью могут происходить одновременно. Это как конвейер на заводе — разные стадии производства идут параллельно, не дожидаясь завершения предыдущих. В ML это полезно для пайплайна «копирование данных → инференс → копирование результатов», где этапы перекрываются во времени. 

Что нам не понравилось: Нет возможности управлять защитой памяти. А отсутствие изоляции памяти между клиентами очень критично для мультитенантной среды — один клиент может случайно повредить данные другого.

Time Slicing — разделение времени GPU

Уровень: NVIDIA драйвер

Метод оптимизации: Временное мультиплексирование

Суть в том, что GPU поочередно переключается между разными процессами через заданные интервалы времени, как старая добрая многозадачность в операционных системах. Каждый процесс получает свою дольку времени для работы с видеокартой. Подходит для задач, которые могут терпеть колебания времени отклика — например, пакетная обработка данных или обучение моделей.

Что нам не понравилось: Для нас как коммерческого облачного провайдера критична простота администрирования и предсказуемость биллинга, а Time Slicing, во-первых, сложен в настройке и мониторинге, а во-вторых, не подходит для real-time инференса, который все-таки нужен для некоторых задач клиентов. 

MPS (Multi-Process Service) — логическое разделение контекстов

Уровень: CUDA runtime / системный демон

Метод оптимизации: Мультиплексирование CUDA-контекстов

MPS создает единого «диспетчера» (MPS-демон), который координирует доступ к GPU от множества клиентских процессов. Вместо того чтобы каждый процесс создавал свой CUDA-контекст, все запросы идут через общий контекст, что снижает накладные расходы. Это как скинуться с друзьями на такси вместо того чтобы покупать машину — эффективнее по ресурсам, но пассажиры влияют друг на друга: сначала того надо завезти домой, потом этого...

Что нам не понравилось: Хотя технически MPS позволяет до 48 партиций, на практике управление большим количеством клиентов через MPS-демон оказалось неудобным. Но сама идея хорошая, запомним ее. 

MIG (Multi-Instance GPU) — аппаратное разделение

Уровень: GPU hardware / firmware

Метод оптимизации: Физическое партиционирование SM-блоков

MIG буквально разрезает мощную GPU (A100/H100) на несколько независимых частей на аппаратном уровне. Каждый раздел получает выделенную память, вычислительные блоки (SM) и пропускную способность. Плюс — полная независимость, минус — ограниченная гибкость в использовании пространства.

Что нам не понравилось: Жесткое ограничение в 7 партиций не покрывает наши потребности — иногда нужно разместить 10+ небольших моделей на одной карте. Ищем дальше. 

vGPU — полная виртуализация GPU

Уровень: Гипервизор / виртуализация

Метод оптимизации: Виртуализация на уровне драйвера и управление ресурсами

Казалось бы, самое очевидное решение: vGPU создает виртуальные GPU для виртуальных машин, где каждая ВМ «думает», что у неё есть собственная видеокарта. Гипервизор динамически распределяет ресурсы физических GPU между виртуальными экземплярами, поддерживает живую миграцию ВМ между хостами и предоставляет детальную телеметрию. Оптимальный баланс изоляции и загрузки. 

Что нам не понравилось: Нам вообще все понравилось. Кроме того, что нужны лицензии NVidia, которые недоступны в России из-за санкционных ограничений.  

Главное, что стоит вынести из этого раздела: чем ниже уровень технологии, тем лучше изоляция, но тем меньше гибкости. У CUDA Streams — максимальная производительность, минимальная изоляция, у vGPU — максимальная изоляция и функциональность, но требует лицензии и больше накладных расходов.

Программные фреймворки (Model Mesh, vLLM Production)

Model Mesh

IBM решила проблему неэффективности GPU посредством создания модели «умного кеша». ModelMesh превращает кластер GPU в распределенный LRU-кеш, где модели автоматически загружаются и выгружаются по мере необходимости. Выглядит блестяще на бумаге, но в реальности все не так радужно. 

Как работает KServe ModelMesh
Как работает KServe ModelMesh

KServe ModelMesh изначально был разработан внутри IBM как проприетарный компонент Watson. Позже компания приняла стратегическое решение открыть исходный код и передать его под крыло сообщества KServe. Это было сделано для ускорения развития технологии, привлечения большего числа контрибьюторов и создания открытого стандарта обслуживания моделей в Kubernetes. 

Однако при переносе всей разработки команды KServe в облачную среду Kubernetes выявила серьезные архитектурные проблемы. ModelMesh начал показывать себя плохо при:

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

  • Большом распределении разных моделей по подам.

  • Динамическом масштабировании в cloud-native окружении.

Не буду вдаваться в детали, но главная техническая проблема заключается в том, что ModelMesh осуществляет частые обращения к etcd для координации состояния моделей между подами. В корпоративной среде IBM с относительно стабильным набором моделей это работало нормально. Но в динамичной Kubernetes-среде с частыми изменениями это стало узким местом. 

Если хотите подробный разбор архитектуры, примеры конфигов и алгоритм размещения — дайте знать в комментариях, все распишем подробно в более хардкорной версии статьи для самых прошаренных. Сначала хотели расписать в этой, но получилось 50 страниц и мы решили пощадить читателей. 

Сердце ModelMesh — это сложный алгоритм размещения, который работает как распределенный LRU-кеш с дополнительной логикой. После принятия решения о размещении модели, можно настроить по какой логике та или иная модель будет вытесняться с GPU, чтобы не мешать соседям, например:

  • LRU (наименее недавно использованный) — базовая стратегия, модель, к которой дольше всего никто не обращался, удаляется первой.

  • LFU (наименее часто используемый) — если модель редко запрашивают, даже если к ней недавно обращались, ее тоже могут удалить.

  • Выселение с учетом размера — очень большие модели, которые занимают много места, могут быть удалены, чтобы освободить место для нескольких маленьких.

  • Приоритетные модели — критически важные модели можно защитить от автоматического удаления.

Из коробки ModelMesh предоставляет широкий набор поддерживаемых фреймворков для вывода моделей:

Время выполнения

Поддерживаемые формы

Особенности

MLServer

sklearn, xgboost, lightgbm, spacy

Легковесный, быстрый старт

Тритон

TensorFlow, PyTorch, ONNX, TensorRT

Высокая производительность, оптимизация графического процессора

TorchServe

PyTorch MAR архивы

Нативная поддержка PyTorch

ОВМС

OpenVINO IR, ONNX

Оптимизация для процессоров Intel

В общем мы изучили все что смогли про Model Mesh и вот к каким выводам пришли: 

  • Прогрев (warm-up) обязателен. Без предварительной загрузки в кэш не добиться стабильной задержки отклика.

  • Процент попаданий в кэш (cache hit rate) — ключевая метрика. Низкий показатель убивает производительность.

  • Жесткие ограничения памяти (memory limits) — необходимость. Предотвращает аварийное завершение подов из-за нехватки памяти в пиковые нагрузки.

  • Обязательно прописывать правила размещения (affinity rules) для критичных моделей. Гарантирует, что важные модели не будут вытеснены из памяти.

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

Плюсы: проверен в продакшне Watson NLU и watsonx Assistant, автоматически управляет жизненным циклом моделей, встроенная отказоустойчивость.

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

✅Использовать если много моделей (>10), нестабильная нагрузка, A/B-тесты, нужно экономить на GPU.

❌Не использовать, если есть жесткие SLA (<50 мс), огромные модели (>10 GB), требование полной изоляции (multi-tenancy), всего 1-2 стабильные модели.

vLLM Production Stack

В январе 2025 года команда vLLM представила референсную архитектуру (reference architecture) для промышленного развертывания больших языковых моделей в кластерах Kubernetes под названием vLLM Production Stack. В отличие от IBM ModelMesh этот проект не заменяет встроенный планировщик (scheduler) vLLM, а создает интеллектуальный шлюз (Gateway) для распределения нагрузки.

Основные принципы работы vLLM Production Stack:

  1. Работа со своими планировщиками. Каждый экземпляр (instance) vLLM работает со своим собственным, оригинальным планировщиком, а система не вмешивается в его логику.

  2. Архитектура на основе шлюза (Gateway-based). Перед группой модулей (pods) vLLM устанавливается «умный» маршрутизатор (router), который распределяет входящие запросы.

  3. Алгоритмы хеширования для балансировки. Для распределения нагрузки используются специальные алгоритмы хеширования.

  4. Динамическая загрузка адаптеров LoRA. Система позволяет загружать и выгружать адаптеры LoRA (Low-Rank Adaptation) прямо во время работы, без необходимости перезапуска модулей.

  5. Маршрутизация с учетом кэша ключей-значений (KV cache-aware routing). Алгоритмы маршрутизации учитывают состояние внутреннего кэша моделей, чтобы максимально эффективно повторно использовать уже вычисленные данные и сокращать задержки.

Тут мы уже изучили производительность, и вот что вышло:

Метрика

vLLM производственный стек

Базовый vLLM

Улучшение

Пропускная способность (треб/с)

125

89

+40%

Задержка P95 (мс)

245

312

-21%

Коэффициент попадания в кэш

87%

23%

+278%

Использование графического процессора

91%

76%

+20%

TTFT P95 (мс)

89

156

-43%

Бенчмарк разницы:

  • Аппаратное обеспечение : 4x NVIDIA A100 80 ГБ

  • Модель: Llama-3-70B-Chat

  • Рабочая нагрузка: 1000 одновременных запросов, запросы разной длины

  • Продолжительность: 30 минут при постоянной нагрузке

Факторы повышения производительности:

  1. Повторное использование кэша KV: 87% попаданий в кэш благодаря маршрутизации с учетом префиксов

  2. Оптимальное дозирование: маршрутизатор балансирует нагрузку для достижения оптимальных размеров партий.

  3. Сокращение количества холодных запусков: интеллектуальный предварительный прогрев на основе шаблонов

  4. Оптимизация памяти: динамическая загрузка LoRA без фрагментации памяти

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

Плюсы:

  • Интеллектуальный роутинг с поддержкой prefix-aware и KV cache-aware стратегий

  • Динамическая загрузка LoRA-адаптеров без перезагрузки моделей

  • Встроенные Kubernetes-операторы для автоматического управления

  • Детальная телеметрия и мониторинг через Prometheus/Grafana

  • Поддержка автомасштабирования по метрикам QPS и GPU-утилизации

Минусы:

  • Высокая сложность архитектуры с множеством компонентов (Router, Gateway, CRD)

  • Значительные накладные расходы на поддержку операторов и мониторинг

  • Зависимость от единого кэша делает систему уязвимой к сбоям

  • Сложная отладка при проблемах с роутингом или кэшированием

Использовать если:

  • Нужны частые A/B-тесты и эксперименты с моделями

  • Требуется динамическая кастомизация через LoRA-адаптеры

  • Есть команда DevOps для поддержки сложной архитектуры

  • Высокий трафик с возможностью переиспользования кэша

Не использовать если:

  • Требуются жёсткие SLA по latency (<100мс)

  • Небольшая команда без экспертизы в Kubernetes

  • Простые задачи с 1-2 стабильными моделями

  • Ограниченный бюджет на операционные расходы

Почему мы выбрали свой путь

Как видите, мы протестировали все популярные решения. На это ушло аж 6 месяцев, в ходе которых наши инженеры DS пришли к неутешительному выводу: ни одно готовое решение не защищает наш продукт без серьезных компромиссов. ModelMesh давал непредсказуемые задержки в проде. vLLM Production Stack работает только с LLM, а это не единственное, что нужно нашим заказчикам. Так мы решили делать свое. 

Наш подход — Cloud.ru Shared GPU

Наш подход к виртуализации GPU основан на глубоком понимании потребностей современных ML-приложений и ограничений существующих решений. Мы осознанно выбрали путь разработки собственного планировщика (cloudru-vgpu-scheduler) с интеграцией в стандартный Kubernetes Scheduler, чтобы решить фундаментальную проблему: эффективное использование дорогостоящих GPU-ресурсов.

Основная архитектурная идея заключается в том, чтобы размещать несколько подов (workload'ов) на одной физической GPU, что позволяет значительно повысить утилизацию ресурсов. В среднем, наши клиенты используют менее 23% от доступной GPU-памяти, что означает огромные потери бюджета на неиспользуемые ресурсы. Наше решение позволяет разместить до 8 виртуальных GPU на одной физической карте H100, эффективно дробя 80 ГБ памяти на более мелкие, управляемые части.

Ключевые аспекты нашего подхода:

  1. Совместное использование GPU. Вместо выделения целой GPU для каждой модели, мы виртуализируем ресурсы, позволяя нескольким подам одновременно использовать одну физическую GPU. Это особенно эффективно для небольших моделей, которые требуют всего несколько гигабайт памяти.

  2. Интеллектуальное планирование. Наш пользовательский планировщик (cloudru-vgpu-scheduler) является центральным компонентом системы, отвечающим за эффективное распределение виртуальных GPU ресурсов. Он работает как расширение стандартного Kubernetes Scheduler, интегрируясь с ним через механизм делегирования планирования (schedulerName).  cloudru-vgpu-scheduler выполняет следующие ключевые функции:

    • Сбор метрик: Постоянно мониторит состояние GPU-узлов, собирая данные о доступной памяти, загрузке и фрагментации.

    • Ранжирование узлов: Оценивает узлы по критериям доступности, утилизации и локальности ресурсов, чтобы определить оптимальные кандидаты для размещения подов.

    • Алгоритм упаковки (binpack): Применяет специализированный алгоритм для максимальной упаковки виртуальных GPU на физические, минимизируя фрагментацию и повышая общую утилизацию с 23% до 78%.

    • Выбор оптимального узла: На основе анализа принимает решение о размещении пода на конкретном узле.

  3. Инициализация ресурсов. После выбора узла инициирует процесс настройки виртуальных GPU ресурсов на узле через cloudru-vgpu-plugin.

  4. Прозрачная виртуализация. Подход на уровне узла с использованием cloudru-vgpu-plugin обеспечивает полную прозрачность для ML-фреймворков. Каждый под «видит» свою выделенную GPU с определенным объемом памяти, хотя на самом деле все поды работают на одной физической карте. Это позволяет использовать любые ML-фреймворки (vLLM, Triton, PyTorch и др.) без изменений в коде приложений.

  5. Изоляция и безопасность. Несмотря на совместное использование ресурсов, каждый контейнер изолирован от других. Если один контейнер попытается использовать больше памяти, чем выделено, он получит ошибку, но не повлияет на другие контейнеры, работающие на той же GPU.

Этот подход позволил нам создать решение, которое сочетает в себе эффективность виртуализации с простотой использования и полной совместимостью с Kubernetes, обеспечивая высокую утилизацию ресурсов без потери стабильности и производительности.

Cloud.ru Shared GPU — это система виртуализации ресурсов GPU, которая работает прозрачно для любых ML-фреймворков и не требует изменений в коде приложений.

Архитектура Cloud.ru Shared GPU
Архитектура Cloud.ru Shared GPU

Результаты тестирования и метрики

После внедрения Cloud.ru Shared GPU мы протестировали свою систему на нескольких популярных моделях и вот результат: загрузка GPU выросла с 23% до 78% (+339%), задержка увеличилась всего на 7%. 

Аппаратное обеспечение:

  • Графический процессор : NVIDIA H100 80 ГБ

  • Процессор : Intel Xeon Gold 6348 (28 ядер)

  • ОЗУ : 512 ГБ DDR4

Тестовые модели:

Модель

Тип

Размер модели

Типичное использование GPU

BGE-M3

embedding

2.3GB

4-6GB

Llama-2-7B

LLM

13GB

16-24GB

ResNet-50

vision

98MB

2-4GB

Результаты для модели BGE-M3

Главные цифры:

Метрика

До Cloud.ru Shared GPU

После Cloud.ru Shared GPU

Улучшение

GPU Utilization

12%

78%

+650%

Memory Efficiency

7.5%

67.5%

+900%

Throughput

847 req/s

2,341 req/s

+276%

Latency P95

156ms

167ms

+7%

Внедрение интерцептора дало следующие результаты, по производительности:

Параметр

Значение

Комментарий

Latency overhead

<2%

Практически незаметно

Memory overhead

~50MB

Минимальный footprint

CPU overhead

<1%

CPU практически не нагружается

Throughput impact

0%

Throughput не страдает

По улучшению утилизации: 

Метрика

До Cloud.ru Shared GPU

После Cloud.ru Shared GPU

Улучшение

Средняя утилизация GPU

23%

78%

+339%

Пиковая утилизация

45%

91%

+102%

Фрагментация памяти

HIGH

LOW

Значительное снижение

Потери ресурсов

77%

22%

-71%

Снижение стоимости

-

-

-67%

Эволюция ML-выводов в цифрах

Статистика продакшена:

Метрика

Значение

Комментарий

Общее количество моделей

247

-

Активные GPU узлы

52

-

Общая GPU память

4160GB

52 x 80GB H100

Используемая память

3205GB

77% утилизация

Экономия затрат

$1.2M/год

-

GPU-инциденты

3

за 6 месяцев

MTTR для GPU проблем

12 минут

vs 2+ часов ранее

Операционные метрики, надежность и отладка:

Метрика

Улучшение

Комментарий

Время отладки

-85%

Намного проще найти проблемы

Время развертывания

без изменений

Без изменений в процессе

Усилия на поддержку

-60%

Меньше операционные накладные расходы

Время решения инцидентов

-75%

Быстро решаем проблемы

Ложные разработки

-90%

Четче метрики = меньше шума

Выводы и планы 

Вот так мы создали систему виртуализации графического процессора, которая повысила утилизацию в 3,4 раза без потери стабильности, сэкономили компании кучу денег и сократили время отладки в 5 раз. Эти полгода поисков и разработки своего решения дали нам важный урок: не пытайтесь решить проблему эффективности на уровне обслуживания модели. Решайте на уровне ресурсов — это проще и надежнее. Расскажите в комментариях о своем опыте оптимизации GPU.

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

Полезные ссылки:

Комментарии (2)


  1. achekalin
    24.09.2025 11:50

    А если вы при этом провайдер, то вы еще и упускаете прибыли, ведь карта могла бы обрабатывать нужды еще 10 клиентов

    Вот тут я немного задумался: если карту продать 10 клиентам, которые, очевидно, будут пользоваться ею с чуть меньшим удобством, чем если бы картой пользовался один человек эксклюзивно, то и ценник должен бля клиента упасть хотя бы раз в 10, разве нет?

    Почему в 10 - потому что провайдер амортизирует одну железку, почему "хотя бы" - потому что за неудобство клиента (если в какой-то момент на карту зайдут и нагрузят ей ё два человека, то скорость для каждого упадет, т.к. кроме разделяемой памяти там есть и сам процессор, который - один на всех) было "честно" дать небольшой дисконт.

    Скажите, а когда я читаю, что модель весит 50 Гб, и понимаю, что видеопамяти ей нужно ещё больше, чем это число - то, как бы мало я видеокартой не пользовался, я весь все равно вынужден арендовать много дорогой видеопамяти, верно?


  1. coodi
    24.09.2025 11:50

    Были исследования, когда для Нвидиа создавали виртуальные устройства для использования в контейнерах, и для каждого этого устройства могли ограничивать объем используемой памяти и времени использования. Можно использовать для ии-агентов, например