Skip to content

Pipeline DVC + Hydra Audit Report — SoccerPredictAI

Date: 2026-04-24 Auditor: GitHub Copilot (Claude Sonnet 4.6) Scope: DVC pipeline корректность, воспроизводимость, params coverage, Hydra/конфиги Method: анализ dvc.yaml, params.yaml, conf/, src/pipelines/


1. DAG Audit

1.1 Граф стадий

load_data_from_sources (always_changed)
    ├── validate_raw
    │       │
    │       └── export_metadata
    └── preprocessing
            ├── validate_finished
            ├── validate_future
            ├── feature_engineering
            │       │
            │       ├── validate_features
            │       └── split_data
            │               │
            │               ├── batch_inference (независимая ветка)
            │               │
            │               ├── classification_models
            │               │       │
            │               │       ├── ablation_study (параллельно)
            │               │       ├── tune_xgb
            │               │       │       │
            │               │       │       └── final_train
            │               │       │               │
            │               │       │               └── register_model
            │               └── (train_ids → tune_xgb)

Полная таблица стадий (15 стадий)

Стадия Deps (файлы) Outs Params
load_data_from_sources src/pipelines/source.py, src/data/source.py match.parquet, match_raw.parquet + .minio.json × 2
validate_raw match_raw.parquet ge_raw.json
export_metadata match_raw.parquet 8 × metadata/*.json
preprocessing match_raw.parquet finished.parquet, future.parquet preprocessing.score_outlier_pct
validate_finished finished.parquet ge_finished.json
validate_future future.parquet ge_future.json
feature_engineering finished.parquet features.parquet, features_meta.parquet features.stats_cols, features.window_sizes, features.elo
validate_features features.parquet, features_meta.parquet ge_features.json data_quality.ge_sample_rows
split_data finished.parquet, features.parquet dataset.parquet, train_ids.parquet, test_ids.parquet, folds.parquet temporal.*
batch_inference future.parquet, finished.parquet, features_meta.parquet, metadata/*.json match_features.parquet features.stats_cols, features.elo, classification.side, classification.window_sizes
classification_models dataset.parquet, train_ids, test_ids, folds, features_meta run_id.json classification.*
ablation_study dataset.parquet, train_ids, test_ids, folds, features_meta ablation_summary.json classification.target_col/side/cat_cols/window_sizes, ablation.*
tune_xgb dataset.parquet, train_ids, folds, features_meta xgb_best_params.json classification.target_col/side/cat_cols/window_sizes, tuning.*
final_train dataset.parquet, train_ids, test_ids, features_meta, run_id.json, xgb_best_params.json final_run_id.json classification.*, final_train.calibration
register_model final_run_id.json registered_model.json register_model.model_name, register_model.model_stage

1.2 Корректность deps

Стадия Проблема Severity
validate_raw Нет dep на src/data_quality/raw.py — изменение validation logic не тригерит ре-ран P2
validate_finished Нет dep на src/data_quality/finished.py P2
validate_future Нет dep на src/data_quality/future.py P2
split_data Dep на src/pipelines/validation.py (не splitting.py!) — misnamed? Нет dep на src/pipelines/preprocess.py P1
batch_inference Нет dep на data/metadata/stageId.json, regionId.json и др. — зависит только от 2 из 8 metadata файлов P2
tune_xgb Нет dep на data/splits/test_ids.parquet (правильно — tuning не смотрит holdout)
ablation_study Нет dep на data/splits/test_ids.parquet несмотря на то что make_classification_runs получает df_test_ids P1
register_model Нет dep на data/models/run_id.json из classification_models — использует только final_run_id.json ✅ правильно

Особые замечания

⚠️ load_data_from_sources: always_changed: true — форсирует ре-ран при каждом dvc repro. Это намеренно (MinIO polling), но означает весь pipeline будет пересчитываться при каждом запуске если input изменился.


1.3 Корректность outs

Стадия Проблема
load_data_from_sources match.parquet объявлен как out, но не является dep ни в одной downstream стадии — мёртвый артефакт
validate_* GE JSON файлы (ge_*.json) являются outs, но не используются как deps downstream — только для информации
ablation_study ablation_summary.json не является dep для downstream stages — результаты ablation не влияют на model selection

2. Params Audit

2.1 Инвентаризация params

Parameter path В dvc.yaml Используется в коде Влияет на результат Статус
preprocessing.score_outlier_pct ✅ preprocess.py used
features.stats_cols ✅ features.py, inference.py used
features.window_sizes ✅ features.py used
features.elo (блок) ✅ features.py, inference.py used
data_quality.ge_sample_rows ✅ validate_features.py used
temporal.test_start ✅ splitting.py used
temporal.folds_start_year ✅ splitting.py used
temporal.folds_end_year ✅ splitting.py used
classification.target_col used
classification.experiment_name used
classification.fracs_for_train used
classification.side used
classification.cat_cols used
classification.window_sizes used
tuning.n_trials used
tuning.frac used
tuning.study_name used
ablation.experiment_name used
ablation.feature_sets used
ablation.fracs_for_train used
final_train.calibration (блок) used
register_model.model_name used
register_model.model_stage used

Параметры без dead/missing статуса. Все объявленные params реально используются в коде.

⚠️ Не в params.yaml, но в коде: - Порядок preprocessing (drop columns list) — hardcoded в src/data/preprocess.py - _SYNC_TIMEOUT = 30 — hardcoded в src/app/routers/predict.py - RabbitMQ credentials default amqp://guest:guest@rabbitmq:5672// — в src/app/connections/broker.py как fallback


3. Pipeline Reproducibility

Гарантии воспроизводимости

Аспект Статус Примечание
params.yaml полностью покрывает ML параметры
DVC отслеживает все deps/outs ✅ (с исключениями выше)
dvc.lock фиксирует хэши артефактов
Random seed ⚠️ Частично logreg/sgd seed=42, HGBT/DummyClassifier нет explicit seed, Optuna нет seed
MLflow tracking URI ✅ из environment MLFLOW_TRACKING_URL
MinIO артефакты ✅ через boto3 env vars

always_changed импликации

load_data_from_sources: always_changed: true — pipeline всегда выполняет эту стадию. Поскольку outs имеют persist: true, DVC не будет стирать файлы, но будет пересчитывать их при каждом dvc repro.


4. Hydra / Conf

Состояние conf/ directory

conf/
    config.yaml
    ablation/
    classification/
    data_quality/
    experiment/
    features/
    final_train/
    preprocessing/
    register_model/
    temporal/
    tuning/

⚠️ Hydra конфиги существуют (conf/), но pipeline стадии не используют Hydra — они вызывают load_params() из src/data/params.py напрямую из params.yaml. Hydra conf/ присутствует в репозитории, но не подключён к CLI entrypoints.

Аспект Статус
params.yaml как конфиг источник
conf/ директория 📋 Создана, не интегрирована в CLI
@hydra.main в pipeline entrypoints ❌ не используется
Hydra-compose или initialize ❌ не обнаружено

5. Findings

ID Severity Описание
P-01 P1 split_data dep: src/pipelines/validation.py вместо src/data/splitting.py — возможный misname, или splitting logic не отслеживается
P-02 P1 ablation_study нет dep на test_ids.parquet, но код make_classification_runs получает df_test_ids
P-03 P1 validate_* стадии не имеют dep на соответствующие src/data_quality/*.py — изменение GE expectations не триггерит re-run
P-04 P1 Hydra conf/ существует, но не интегрирован в pipeline — параллельная конфиг система создаёт confusion
P-05 P2 match.parquet объявлен как out в DVC, но не используется ни одной downstream стадией
P-06 P2 Нет explicit random seed для HGBT и Optuna study — полная воспроизводимость под вопросом
P-07 P2 batch_inference не зависит от load_data_from_sources явно, только через preprocessing — порядок не гарантирован при параллельном исполнении