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

Меня зовут Андрей Качетов, я эксперт и партнер по ML-платформам.
Пару лет назад я писал статью [1] о «молодом и подающем надежды» подходе MLOps, и по сей день продолжаю внедрять его в жизнь наших дата-сайентистов. С тех пор ландшафт в мире машинного обучения [2] заметно изменился. Многие компании уже понимают ценность MLOps и внедряют у себя MLflow, Airflow и другие подобные решения. Сегодня я расскажу о практическом кейсе одной из таких компаний.
ТК «Центр», один из наших клиентов, обратился к нам за помощью в сборке конвейера для моделей. Зачем он нужен? Представьте, что у вас есть все детали для сборки автомобиля, но нет инструкции и соединительных элементов. Дата-сайентисты вручную переносили модели между средами, деплой был непрозрачным и ручным, а отладка превращалась в задачу со звездочкой.
Мы взяли этот «конструктор» и собрали из него единый, сквозной и понятный автоматизированный флоу, который позволил команде сосредоточиться на моделях, а не на инфраструктуре. Об этом и пойдет речь ниже.
Содержание:
Когда мы пришли в проект, у клиента из MLOps-инструментов не было связного процесса — лишь несколько разрозненных сервисов. В рамках проекта мы развернули в облаке Selectel JupyterHub, MLflow для трекинга экспериментов, Airflow для запуска batch-моделей и KServe на базе Kubernetes для развертывания онлайн-моделей.
Изначально это работало так: дата-сайентист обучал модель в Jupyter и вручную сохранял артефакты, а затем отдельно писал DAG для Airflow. Процесс был фрагментированным, непрозрачным и трудоемким:
каждый этап был изолирован и требовал ручных действий;
было сложно отследить, какая версия кода и данных привела к конкретной модели в проде;
любое изменение требовало правок в нескольких местах, что замедляло Time-to-Market.
Наша задача заключалась в том, чтобы создать на основе этих инструментов единую и удобную платформу.
Во время онбординга на проект и знакомства с инфраструктурой клиента мы поняли, что ему вполне хватает существующих опенсорсных инструментов для решения текущих задач. Поэтому мы решили не изобретать велосипед, а просто связать используемые решения в логичный автоматизированный процесс. Вот ключевые компоненты нашей архитектуры:

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. Процесс выглядит так:
DS готовит код для инференса и коммитит его в Git-репозиторий.
Airflow автоматически подтягивает изменения.
Запускается DAG, который забирает нужную версию модели из MLflow и применяет ее к данным.
Сделано все было через dag_processor (подробнее о нем можно почитать в документации Airflow [8]).
Фактически мы опирались на механизм Airflow по обработке DAG’ов: CI/CD генерирует Python-код DAG’а и пушит его в Git-репозиторий , после чего DAG Processor через механизм Git DAG Bundle автоматически синхронизирует изменения. Это позволило обойтись без кастомных сервисов и сохранить декларативный подход к управлению пайплайнами.
4. Развертывание онлайн-моделей (KServe)
Для моделей, работающих в режиме реального времени, был разработан унифицированный сценарий деплоя. После регистрации модели в MLflow запускается пайплайн, который упаковывает модель в нужный формат и разворачивает ее в KServe.
5. Сквозной мониторинг
Мы внедрили базовую систему мониторинга, которая отслеживает состояние пайплайнов и доступность онлайн-сервисов, а также логирует все действия пользователей всех систем. Это позволило быстро реагировать [9] на проблемы и понимать, на каком этапе что-то пошло не так.
Сейчас рутина дата-сайентиста в ТК «Центр» выглядит примерно так:
Эксперимент. Открыл Jupyter, написал код в унифицированном шаблоне, запустил обучение модели, все результаты автоматически попали в MLflow. Далее в самом MLFlow в experiment run проставил тег (dev, test, prod) — благодаря CI эта model URI проставится в переменную окружения контейнера с DAG run (KPO).
Выбор лучшей модели. В интерфейсе MLflow сравнил запуски и выбрал лучшую модель, зарегистрировал ее в Model Registry.
Деплой:
для оффлайн-модели: закоммитил код обработки в Git, далее Airflow сам подхватит его и запустит регулярный пересчет.
для онлайн-модели: запустил пайплайн деплоя с указанием версии модели из MLflow. Через несколько минут модель будет доступна по API.
Наблюдение. При необходимости в любое время смотрит в системе мониторинга, что его модель успешно работает и отвечает на запросы. Аналогично проверяет логи модели, что позволяет замечать различные кейсы.
Весь процесс от идеи до работающей модели стал предсказуемым и занимает значительно меньше времени.
Вся инфраструктура развернута в 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 — это не столько про конкретный стек, сколько про процессы и связи между ними. Правильно собранный пазл из опенсорсных инструментов может дать огромный прирост в эффективности и прозрачности процессов и позволить команде заниматься тем, что у нее получается лучше всего — создавать ценность с помощью данных.
А инсайтами с других проектов по оптимизации инфраструктуры мои коллеги делятся в своих статьях. Рекомендую к прочтению:
Тонкости обновления драйверов NVIDIA в Yandex Managed Kubernetes [12]
BuildKit в Kubernetes: мануал по быстрой и автомасштабируемой сборке проектов [13]
GitOps для Airflow: как мы перешли на лёгкий K8s-native Argo Workflows [14]
Infrastructure as Code на практике: как мы рефакторили сложный Ansible-репозиторий [15]
Автор: 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
Нажмите здесь для печати.