MLOps Path

6.1.2 · блок 6

Качество данных и версионирование

Качество данных и версионирование

Зачем это нужно

«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.

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:

1. Row count > 10 000 (не пустой export).

2. null_rate(feature_*) < 5% для каждой фичи.

3. Label distribution: churn rate между 5% и 40% (не сломанная выборка).

4. 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 — воспроизводимость.

Что сделать после занятия

Официальные материалы

Открыть интерактивную версию