4.1.2 · блок 4
Артефакты и воспроизводимость
Артефакты и воспроизводимость
Зачем это нужно
«У меня локально accuracy 0.91, а в prod модель ведёт себя иначе» — классическая боль. Причины часто не в «магии prod», а в разных версиях кода, данных и окружения. MLOps начинается с дисциплины артефактов: всё, что влияет на результат, должно быть зафиксировано, версионировано и связано друг с другом.
Воспроизводимость нужна не только ради аудита. Она позволяет откатиться, сравнить эксперименты, расследовать инцидент «модель начала врать» и доказать регулятору, на чём обучалась модель.
Основные идеи
Что такое ML-артефакт. Любой объект, который можно сохранить и передать дальше по pipeline:
| Артефакт | Пример | Где хранить |
|----------|--------|-------------|
| Код | commit SHA, tag | Git |
| Данные | snapshot parquet, версия датасета | S3 / data lake + manifest |
| Модель | `.pkl`, ONNX, SavedModel | Model registry, artifact store |
| Окружение | `requirements.txt`, Docker image digest | Git + container registry |
| Конфиг обучения | YAML hyperparameters | Git / experiment tracker |
| Метрики | F1, calibration plot | ClearML / MMS |
Reproducibility triad (триада воспроизводимости).
1. Code — тот же commit.
2. Data — тот же snapshot (или детерминированный query + seed).
3. Environment — тот же образ или lockfile.
Изменение любого leg triad — новый эксперимент, не «мелкий фикс».
Детерминизм vs стохастика. Обучение с random_state=42 и фиксированным порядком батчей даёт повторяемый результат. На GPU некоторые ops недетерминированы — документируйте это в model card.
Immutable artifacts. Образ scorer:latest перезаписали — старая версия потеряна. Правило курса: тег = gitSha-buildNumber или semver + digest. Никогда не деплоить mutable latest в prod.
Lineage (происхождение). Цепочка: dataset v3 → train job #8842 → model v1.2.3 → deploy release 17. Без lineage вы не ответите на вопрос «какие данные были в prod вчера в 3:00».
Model serialization. scikit-learn: joblib.dump / load. Важно: версия sklearn при save и load должна совпадать (или быть совместимой). pickle и joblib.load могут выполнить произвольный код — загружайте только доверенные, проверенные артефакты. Для production предпочитайте подписанные артефакты; где подходит, переносимые форматы ONNX или skops. В CI — тест «загрузить модель из artifact и вызвать predict на фикстуре».
Конфиг vs код. Гиперпараметры в YAML рядом с кодом или в experiment tracker — не «зашиты в ноутбук ячейкой 47». Notebook — прототип; prod pipeline — скрипт + config.
Как это выглядит на практике
Команда переобучает churn-модель:
1. Data engineer публикует churn_features_2026-07-28.parquet с manifest (hash, row count, schema version).
2. Train job (локально или в Argo WF) читает manifest, логирует hash в ClearML.
3. На выходе: model.joblib, metrics.json, confusion_matrix.png — все привязаны к Task ID в ClearML.
4. Jenkins собирает inference-образ с pin scikit-learn==1.4.2 из lockfile; model копируется в образ или монтируется из registry по URI models/churn/v1.2.3.
5. MMS регистрирует запись: model id, ClearML task, image tag, approver.
Через месяц инцидент: drift по фиче tenure. SRE открывает MMS → видит lineage → поднимает тот же train config + dataset snapshot → воспроизводит обучение → сравнивает метрики.
Anti-pattern (избегайте):
model_final_v2_REALLY_FINAL.pkl на рабочем столе
requirements «поставил вручную, вроде работает»
Что сделать после занятия
- [ ] Для учебного проекта перечислите все артефакты от данных до deploy и укажите, где каждый версионируется.
- [ ] Добавьте в репозиторий
requirements.lockили pin версий в Dockerfile. - [ ] Напишите однострочный manifest датасета: path, sha256, date, schema_version.