ML Infrastructure
~20 мин

Трекинг экспериментов

MLflow, DVC, W&B — трекинг экспериментов, версионирование моделей и данных.

Трекинг экспериментов — чтобы не перезаписать лучшую модель

Загрузка интерактивного виджета...

Пятница вечером. Ты запустил 30 экспериментов за неделю, нашёл AUC 0.94 — лучший результат. Понедельник утром: «какие гиперпараметры дали 0.94?» Ответ — тишина. Ноутбук перезаписан, параметры не сохранены, модель потеряна. Ты не первый, кто переобучил ячейку в Jupyter и потерял лучший результат.

Без системного трекинга ML-эксперименты — это хаос: Excel-таблички, Slack-сообщения «лучшая модель — третий запуск во вторник», файлы model_final_v2_FINAL.pkl. Трекинг экспериментов решает это: каждый запуск автоматически сохраняет параметры, метрики, артефакты и код. Через полгода ты (или коллега) можешь точно воспроизвести любой результат.

Аналогия: лабораторный журнал учёного. Химик записывает каждый опыт: реагенты, температуру, результат. Без журнала — невозможно повторить удачный эксперимент и понять, почему неудачный провалился. Трекинг экспериментов — это лабораторный журнал для ML.

Дашборд трекинга экспериментов: параметры, метрики, артефакты
MLflow/W&B сохраняют каждый эксперимент: гиперпараметры, метрики, модели

Большая картина: цикл ML-эксперимента

Каждый ML-эксперимент проходит пять шагов. Трекинг-система автоматизирует шаги 3-5:

1. Гипотеза — «если добавить фичу X и увеличить depth до 8, AUC вырастет». Без чёткой гипотезы эксперимент — рандомный тыкинг. 2. Эксперимент — запуск обучения с конкретными параметрами. Код, данные, гиперпараметры — всё зафиксировано. 3. Логирование — автоматическая запись: параметры (lr=0.01, depth=8), метрики (AUC=0.93, F1=0.87), артефакты (модель, графики, confusion matrix), окружение (Python 3.11, sklearn 1.4, git commit abc123). 4. Сравнение — таблица всех экспериментов: сортируешь по AUC, фильтруешь по параметрам, строишь графики «AUC от learning rate». Видишь, что гипотеза не подтвердилась — depth=8 дал оверфит. 5. Выбор — лучшая модель регистрируется в Model Registry, получает версию и идёт на staging-тестирование.

Зачем это нужно

Без трекинга ты сравниваешь 50 экспериментов по памяти. С трекингом — в один клик: таблица, сортировка, графики. Через месяц тимлид спрашивает «почему CatBoost, а не LightGBM?» — открываешь MLflow, показываешь сравнение. Всё задокументировано, всё воспроизводимо.

MLflow — стандарт индустрии

MLflow — самый популярный open-source инструмент для трекинга. Self-hosted: данные остаются у тебя, не уходят в облако. Бесплатный. Используется в большинстве enterprise-компаний. Четыре компонента:

MLflow Tracking — ядро системы. Логирует параметры, метрики, артефакты каждого запуска. Предоставляет веб-UI для сравнения экспериментов: таблица, графики, фильтрация. Данные хранятся локально (SQLite) или на сервере (PostgreSQL + S3). MLflow Projects — формат упаковки ML-кода для воспроизводимости. MLproject-файл описывает зависимости (conda/pip), точку входа (train.py), параметры. Любой коллега запускает mlflow run . — и получает те же результаты. MLflow Models — единый формат упаковки моделей. Не важно, sklearn, PyTorch или XGBoost — модель сохраняется в стандартном формате с единым API predict(). Деплой одной командой: mlflow models serve. MLflow Model Registry — каталог моделей с версиями и стадиями жизненного цикла. Модель v3 → Staging → прошла тесты → Production. Старая версия → Archived. Загрузка production-модели — одна строка.

import mlflow
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score, f1_score

# Подключаемся к серверу трекинга
mlflow.set_tracking_uri("http://mlflow.internal:5000")
mlflow.set_experiment("churn-prediction")

with mlflow.start_run(run_name="gbm-depth6-lr005"):
    # 1. Логируем параметры
    params = {"n_estimators": 500, "max_depth": 6, "learning_rate": 0.05}
    mlflow.log_params(params)
    mlflow.log_param("train_size", len(X_train))

    # 2. Обучаем модель
    model = GradientBoostingClassifier(**params)
    model.fit(X_train, y_train)
    y_pred = model.predict_proba(X_test)[:, 1]

    # 3. Логируем метрики
    mlflow.log_metric("auc", roc_auc_score(y_test, y_pred))
    mlflow.log_metric("f1", f1_score(y_test, (y_pred > 0.5).astype(int)))

    # 4. Логируем артефакты (графики, данные)
    mlflow.log_artifact("plots/confusion_matrix.png")
    mlflow.log_artifact("plots/feature_importance.png")

    # 5. Сохраняем модель + регистрируем в Registry
    mlflow.sklearn.log_model(
        model, "model",
        registered_model_name="churn-model"
    )

Model Registry workflow: после обучения лучшая модель регистрируется и получает версию. Дальше — стадии жизненного цикла:

from mlflow.tracking import MlflowClient

client = MlflowClient()

# Перевести модель v3 в Production
client.transition_model_version_stage(
    name="churn-model", version=3, stage="Production"
)

# В inference-сервисе — всегда загружаем production
model = mlflow.pyfunc.load_model("models:/churn-model/Production")
predictions = model.predict(new_data)

Weights & Biases — визуализация и гиперпараметрический поиск

W&B (Weights & Biases) — облачная платформа с лучшей визуализацией на рынке. Графики loss по эпохам обновляются в реальном времени прямо в браузере. Особенно хорош для deep learning, где обучение длится часы и нужно видеть прогресс.

Sweeps — автоматический гиперпараметрический поиск. Описываешь пространство поиска (lr от 0.001 до 0.1, batch_size из [16, 32, 64]), W&B запускает эксперименты с Bayesian optimization и визуализирует результаты: parallel coordinates, importance plot. Не нужно писать свой grid search. Tables — интерактивные таблицы для анализа ошибок. Логируешь предсказания модели вместе с входными данными, фильтруешь по ошибкам, группируешь по категориям. Незаменимо для computer vision: «покажи все изображения, где модель ошиблась». Artifacts — версионирование датасетов и моделей. Artifact — это именованный набор файлов с версией. Датасет v2 → модель v5 → evaluation report. W&B строит граф зависимостей: «эта модель обучена на этом датасете».

import wandb

# Инициализация
wandb.init(project="churn-prediction", name="catboost-v3")
wandb.config.update({"lr": 0.05, "depth": 6, "iterations": 1000})

# Логирование метрик по эпохам → живые графики в браузере
for epoch in range(100):
    loss, auc = train_epoch(model, data)
    wandb.log({"loss": loss, "auc": auc, "epoch": epoch})

# Логирование таблицы предсказаний для анализа ошибок
table = wandb.Table(columns=["id", "true", "pred", "confidence"])
for i, (y_true, y_pred, conf) in enumerate(zip(labels, preds, confs)):
    table.add_data(i, y_true, y_pred, conf)
wandb.log({"predictions": table})

wandb.finish()

MLflow vs W&B: MLflow — self-hosted, данные не уходят наружу, полный контроль, бесплатный. W&B — облачный, красивый UI, Sweeps из коробки, бесплатный для индивидуального использования. В enterprise чаще MLflow (безопасность данных). В исследованиях и стартапах — W&B. Многие используют оба: W&B для экспериментов, MLflow для Model Registry и деплоя.

Что логировать: полный чеклист

Главное правило: логируй всё, что нужно для воспроизведения эксперимента. Через полгода ты должен восстановить точно такой же результат. Вот полный чеклист:

Параметры — всё, что ты задаёшь до обучения: • Гиперпараметры модели (lr, batch_size, epochs, depth, regularization) • Параметры данных (train_size, test_split, random_seed) • Параметры предобработки (scaler_type, n_features, tokenizer) • Имя модели, версия алгоритма

Метрики — всё, что получаешь после обучения: • Основные метрики (AUC, F1, precision, recall, RMSE) • Метрики по эпохам (train_loss, val_loss по шагам — для графиков) • Метрики по сегментам (AUC для premium, AUC для new_users) • Время обучения, потребление памяти

Артефакты — файлы, связанные с экспериментом: • Сама модель (pickle, ONNX, checkpoint) • Графики (confusion matrix, ROC curve, feature importance, learning curves) • Предсказания на тест-сете (для анализа ошибок)

Окружение и код — для воспроизводимости: • Git commit hash (какой код использовался) • requirements.txt / conda env (версии библиотек) • Hardware (GPU модель, количество RAM) • Версия данных (DVC hash, дата загрузки)

💡 Практический совет

Логируй с первого эксперимента, а не «когда будет время». Настройка MLflow — 5 минут и 10 строк кода. Стоимость восстановления потерянного эксперимента — часы или дни. Автоматическое логирование: mlflow.autolog() логирует параметры и метрики для sklearn, PyTorch, XGBoost, LightGBM без единой строки кода.

Сравнение экспериментов: как выбрать лучшую модель

Залогировать 50 экспериментов — полдела. Настоящая ценность — в сравнении. Как понять, какой эксперимент лучший?

Таблица экспериментов — базовый инструмент. Все запуски в одной таблице: параметры + метрики. Сортировка по AUC, фильтрация по параметрам (только depth ≥ 6), поиск по тегам. MLflow UI и W&B предоставляют это из коробки. Параллельные координаты — визуализация связи параметров и метрик. Каждый эксперимент — линия, проходящая через оси (lr, depth, n_estimators, AUC). Видишь паттерны: «все запуски с lr > 0.1 дали низкий AUC». W&B строит этот график автоматически. Парето-фронт — когда оптимизируешь несколько метрик одновременно. Пример: AUC vs inference_time. Модель A: AUC=0.95, 200ms. Модель B: AUC=0.93, 50ms. Обе на парето-фронте — ни одна не доминирует другую. Выбор зависит от бизнес-требований: latency-critical → модель B.

Практический workflow сравнения: 1. Отфильтруй эксперименты по базовым критериям (AUC ≥ 0.90, train_time < 1h) 2. Отсортируй по основной метрике 3. Для top-5 проверь метрики по сегментам (не просел ли AUC для важных групп?) 4. Для top-2 сравни learning curves (нет ли оверфита?) 5. Если метрики близки — выбирай более простую модель (Occam's razor)

Практика: полный пример с MLflow

Собираем всё вместе: полный скрипт трекинга эксперимента от загрузки данных до регистрации лучшей модели. Можешь скопировать и запустить.

"""Полный пример: трекинг экспериментов с MLflow"""
import mlflow
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score, f1_score, classification_report
import matplotlib.pyplot as plt

# --- Настройка ---
mlflow.set_tracking_uri("http://localhost:5000")  # или "sqlite:///mlflow.db"
mlflow.set_experiment("breast-cancer-classification")

# --- Данные ---
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# --- Перебор гиперпараметров ---
configs = [
    {"n_estimators": 100, "max_depth": 3, "learning_rate": 0.1},
    {"n_estimators": 300, "max_depth": 5, "learning_rate": 0.05},
    {"n_estimators": 500, "max_depth": 6, "learning_rate": 0.01},
]

best_auc, best_run_id = 0, None

for params in configs:
    with mlflow.start_run(run_name=f"gbm-d{params['max_depth']}-lr{params['learning_rate']}"):
        # Логируем параметры
        mlflow.log_params(params)
        mlflow.log_param("train_size", len(X_train))
        mlflow.log_param("test_size", len(X_test))

        # Обучаем
        model = GradientBoostingClassifier(**params, random_state=42)
        model.fit(X_train, y_train)
        y_pred = model.predict_proba(X_test)[:, 1]

        # Логируем метрики
        auc = roc_auc_score(y_test, y_pred)
        f1 = f1_score(y_test, (y_pred > 0.5).astype(int))
        mlflow.log_metric("auc", round(auc, 4))
        mlflow.log_metric("f1", round(f1, 4))

        # Логируем feature importance как артефакт
        fig, ax = plt.subplots(figsize=(8, 4))
        top_idx = np.argsort(model.feature_importances_)[-10:]
        ax.barh(range(10), model.feature_importances_[top_idx])
        ax.set_title("Top-10 Feature Importance")
        fig.savefig("feature_importance.png", bbox_inches="tight")
        mlflow.log_artifact("feature_importance.png")
        plt.close()

        # Сохраняем модель
        mlflow.sklearn.log_model(model, "model")

        # Трекаем лучший
        if auc > best_auc:
            best_auc = auc
            best_run_id = mlflow.active_run().info.run_id

# --- Регистрируем лучшую модель ---
mlflow.register_model(
    model_uri=f"runs:/{best_run_id}/model",
    name="breast-cancer-model"
)
print(f"Best AUC: {best_auc:.4f}, registered as breast-cancer-model")

🎯 На собеседовании

Junior

Зачем нужен трекинг экспериментов? Чтобы не потерять результаты среди 50 запусков. Логирует параметры, метрики, артефакты, модель. Через полгода можно воспроизвести любой эксперимент. • Что такое MLflow? Open-source инструмент для трекинга ML-экспериментов. Четыре компонента: Tracking (логи), Projects (воспроизводимость), Models (упаковка), Model Registry (версионирование). • Что нужно логировать? Параметры (гиперпараметры, seed, данные), метрики (AUC, F1, loss), артефакты (модель, графики), окружение (git commit, версии библиотек).

Middle

MLflow vs W&B — когда что? MLflow — self-hosted, данные внутри, Model Registry для продакшна. W&B — облачный, лучшая визуализация, Sweeps для подбора гиперпараметров. Enterprise → MLflow (безопасность). Исследования → W&B (удобство). • Что такое Model Registry? Каталог моделей с версиями и стадиями: Staging → Production → Archived. Позволяет откатиться к предыдущей версии одной строкой. Загрузка production-модели: mlflow.pyfunc.load_model("models:/name/Production"). • Как сравнивать эксперименты? Таблица с сортировкой по основной метрике. Parallel coordinates для визуализации связи параметров и метрик. Проверка по сегментам для top-кандидатов. При равных метриках — выбираем более простую модель.

Senior

Как организовать трекинг в команде из 10 DS? Централизованный MLflow-сервер (PostgreSQL + S3). Единая конвенция именования экспериментов и тегов. Автоматическое логирование через mlflow.autolog() в шаблоне проекта. CI интеграция: каждый PR с ML-кодом автоматически запускает эксперимент и логирует результат. • Парето-фронт для выбора модели. Когда оптимизируешь несколько метрик (quality vs latency, AUC vs interpretability) — строишь парето-фронт. Модели на фронте не доминируют друг друга. Выбор зависит от бизнес-ограничений: latency < 50ms → выбираем модель с best AUC при этом ограничении. • Воспроизводимость end-to-end. Трекинг параметров недостаточен. Нужно: DVC для версии данных, Docker для окружения, mlflow.log_param("git_commit", ...) для кода, фиксированный seed. Тест воспроизводимости: коллега с нуля получает тот же результат.

Собираем всё вместе

Трекинг экспериментов — фундамент воспроизводимого ML. Цикл простой: гипотеза → эксперимент → логирование (параметры, метрики, артефакты, окружение) → сравнение → выбор лучшей модели → Model Registry. MLflow — open-source стандарт с Model Registry для продакшна. W&B — облачный, с Sweeps и визуализацией для исследований.

Если запомнить одну вещь из этой ноды: настрой MLflow до первого эксперимента, а не после пятидесятого. 10 строк кода сейчас экономят дни работы потом. mlflow.autolog() — и вообще ноль усилий.

Дальше на роадмапе: MLOps Basics — полный цикл ML-системы, Model Serving — как задеплоить зарегистрированную модель, Monitoring — как отследить деградацию на проде.