Зачем это нужно
«Garbage in, garbage out» — не лозунг, а ежедневная реальность. Модель может быть идеальной, но если в prod пришли NULL вместо возраста клиента или схема изменилась без уведомления — predictions деградируют молча. Data quality и версионирование — страховка от этого.
MLOps-инженер отвечает не только за код пайплайна, но за контракты: что считается «хорошими» данными и как фиксируется, какая версия dataset использовалась при обучении.
Основные идеи
Измерения качества данных (упрощённо).
| Измерение | Вопрос | Пример проверки |
|---|---|---|
| Completeness | Все ли поля заполнены? | null_rate(age) < 0.01 |
| Validity | Значения в допустимых границах? | age BETWEEN 0 AND 120 |
| Uniqueness | Нет ли дубликатов ключей? | count(distinct user_id) = count(*) |
| Timeliness | Данные свежие? | max(event_ts) > now() - 1h |
| Consistency | Согласованы ли связанные поля? | if status='closed' then close_date IS NOT NULL |
Data validation vs model validation. Model validation — hold-out, cross-val, метрики ML. Data validation — до обучения: «можно ли вообще запускать train job на этом snapshot?». Если validation failed — train не стартует (fail fast).
Версионирование dataset.
Snapshot — неизменяемый срез данных на момент времени (
train_2026-01-15_v3.parquet).Version tag — semver или дата + hash схемы.
Связь с экспериментом — ClearML/MMS фиксирует: experiment X обучен на dataset v3.
Schema evolution. Добавление nullable колонки — обычно backward compatible. Удаление колонки или смена типа — breaking. Политика: schema registry (Avro/Protobuf в Kafka) или явный changelog в repo.
Great Expectations / dbt tests / custom checks — инструменты вторичны; важна идея: проверки в CI/CD data pipeline, алерт при нарушении.
Train/serve skew из-за качества. Train видел imputed age=median; serve получает NULL и другой imputation path → разные распределения. Решение: одинаковая логика imputation в training pipeline и serving (shared library или Feature Store).
Data contracts (контракты между командами). Команда CRM публикует контракт: «поле balance — float, обновляется daily, SLA 06:00 UTC». ML-команда строит зависимости на этом контракте. Нарушение контракта — incident для обеих сторон.
PII и compliance. Качество включает безопасность: нет ли PII в логах фич, соблюдён ли retention. Версионирование помогает audit: «какие данные использовались для модели v12?».
Как это выглядит на практике
Pre-train gate в Argo Workflow:
`
Упрощённый фрагмент DAG
- name: validate-dataset template: data-quality-check arguments: parameters: - name: dataset_uri value: "s3://ml-gold/churn/train_2026-01-15_v3/"
- name: train-model
dependencies: [validate-dataset]
стартует только если validate прошёл
`
Checks в validate-dataset:
Row count > 10 000 (не пустой export).
null_rate(feature_*) < 5%для каждой фичи.Label distribution: churn rate между 5% и 40% (не сломанная выборка).
Schema hash совпадает с
schemas/churn_v2.json.
При провале: Slack-алерт data team + блокировка train. DS не тратит GPU на мусор.
Версионирование в MMS (корпоративный реестр):
| Поле модели | Значение |
|---|---|
| model_version | v44 |
| training_dataset | churn/train_2026-01-15_v3 |
| feature_schema_hash | a3f9c2... |
| data_quality_report | link to artifact |
Rollback модели без знания dataset version — половина решения. Rollback вместе с dataset version — воспроизводимость.
Что сделать после занятия
Для одной фичи учебного проекта опишите 3 data quality check'а с порогами.
Сформулируйте data contract из 5 полей между «источником» и «ML-пайплайном».
Объясните разницу между «версия модели» и «версия dataset» — зачем хранить обе.