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

MLOps-пазл: как мы собрали единый конвейер для ML-моделей из разрозненных инструментов

MLOps-пазл: как мы собрали единый конвейер для ML-моделей из разрозненных инструментов - 1

Меня зовут Андрей Качетов, я эксперт и партнер по ML-платформам.

Пару лет назад я писал статью [1] о ‭«молодом и подающем надежды» подходе MLOps, и по сей день продолжаю внедрять его в жизнь наших дата-сайентистов. С тех пор ландшафт в мире машинного обучения [2] заметно изменился. Многие компании уже понимают ценность MLOps и внедряют у себя MLflow, Airflow и другие подобные решения. Сегодня я расскажу о практическом кейсе одной из таких компаний.

ТК «Центр», один из наших клиентов, обратился к нам за помощью в сборке конвейера для моделей. Зачем он нужен? Представьте, что у вас есть все детали для сборки автомобиля, но нет инструкции и соединительных элементов. Дата-сайентисты вручную переносили модели между средами, деплой был непрозрачным и ручным, а отладка превращалась в задачу со звездочкой.

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

Содержание:

Дано: MLOps-инструменты без связки

Когда мы пришли в проект, у клиента из MLOps-инструментов не было связного процесса — лишь несколько разрозненных сервисов. В рамках проекта мы развернули в облаке Selectel JupyterHub, MLflow для трекинга экспериментов, Airflow для запуска batch-моделей и KServe на базе Kubernetes для развертывания онлайн-моделей.

Изначально это работало так: дата-сайентист обучал модель в Jupyter и вручную сохранял артефакты, а затем отдельно писал DAG для Airflow. Процесс был фрагментированным, непрозрачным и трудоемким:

  • каждый этап был изолирован и требовал ручных действий;

  • было сложно отследить, какая версия кода и данных привела к конкретной модели в проде;

  • любое изменение требовало правок в нескольких местах, что замедляло Time-to-Market.

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

От инструментов к платформе

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

MLOps-пазл: как мы собрали единый конвейер для ML-моделей из разрозненных инструментов - 2

1.Единая среда для экспериментов (JupyterHub)
Мы настроили JupyterHub так, чтобы он стал единой точкой входа. Ключевое нововведение — преднастроенные коннекшены. При запуске своего инстанса дата-сайентист сразу получает окружение с выбранным пресетом ресурсов к MLflow и все преднастроенные библиотеки. Ему не нужно думать об адресах, портах и токенах — он сразу может переходить к действиям.

2. Трекинг экспериментов и моделей (MLflow)
MLflow стал центральным реестром для всего, что связано с моделями. Мы стандартизировали логирование: теперь для каждой модели автоматически отправляются метрики, параметры и сам артефакт модели в MLflow. Также была добавлена ролевая модель.
При этом мы явно разделили роли сущностей внутри MLflow. Experiment run используется как технический источник правды для автоматизации: именно из его метаданных (модель из последнего run) и тегов (test, prod) CI/CD получает model URI, который далее пробрасывается в Airflow или в пайплайн деплоя онлайн-модели. Model Registry, в свою очередь, выполняет роль каталога моделей и точки принятия решений: здесь дата-сайентист сравнивает версии, регистрирует финальную модель и управляет ее жизненным циклом.

3. Оркестрация оффлайн-моделей (Airflow)
Для batch-моделей мы использовали связку Git Sync + Airflow. Процесс выглядит так:

  1. DS готовит код для инференса и коммитит его в Git-репозиторий.

  2. Airflow автоматически подтягивает изменения.

  3. Запускается DAG, который забирает нужную версию модели из MLflow и применяет ее к данным.

Сделано все было через dag_processor (подробнее о нем можно почитать в документации Airflow [8]).
Фактически мы опирались на механизм Airflow по обработке DAG’ов: CI/CD генерирует Python-код DAG’а и пушит его в Git-репозиторий , после чего DAG Processor через механизм Git DAG Bundle автоматически синхронизирует изменения. Это позволило обойтись без кастомных сервисов и сохранить декларативный подход к управлению пайплайнами.

4. Развертывание онлайн-моделей (KServe)
Для моделей, работающих в режиме реального времени, был разработан унифицированный сценарий деплоя. После регистрации модели в MLflow запускается пайплайн, который упаковывает модель в нужный формат и разворачивает ее в KServe.

5. Сквозной мониторинг
Мы внедрили базовую систему мониторинга, которая отслеживает состояние пайплайнов и доступность онлайн-сервисов, а также логирует все действия пользователей всех систем. Это позволило быстро реагировать [9] на проблемы и понимать, на каком этапе что-то пошло не так.

Жизненный цикл модели: как это работает на практике

Сейчас рутина дата-сайентиста в ТК «Центр» выглядит примерно так:

  1. Эксперимент. Открыл Jupyter, написал код в унифицированном шаблоне, запустил обучение модели, все результаты автоматически попали в MLflow. Далее в самом MLFlow в experiment run проставил тег (dev, test, prod) — благодаря CI эта model URI проставится в переменную окружения контейнера с DAG run (KPO).

  2. Выбор лучшей модели. В интерфейсе MLflow сравнил запуски и выбрал лучшую модель, зарегистрировал ее в Model Registry.

  3. Деплой:

    • для оффлайн-модели: закоммитил код обработки в Git, далее Airflow сам подхватит его и запустит регулярный пересчет.

    • для онлайн-модели: запустил пайплайн деплоя с указанием версии модели из MLflow. Через несколько минут модель будет доступна по API.

  4. Наблюдение. При необходимости в любое время смотрит в системе мониторинга, что его модель успешно работает и отвечает на запросы. Аналогично проверяет логи модели, что позволяет замечать различные кейсы.

Весь процесс от идеи до работающей модели стал предсказуемым и занимает значительно меньше времени.

DevOps-реализация платформы

Вся инфраструктура развернута в Kubernetes с разделением окружений на отдельные нод-группы для изоляции ресурсов. Окружения определяются через ветки в GitLab — каждая feature-ветка автоматически получает свое изолированное окружение для разработки и тестирования.

CI/CD организован через GitLab CI: пайплайн выполняет обучение, генерацию Python-кода для DAG’ов Airflow с последующим пушем в центральный Git-репозиторий, который автоматически синхронизируется с Airflow. Также в рамках пайплайна происходит подстановка значений в values для Helm-чартов KServe InferenceService. Деплой online-модели происходит через ArgoCD — для каждой ветки разработки создается отдельный InferenceService. Все ссылки на обученную модель, Airflow DAG и API модели выводятся в логах GitLab pipeline.

Реализована автоматическая очистка: при вливании или удалении feature-ветки соответствующие онлайн-модели и связанные ресурсы автоматически удаляются из кластера, что предотвращает накопление неиспользуемых InferenceService и экономит ресурсы.

Итого: дата-сайентист получил возможность управлять полным жизненным циклом модели через GitLab-интерфейс. Все сводится к пушу изменений в ветку: пайплайн автоматически обучает модель, создает необходимую инфраструктуру и выдает готовые ссылки для работы. Не нужно разбираться в Kubernetes, Helm-чартах или ArgoCD — все это сделает автоматизация. Можно просто сосредоточиться на работе с самими моделями.

Что мы получили в итоге

Главный результат нашей работы — работающий процесс на основе связанных друг с другом инструментов.

Между этапами жизненного цикла модели больше нет ручных шагов, их заменил единый сквозной флоу. Time-to-Market заметно ускорился: вывод новой модели в прод сократился с недель до дней (а в некоторых случаях и часов). Возросла прозрачность системы — теперь всегда можно отследить, из какого эксперимента и какого кода родилась модель на проде. При вливании/удалении веток происходит автоматическая очистка старых окружений — мелочь, а приятно.

Но что еще важнее — дата-сайентистам больше не нужно быть DevOps-инженерами. Они могут следовать понятной инструкции и получать результат. 

Текущее решение отлично закрывает базовые потребности [10] команды, которая работает с классическими ML-моделями. В будущем мы планируем развивать платформу, а именно:

  • добавить расширенные дашборды для мониторинга качества моделей (data drift, target drift);

  • внедрить поддержку GPU для работы с нейросетями, LLM и RAG;

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

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

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

Автор: kachetov

Источник [16]


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

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

URLs in this post:

[1] статью: https://habr.com/ru/companies/alfa/articles/739792/

[2] обучения: http://www.braintools.ru/article/5125

[3] Дано: MLOps-инструменты без связки: https://www.braintools.ru%20MLOps-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B%20%D0%B1%D0%B5%D0%B7%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BA%D0%B8

[4] От инструментов к платформе: #%D0%9E%D1%82%20%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2%20%D0%BA%20%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D0%B5

[5] Жизненный цикл модели: как это работает на практике: https://www.braintools.ru%20%D0%BA%D0%B0%D0%BA%20%D1%8D%D1%82%D0%BE%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82%20%D0%BD%D0%B0%20%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B5

[6] DevOps-реализация платформы: #DevOps-%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B

[7] Что мы получили в итоге: #%D0%A7%D1%82%D0%BE%20%D0%BC%D1%8B%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D0%BB%D0%B8%20%D0%B2%20%D0%B8%D1%82%D0%BE%D0%B3%D0%B5

[8] документации Airflow: https://airflow.apache.org/docs/apache-airflow-providers-git/stable/bundles/index.html

[9] реагировать: http://www.braintools.ru/article/1549

[10] потребности: http://www.braintools.ru/article/9534

[11] Единый вход для ML-стека на примере Keycloak: https://habr.com/ru/companies/kts/articles/971982/

[12] Тонкости обновления драйверов NVIDIA в Yandex Managed Kubernetes: https://habr.com/ru/companies/kts/articles/962396/

[13] BuildKit в Kubernetes: мануал по быстрой и автомасштабируемой сборке проектов: https://habr.com/ru/companies/kts/articles/960922/

[14] GitOps для Airflow: как мы перешли на лёгкий K8s-native Argo Workflows: https://habr.com/ru/companies/alfa/articles/947754/

[15] Infrastructure as Code на практике: как мы рефакторили сложный Ansible-репозиторий: https://habr.com/ru/companies/kts/articles/945016/

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

www.BrainTools.ru

Rambler's Top100