Версионирование данных с DVC
Git хранит код, но давится на гигабайтных датасетах — DVC решает эту проблему.
DVC (Data Version Control) — инструмент, который версионирует большие файлы данных и моделей поверх git, храня в репозитории лёгкие текстовые указатели, а сами данные — во внешнем хранилище.
Зачем версионировать данные
Представьте: модель в проде ошибается, вы хотите воспроизвести её обучение. Но датасет с тех пор обновился. Без версионирования данных вы не повторите результат — а значит, не отладите проблему. Версионирование данных даёт ответ на вопрос «на каких именно данных обучена эта модель» так же точно, как git отвечает «на каком коде».
Почему git не подходит
Git хранит полную историю каждого файла. Для кода это идеально, но датасет на 5 ГБ превратит репозиторий в десятки гигабайт после нескольких версий, а git diff бинарника бесполезен. DVC решает это разделением: метаданные — в git, данные — в объектном хранилище (S3, GCS, MinIO, диск).
Как работает .dvc-указатель
Когда вы делаете dvc add data/train.csv, DVC считает хеш файла, копирует его в кеш и создаёт маленький текстовый файл data/train.csv.dvc с этим хешем. В git коммитится только указатель — несколько строк:
outs:
- md5: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
size: 5242880
path: train.csv
Теперь git-коммит однозначно связан с конкретной версией данных через хеш. git checkout старого коммита + dvc checkout восстановят и код, и ровно те данные.
Удалённое хранилище
Команда dvc push отправляет данные из локального кеша в общее удалённое хранилище, а dvc pull забирает. Так датасет не лежит в git, но доступен всей команде и CI.
# настроить удалённое хранилище (S3-совместимое)
dvc remote add -d storage s3://my-bucket/dvcstore
# зафиксировать датасет
dvc add data/train.csv
git add data/train.csv.dvc data/.gitignore
git commit -m "data: train v1"
dvc push # данные -> S3, указатель -> git
Как работает под капотом
В основе — контентно-адресуемое хранилище: имя файла в кеше = его хеш содержимого. Одинаковые файлы хранятся один раз (дедупликация). Чтобы не копировать гигабайты, DVC по возможности использует reflink или хардлинк между рабочей директорией и кешем. Связь «коммит → данные» детерминирована: один и тот же хеш всегда означает один и тот же байт-в-байт датасет.
DVC-пайплайны
DVC умеет не только хранить данные, но и описывать этапы обработки в dvc.yaml с зависимостями. Тогда dvc repro пересчитает только то, что изменилось — как Makefile для данных.
stages:
prepare:
cmd: python prepare.py
deps: [data/raw.csv, prepare.py]
outs: [data/clean.csv]
train:
cmd: python train.py
deps: [data/clean.csv, train.py]
outs: [models/model.pkl]
Частые ошибки
- Закоммитить данные в git напрямую. Репозиторий распухнет; смысл DVC именно в том, чтобы этого избежать.
- Забыть
dvc push. Указатель в git есть, а данных в общем хранилище нет — у коллегиdvc pullупадёт. - Не коммитить .dvc-файл. Без него git-коммит не знает версию данных, и связь теряется.
Итог
- DVC версионирует большие данные и модели, храня в git лёгкие указатели с хешем, а данные — во внешнем хранилище.
- Пара «git-коммит + .dvc-указатель» однозначно фиксирует версию данных, обеспечивая воспроизводимость.
- DVC-пайплайны (
dvc.yaml) пересчитывают только изменившиеся этапы, как Makefile для ML.