Skip to content

MLflow Registry Audit Report — SoccerPredictAI

Date: 2026-04-24 Auditor: GitHub Copilot (Claude Sonnet 4.6) Scope: MLflow experiments, runs, lineage, Model Registry, aliases, naming Method: анализ src/utils/mlflow_meta.py, src/models/classification.py, src/models/final_train.py, src/pipelines/register_model.py, params.yaml, mlruns/


1. Experiments Structure

1.1 Инвентаризация экспериментов

По коду (mlflow_meta.py docstring):

Experiment name Назначение Активен
matches_clf production runs: train_eval, ablation, tuning, final_train ✅ (planned convention)
matches_clf_smoke smoke / fast-dev runs ✅ (текущий активный)

Текущий конфиг: params.yaml: classification.experiment_name = matches_clf_smoke — все runs пишутся в smoke эксперимент.

⚠️ P1: Весь production pipeline записывает в matches_clf_smoke, а не в matches_clf. Нет автоматического переключения между smoke и production экспериментами.

1.2 Naming conventions

Experiments: - matches_clf / matches_clf_smoke — единообразное именование ✅

Runs: | Тип run | Формат имени | Пример | |---------|-------------|--------| | Parent (train_eval) | [smoke \| ]train_eval \| frac={frac} \| feat={profile} | train_eval \| frac=0.001 \| feat=full | | Parent (ablation) | [smoke \| ]ablation \| variant={v} \| frac={frac} | ablation \| variant=elo_only \| frac=0.001 | | Child (model) | model \| {model_name} | model \| xgb | | XGB tuning parent | xgb_tuning_frac-{frac} | xgb_tuning_frac-0.1 | | Final train | [smoke \| ]final_train \| model={name} | final_train \| model=xgb |

✅ Именование консистентно.

Tags: | Tag | Значение | Логируется | |-----|----------|-----------| | pipeline.run_kind | smoke/train_eval/final_train | ✅ | | pipeline.stage | train_eval/ablation/final_train | ✅ | | pipeline.scope | parent/child | ✅ | | pipeline.variant | baseline/elo_only/etc | ✅ | | features.profile | full/elo_only/stats_only/no_h2h | ✅ | | model.family | gradient_boosting/linear/dummy | ✅ | | data.version | ETag из .minio.json | ✅ | | data.source_last_modified | MinIO LastModified | ✅ | | data.ingested_at | ingested_at из .minio.json | ✅ | | pipeline.git_sha | HEAD SHA | ✅ | | pipeline.params_hash | SHA256 params.yaml | ✅ |


2. Run Lineage

2.1 Parent / child runs

Структура:

Parent run: train_eval | frac=... | feat=...
    └── Child: model | baseline
    └── Child: model | logreg
    └── Child: model | sgd_logloss
    └── Child: model | hgb
    └── Child: model | xgb

✅ Nested runs используются корректно.

2.2 Data lineage

В каждом run логируются:

Поле Ожидается Логируется
data.version (ETag) build_data_lineage_tags()
data.source_last_modified
data.ingested_at
data.train_rows
data.test_rows
data.train_start / train_end
data.test_start
pipeline.git_sha
pipeline.params_hash
pipeline.dvc_exp_name ✅ (из env DVC_EXP_NAME)
dataset logged as MLflow input mlflow.log_input()

⚠️ P2: data.source_created_at явно не логируется (задокументировано в docstring — MinIO не предоставляет creation time отдельно от last_modified).


3. Model Registry

3.1 Структура Registry

Параметр Значение
Model name soccer_clf
Stage/Alias champion
Registration стадия register_model DVC stage
Тригер зависит от final_trainfinal_run_id.json

3.2 Registration logic (register_model.py)

# Идемпотентность: если alias уже указывает на run_id — skip
# Иначе: create version → set alias "champion"

✅ Idempotency реализована — повторный запуск с тем же run_id безопасен.

3.3 Champion/Challenger

Аспект Статус
Champion alias (champion)
Challenger pattern ❌ не реализован
Автоматическое A/B или shadow deployment ❌ не реализован
Ручная gate перед promotion 🚧 Требует ручного шага (status.md)

⚠️ P1: Нет champion/challenger сравнения — каждый final_train автоматически становится champion без сравнения с предыдущей моделью.


4. Registry → Serving Connection

# src/app/tasks/predict.py
_service = PredictionService(
    tracking_uri=settings.mlflow.tracking_uri,
    model_name=settings.mlflow.model_name,  # = "soccer_clf"
    model_stage=settings.mlflow.model_stage,  # = "champion"
)

✅ Serving загружает модель по alias champion — правильная связь registry → serving.

⚠️ P1: Нет graceful rollback механизма — если новый champion деградирует, нет автоматического revert.


5. Artifacts в MLflow

Артефакт Логируется
sklearn model (mlflow.sklearn)
confusion matrix plots plot_confusion_matrix_multiclass()
calibration curves plot_calibration_curves()
feature importance plots plot_feature_importance()
folds.csv
predictions / holdout CSV ✅ (в final_train)
segment metrics
ECE (raw + calibrated)

6. Findings

ID Severity Описание
ML-01 P1 Все runs пишутся в matches_clf_smoke — нет переключения на production experiment при production-запуске
ML-02 P1 Нет champion/challenger сравнения при регистрации — новая модель автоматически становится champion
ML-03 P1 Нет автоматического rollback при деградации модели после promotion
ML-04 P2 ablation_study runs пишутся в тот же эксперимент что и train_eval — нет явного разделения exploratory vs training runs
ML-05 P2 pipeline.dvc_exp_name берётся из env DVC_EXP_NAME — при запуске вне DVC env этот тег будет отсутствовать