Отслеживание экспериментов в MLflow

«У меня вчера было 0.94, а сегодня 0.91, что я менял?» — на этот вопрос отвечает трекинг экспериментов.

Отслеживание экспериментов — это систематическая запись каждого запуска обучения (параметры, метрики, артефакты, окружение), чтобы результаты можно было сравнивать и воспроизводить.

Зачем отслеживать

Дата-сайентист за день делает десятки запусков, меняя learning rate, число деревьев, набор признаков. Без записи через час он уже не помнит, какая комбинация дала лучший результат. Трекинг превращает эту работу из гадания в инженерию: каждый запуск зафиксирован, лучший — найден объективно, и его можно повторить.

Эксперимент как инженерная практика

Без трекинга работа дата-сайентиста напоминает алхимию: смешал что-то, получил результат, но повторить не может. Трекинг превращает это в воспроизводимую инженерию — и не только ради красоты. Он отвечает на три практических вопроса, которые иначе съедают дни. «Какая комбинация дала лучший результат?» — отсортируйте runs по метрике. «Почему сегодня хуже, чем вчера?» — сравните параметры двух runs рядом. «Как воспроизвести прод-модель спустя три месяца?» — откройте её run и повторите с теми же параметрами, seed и версией данных. Командно трекинг даёт ещё и общую память: коллега видит ваши эксперименты и не повторяет неудачные ветки.

Анатомия run

Единица трекинга в MLflow — run (запуск). У него есть:

  • params — входные гиперпараметры (learning_rate, n_estimators);
  • metrics — результаты (accuracy, f1, loss), можно логировать по шагам;
  • artifacts — файлы: сама модель, графики, матрица ошибок;
  • tags — пометки (git-коммит, автор, версия данных).

Runs группируются в experiments (например, «fraud-detector»). UI MLflow позволяет отсортировать runs по метрике и сравнить параметры рядом.

Пример логирования

import mlflow

mlflow.set_experiment("fraud-detector")

with mlflow.start_run():
    mlflow.log_param("n_estimators", 200)
    mlflow.log_param("max_depth", 8)

    model = train(...)            # ваше обучение
    acc = evaluate(model, X_val)

    mlflow.log_metric("val_accuracy", acc)
    mlflow.log_artifact("confusion_matrix.png")
    mlflow.sklearn.log_model(model, "model")
    mlflow.set_tag("git_sha", "a1b2c3d")

Сравнение запусков своими руками

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

runs = [
    {"id": 1, "lr": 0.10, "depth": 4, "f1": 0.881},
    {"id": 2, "lr": 0.05, "depth": 8, "f1": 0.913},
    {"id": 3, "lr": 0.20, "depth": 6, "f1": 0.897},
    {"id": 4, "lr": 0.05, "depth": 12, "f1": 0.905},
]

best = max(runs, key=lambda r: r["f1"])
print("Все запуски (по убыванию f1):")
for r in sorted(runs, key=lambda r: -r["f1"]):
    print(f"  run {r['id']}: lr={r['lr']} depth={r['depth']} f1={r['f1']:.3f}")
print(f"Лучший: run {best['id']} c f1={best['f1']:.3f}")

Вывод:

Все запуски (по убыванию f1):
  run 2: lr=0.05 depth=8 f1=0.913
  run 4: lr=0.05 depth=12 f1=0.905
  run 3: lr=0.2 depth=6 f1=0.897
  run 1: lr=0.1 depth=4 f1=0.881
Лучший: run 2 c f1=0.913

Как работает под капотом

MLflow Tracking — это сервер (или локальная папка mlruns/) с двумя хранилищами: бэкенд для параметров/метрик (БД или файлы) и хранилище артефактов (диск/S3). Клиент при log_* шлёт записи на сервер. Каждый run получает уникальный run_id, по которому позже модель регистрируют в реестре. Так трекинг (как получили) и реестр (что в проде) связаны.

Частые ошибки

  • Логировать метрику, но не параметры. Знать «было 0.91» бесполезно, если не знаешь, при каких настройках.
  • Не сохранять версию данных и git-коммит в тегах. Без них run невоспроизводим.
  • Сравнивать runs из разных датасетов как равные. Метрики сопоставимы только на одном валидационном наборе.

Итог

  • Трекинг экспериментов фиксирует параметры, метрики и артефакты каждого запуска, делая выбор лучшей модели объективным.
  • Run в MLflow связывает «как получили модель» с её регистрацией в реестре через run_id.
  • Для воспроизводимости логируйте не только метрики, но и параметры, версию данных и git-коммит.
Проверьте себя
1. Что такое run в MLflow?
AСервер для инференса
BЕдиничный запуск обучения с его параметрами, метриками и артефактами
CВерсия датасета
DСтадия модели в реестре
2. Почему важно логировать параметры, а не только метрики?
AПараметры красивее выглядят
BБез параметров нельзя понять, при каких настройках получена метрика, и воспроизвести результат
CМетрики логировать нельзя
DПараметры ускоряют обучение
3. Как трекинг связан с реестром моделей?
AНикак не связан
BЧерез run_id: модель из конкретного run регистрируется в реестре
CОни хранят одно и то же
DРеестр заменяет трекинг