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 — порядок не гарантирован при параллельном исполнении