Прямой ответ
MLOps — практика, при которой обучение, проверка и выкатка модели выполняются как автоматизированный пайплайн, а не как последовательность ручных действий в ноутбуке. Цель — предсказуемость: любая модель в проде появилась через один и тот же процесс с проверками и возможностью отката.
Базовый пайплайн:
- Подготовка данных. Сбор среза, проверка схемы и качества, фиксация версии датасета.
- Обучение. Запуск с зафиксированными параметрами и логированием в трекинг — см. MLflow.
- Оценка. Прогон на отложенном наборе, сравнение с текущей продакшен-моделью.
- Регистрация и проверки. Запись версии в реестр, проверка схемы входа, времени инференса, размера артефакта.
- Выкатка. Перевод алиаса на новую версию; сначала на часть трафика, затем полностью.
- Наблюдение. Метрики качества и дрейфа; при деградации — откат.
Принципы, которые отличают пайплайн от набора скриптов:
- Воспроизводимость. Одинаковые вход и версия кода дают одинаковую модель. Обеспечивается фиксацией датасета,
random_stateи окружения. - Идемпотентность. Повторный запуск шага не портит результат: данные пишутся в новую версию, а не перезаписываются.
- Проверки как часть потока. Модель, не прошедшая проверки, физически не может попасть в продакшен.
- Откат за минуты. Переключение алиаса реестра, а не переобучение — механика в статье про model registry.
Триггеры переобучения:
- По расписанию. Простейший и самый предсказуемый вариант.
- По деградации качества. Когда метрики на отложенных истинных метках опускаются ниже порога.
- По дрейфу данных. PSI или KS превышают порог — см. мониторинг моделей.
- По изменению схемы или источника данных. Требует пересборки признаков.
Практика: структура и автоматизация
Оркестрация. Шаги удобно выразить как DAG в Airflow: каждая задача — шаг пайплайна, с ретраями, таймаутами и алертами. Основы — в статье про оркестрацию пайплайнов.
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime, timedelta
with DAG("ml_retrain_daily", schedule="0 3 * * *", start_date=datetime(2026, 1, 1),
catchup=False, default_args={"retries": 2, "retry_delay": timedelta(minutes=10)}) as dag:
prepare = PythonOperator(task_id="prepare_dataset", python_callable=prepare_dataset)
train = PythonOperator(task_id="train_model", python_callable=train_model)
evaluate = PythonOperator(task_id="evaluate_model", python_callable=evaluate_model)
promote = PythonOperator(task_id="promote_if_better", python_callable=promote_if_better)
prepare >> train >> evaluate >> promote
Проверки, которые должны быть обязательными:
- Качество данных. Полнота, уникальность ключей, контроль объёма — те же практики, что и для обычных пайплайнов, см. data quality.
- Схема признаков. Совпадение с ожидаемым набором и типами; новый или пропавший признак блокирует выкатку.
- Порог качества. Новая модель должна быть не хуже текущей на отложенном наборе с учётом разброса.
- Производительность инференса. Время предсказания на эталонном объёме; регресс по скорости — тоже регресс.
- Отсутствие утечек. Проверка, что признаки доступны в момент предсказания.
Промотирование только при улучшении:
def promote_if_better(**ctx):
new = ctx["ti"].xcom_pull(task_ids="evaluate_model", key="metrics")
cur = load_production_metrics()
if new["roc_auc"] < cur["roc_auc"] - 0.005:
raise ValueError("новая модель хуже текущей — промоушен отменён")
set_alias(model_name, new["version"], "production")
Рекомендации:
- Разделяйте обучение и выкатку. Обучение может запускаться часто, выкатка — только через проверки и, желательно, с подтверждением.
- Храните код пайплайна в репозитории. Ноутбуки допустимы для исследования, но не как источник продакшен-модели.
- Логируйте всё: версии данных, кода, параметров, метрик. Без этого невозможно расследовать «почему модель ухудшилась».
- Тестируйте сам пайплайн. Проверка, что задача падает на некорректной схеме, так же важна, как тесты модели.
- Не автоматизируйте то, что требует решения. Автоматическое переобучение без проверки качества закрепляет деградацию; лучше автоматизировать подготовку и проверку, а решение о выкатке оставить человеку.
Практический сценарий: переобучение «сломало» продакшен
Контекст: настроили ежедневное автоматическое переобучение с автовыкаткой. Через неделю качество на реальном трафике упало на 9 %.
- Что произошло. В обучающие данные попал период с аномалией источника: часть признаков три дня не заполнялась. Модель обучилась на искажённом срезе, проверки качества не было — автовыкатка срабатывала безусловно.
- Диагностика. В истории версий видно три переобучения подряд с падающими метриками; каждая версия автоматически становилась продакшеном.
- Действия. Откатили алиас на версию недельной давности; заблокировали автовыкатку; добавили проверки качества данных и порог сравнения с текущей моделью.
- Проверка. После чистки данных переобучение дало модель лучше текущей, промоушен прошёл через проверку; качество восстановилось.
- Профилактика. В пайплайн добавлены: контроль полноты признаков перед обучением, обязательное сравнение с продакшен-версией, алерт на три подряд неуспешных переобучения и правило «выкатка только после проверки».
Вывод: автоматизация MLOps ценна не скоростью, а обязательностью проверок. Пайплайн без проверок быстрее распространяет ошибки, а не модели.
FAQ
С какого уровня зрелости стоит начинать? Минимум, который окупается сразу: фиксация версии датасета, логирование прогонов, реестр моделей с алиасами и ручной промоушен после проверки. Полная автоматизация переобучения — следующий этап, а не стартовый.
Нужен ли Kubernetes для MLOps? Нет. Для большинства команд достаточно оркестратора и контейнеров; Kubernetes оправдан при больших вычислительных задачах и требованиях к изоляции. Основы — в статье про Kubernetes.
Как тестировать модель в CI? Три уровня: юнит-тесты функций признаков, регрессионный прогон на фиксированном наборе с проверкой метрик и проверка схемы входа. Полное переобучение в CI обычно избыточно — его выносят в отдельный пайплайн.
Что делать с несколькими моделями в одном продукте? Каждая модель — отдельный пайплайн с общим набором практик: версионирование данных, проверки, реестр, наблюдение. Общие признаки выносят в единый слой, чтобы изменение определения не ломало несколько моделей одновременно.
Источники: MLflow docs, Airflow docs, scikit-learn model persistence — ссылки в шапке.