Оптимізація ML-пайплайнів з Kubeflow. Як ми зекономили ресурси, збільшили гнучкість і прибрали хаос
Мене звати Богдан Зелінський, я Machine Learning Engineer в Universe Group, де останні роки займаюся побудовою комплексних
У своїй роботі я часто маю справу з генеративними моделями, кастомним препроцесінгом, парсингом облич, NSFW-фільтрацією контенту, captioning-ом зображень та багато чим іншим. Усі ці фічі повинні працювати стабільно, швидко й економно. Саме це підштовхнуло нас до пошуку більш гнучкої
Машинне навчання — це вже давно не просто про моделі. Це про пайплайни. А пайплайни — це про інфраструктуру. І саме інфраструктура часто визначає, наскільки ефективним буде
Цю істину ми засвоїли дорогою ціною, коли починали з невеликою командою і обмеженим бюджетом. У цій статті я поділюсь досвідом, як ми пройшли шлях від SageMaker до Kubeflow і побудували кастомізовану, ефективну й економічну
Що ми будували: коротко про наш продукт
Наш застосунок працює на перетині комп’ютерного зору, генеративного ШІ та естетики. Серед ключових фіч:
- Photo enhancement — покращення фото в один клік (збільшення роздільної здатності, прибирання нерівностей шкіри і, якщо необхідно, колористика чорно-білих фото).
- Magic Brush — видалення або додавання обʼєктів на фото.
- Background replace — заміна фону для обʼєкта на фото.
- AI-фільтри — генерація зображень у заданому стилі (як Lego, мультфільми різних студій тощо).
- AI-аватари — реалістичні фото користувачів у заданих обставинах (наприклад, бізнес-фотосесія).
- Генерація відео — короткі анімації з заданим сюжетом (наприклад, «як виросте ваша дитина»).
Відео з демонстрацією фіч Visify:
Під капотом — складні пайплайни з численними етапами препроцесінгу, інференсу моделей, постпроцесінгу та збереження результатів. Частина логіки вимагає GPU, частина — ні. Спершу ми спробували все покласти на SageMaker, але досить швидко зрозуміли, що це не ідеальне рішення для наших потреб.
Чому довелось переосмислити інфраструктуру
Коли ми стартували, у нас не було ні MLOps-команди, ні досвіду з розгортанням складних
Наша перша реалізація включала кілька SageMaker endpoint’ів, які обробляли запити через REST API. Цілі пайплайни були загорнуті в Docker-контейнери. Усі пайплайни ми піднімали вручну або через AWS Lambda тригери. Масштабування endpoint’ів було налаштоване на базові метрики (як GPU utilization) через вбудований скейлер.
Але на практиці у нашої першої реалізації виникло багато обмежень:
- Обмежена гнучкість автоскейлінгу. SageMaker дозволяє масштабуватись лише за базовими метриками, як-от утилізація CPU або кількість запитів в секунду. Додати кастомну метрику — це вже цілий проєкт.
- REST API ендпоінти — недостатньо ефективно. Потрібно окремо ставити лоадбалансери, самостійно розв’язувати проблему таймаутів. А для нашого запиту це неефективно та додаватиме навантаження на команду.
- Дорого. Оскільки SageMaker додає ще один прошарок поверх EC2, його використання обходиться дорожче за пряме розгортання. Аналогічні за обчислювальними ресурсами SageMaker інстанси дорожчі за EC2, у результаті це призводить до помітного зростання витрат на інфраструктуру.
- Неефективне використання GPU. Препроцесінг і постпроцесінг фотографій виконуються повністю на CPU, але запускаються разом із інференсом на GPU інстансах. У підсумку — GPU в цей час простоює.
- Недостатній обсяг VRAM. Задля ефективнішого інференсу всі необхідні моделі тримаються постійно у VRAM. А зі збільшенням складності пайплайнів обсягу VRAM, доступного на інстансах SageMaker, стало недостатньо. Тому в деяких випадках довелось робити загрузку/вигрузку моделей з відеопамʼяті, що суттєво уповільнило інференс.
Це рішення спрацювало на старті, але стало занадто неефективним після того, як продукт почав масштабуватись.
Як нова інфраструктура закрила усі болі
Після запуску MVP ми почали активно досліджувати альтернативи. Вибір припав на Kubeflow — як платформу, яка дозволяє оркеструвати пайплайни на Kubernetes, розділяти ресурси, ефективно менеджити таски та масштабуватись. І щоб витиснути максимум з нової інфраструктури, ми адаптували принципи мікросервісної архітектури під наші потреби — тривалі інференси комплексних пайплайнів з обробки/генерації зображень.
Що ми зробили:
Розділили пайплайн на CPU та GPU компоненти
Ми поділили весь пайплайн на окремі компоненти за типом ресурсів, які вони споживають. Зокрема, всі етапи, що потребують обчислювальної потужності GPU — насамперед інференс моделей — були винесені в окремі сервіси, які ми розгорнули через KServe. Це дозволило ефективніше керувати цими компонентами, запускати їх лише за потреби, перевикористовувати в різних пайплайнах та ізольовано масштабувати.
Усі інші частини пайплайна — зокрема препроцесінг вхідних даних, постпроцесінг результатів, логування, збереження до сховищ і метрики — ми реалізували як Kubeflow-компоненти, що працюють на менш вартісних CPU-орієнтованих інстансах.
Автоматизували запуск пайплайнів через чергу
Ми створили окремий мікросервіс, який постійно слухає чергу задач — наприклад, AWS SQS або інший брокер повідомлень. І коли зʼявляється нова таска — запускається відповідний Kubeflow pipeline run.
Ми також додали логіку маршрутизації: залежно від типу задачі або її параметрів запускається певна версія пайплайна та обирається відповідна конфігурація ресурсів. Це дозволяє адаптивно масштабувати навантаження, і бути більш ефективними на менш ресурсоємних задачах.
Скейлимо динамічно завдяки Kubernetes
Замість ручного налаштування скейлерів або кастомних скриптів, ми використовуємо KEDA (Kubernetes-based Event Driven Autoscaler). Це дозволяє масштабувати поди на основі не лише стандартних метрик, як CPU чи GPU, але й подій — наприклад, довжини черги, часу очікування запитів чи навіть кастомного health-індексу.
Як нова інфраструктура перекрила обмеження попередньої
- Завдяки гнучкому кастомному налаштуванню KEDA cистема реагує на реальне навантаження, масштабуючись саме тоді, коли потрібно, і саме в тих компонентах, де це критично.
- Запуск пайплайнів через чергу завдань дозволив повністю відмовитися від REST API endpoint’ів для інференсу. Це зняло потребу в окремих лоадбалансерах, знизило ризик таймаутів, спростило масштабування і дозволило нам краще контролювати пріоритети обробки.
- Оскільки Kubeflow розгорнутий повністю всередині EKS-кластера (на EC2-інстансах) це моментально дозволило нам економити на різниці між SageMaker та EC2.
- Розділення задач на CPU- і GPU-компоненти дозволило запускати більшість сервісів на дешевших ресурсах. GPU задіюється лише тоді, коли це дійсно необхідно.
- Завдяки модульності нашої нової інфраструктури у нас більше нема потреби «втискувати» всі необхідні моделі в одну відеокарту. Тепер для інференсу кожної моделі піднятий свій KServe-сервіс з достатньою кількістю ресурсів.
Таким чином нова інфраструктура повністю закрила наші ключові проблеми та суттєво підвищила ефективність використання ресурсів. У нашому випадку повний перехід був не лише виправданим, а й необхідним для подальшого масштабування продукту. І оскільки до цього ми зосереджувались переважно на архітектурних рішеннях, варто також окремо розглянути загальні переваги та обмеження самого Kubeflow як платформи.
Переваги Kubeflow
Підтримка повного життєвого циклу ML
- Охоплює весь цикл розробки ML: експерименти, тренування, тюнінг, деплоймент та моніторинг.
- Добре інтегрується з Kubernetes-орієнтованими інструментами (наприклад, Argo, Istio, KServe).
Масштабованість
- Використовує можливості Kubernetes для ефективного масштабування навантажень.
- Підтримує розподілене навчання (PyTorch, TensorFlow, MPI тощо) з мінімальними зусиллями.
Модульна архітектура
- Кожен компонент (наприклад, Pipelines, Notebooks) працює незалежно.
- Можна встановити тільки ті компоненти, які потрібні.
Підтримка хмари та локального розгортання
- Працює на будь-якому кластері Kubernetes: EKS, GKE, AKS, OpenShift тощо.
- Дозволяє реалізовувати гібридні та мультихмарні стратегії.
Інтегрований інтерфейс та ноутбуки
- Вбудована вебпанель для керування пайплайнами, експериментами та моделями.
- Інтеграція з Jupyter Notebook для інтерактивної розробки.
Недоліки Kubeflow
Складність встановлення та налаштування
- Не підходить для початківців; потребує глибоких знань Kubernetes, мереж, RBAC тощо. Має високий поріг входу для спеціалістів без DevOps-досвіду.
- Встановлення та супровід (особливо з Istio або Dex) можуть бути проблемними.
Споживання CPU та RAM ресурсів при простої
- Оскільки Kubeflow складається з десятка різних мікросервісів? він споживає багато пам’яті та CPU навіть під час простою. І, як наслідок, буде не найефективнішим рішенням для проєктів з малим, нерегулярним навантаженням/
Недостатня документація та фрагментованість
- Документація покращується, але часто застаріла або розпорошена.
- Деякі компоненти швидко оновлюються без синхронізації з документацією.
Складність оновлень
- Оновлення між версіями можуть ламати сумісність.
- Часто немає чітких інструкцій для міграції.
Недосконалий інтерфейс
- Інтерфейс не завжди стабільний або зручний.
- Часто доводиться поєднувати UI, CLI та ручне редагування YAML.
Висновки та поради
- SageMaker — хороший старт, але не завжди вигідне рішення у довгостроковій перспективі. Якщо ваш пайплайн довго виконується або має складну логіку, вам може стати тісно.
- Модульність — ключ до швидкої розробки. Ми винесли основні етапи (наприклад, text2image, upscaling, face parsing тощо) в окремі KServe-компоненти. Нові пайплайни тепер можна збирати як LEGO — з уже готових блоків. Це пришвидшує девелопмент, зменшує дублювання коду і дозволяє підтримувати менше артефактів.
- Інвестиція в компонент = економія в майбутньому. Якщо якоїсь базової компоненти ще нема — додаємо її один раз, і вона працює в усіх наступних фічах. З часом кожна нова фіча стає дешевшою в розробці.
- Kubeflow + KServe = гнучкість, контроль і ефективність. Можна окремо керувати ресурсами, масштабуватись за потрібними метриками й запускати пайплайни як реакцію на події.
- Важливо розділяти CPU та GPU-задачі. Це здається очевидним, але дуже багато команд тримають усе в одному контейнері — і втрачають дорогоцінні GPU-години.
- Побудова інфраструктури — це інвестиція. Будуйте платформу, а не окремі пайплайни. Інфраструктура, де компоненти перевикористовуються і масштабуються незалежно, — це вже не просто «код, що працює», а справжня
ML-платформа, яка масштабуватиметься разом із вашим продуктом.
PS: Кому варто придивитися до Kubeflow
- Командам, які переросли MVP і хочуть масштабуватись без переплати за ресурси.
- Тим, хто хоче розділити пайплайн на логічні кроки з різними вимогами до ресурсів.
- Продуктам, де є тривалі інференси, комплексні пайплайни або heavy-CPU preprocessing.
5 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів