Содержание
  1. Разделение кода Git, метаданных DVC и содержимого в cache
  2. Инициализация и добавление первого CSV
  3. Что фиксировать в Git, а что исключает .gitignore
  4. Вторая версия датасета и согласованный коммит
  5. Восстановление Git metadata плюс dvc checkout
  6. Remote push/pull и отличие local cache от резервной копии
  7. Матрица четырёх случаев наличия metadata/cache/remote и точный контроль строк
  8. Частые вопросы
Гайды

Как версионировать датасет с DVC и Git

12 ноября 2026 · 12 минут чтения

Как версионировать датасет с DVC и Git: код и метаданные живут в Git, содержимое — в DVC cache, а связывает их файл .dvc. Git хранит историю коммитов и лёгкие указатели, DVC — сами байты данных. Восстановление версии требует обоих слоёв: git checkout возвращает метаданные, dvc checkout подтягивает содержимое из cache.

Разделение кода Git, метаданных DVC и содержимого в cache

DVC — свободный инструмент с открытым исходным кодом для управления данными, автоматизации ML-пайплайнов и управления экспериментами. Это описание даёт официальный User Guide проекта. Там же сказано, что DVC опирается на привычный инженерный набор: Git, IDE, CI/CD, облачное хранилище. Принцип кодификации из того же руководства требует описывать версии данных, моделей, пайплайны и эксперименты в человекочитаемых метафайлах.

Практически это три слоя. Первый — код: скрипты обучения, конфиги, ноутбуки. Он лежит в Git и версионируется обычными коммитами. Второй — метаданные: файлы .dvc, которые DVC создаёт и обновляет при отслеживании данных. Документация команды dvc add называет такие файлы лёгкими указателями на ваши данные. Третий — содержимое: сами CSV, архивы, модели. Оно попадает в DVC cache, локальное хранилище на диске.

Связь между слоями односторонняя по смыслу и двусторонняя по работе. .dvc-файл знает хэш содержимого и путь к нему. Git знает, какая версия .dvc-файла относится к какому коммиту кода. Cache знает, где лежат байты. Ни один слой по отдельности не даёт воспроизводимую версию датасета.

Проверить разделение можно глазами. После первого dvc add в репозитории появляются два новых объекта: сам .dvc-файл и запись в .gitignore, которая закрывает исходный CSV от Git. Команда git status показывает новый .dvc-файл; сам CSV исключён правилами .gitignore. Это и есть точка, где заканчивается зона Git и начинается зона DVC.

Ошибка новичка — закоммитить CSV напрямую, минуя dvc add. Тогда история файла уходит в Git, размер репозитория растёт, а .dvc-файла нет, и dvc checkout нечего восстанавливать. Второй частый промах — добавить .dvc-файл в .gitignore вместе с данными. Метаданные обязаны попасть в Git, иначе связь между коммитом и версией данных теряется безвозвратно.

Инициализация и добавление первого CSV

Установка описана в стартовом руководстве DVC: проще всего поставить инструмент через uv или pipx, а затем проверить доступность командой dvc --help. Если выводится список команд, можно продолжать. Дальше в пустом репозитории выполняется dvc init — команда создаёт служебные файлы DVC внутри .dvc/ и подготавливает проект к отслеживанию данных.

Учебный пример, на котором удобно пройти весь цикл: файл data/train.csv с колонками id,label. Версия v1 содержит две записи, версия v2 добавляет третью. Реальные хэши в примере не нужны, обозначим их как <hash_v1> и <hash_v2>.

Порядок действий для первой версии:

ТЕРМИНАЛ
mkdir -p data
printf 'id,label\n1,yes\n2,no\n' > data/train.csv
git init
dvc init
git add .dvc .dvcignore
git commit -m "init dvc"
dvc add data/train.csv
git add data/train.csv.dvc data/.gitignore
git commit -m "dataset-v1"

Разберём, что произошло на каждом шаге. dvc init создал каталог .dvc/ с конфигом и внутренними файлами. dvc add data/train.csv посчитал хэш содержимого, положил копию в cache и создал data/train.csv.dvc — текстовый файл с хэшем и размером. Заодно DVC дописал в data/.gitignore строку, закрывающую сам CSV. Коммит dataset-v1 зафиксировал в Git только метаданные.

Синопсис команды dvc add из справочника включает флаги -f, --no-commit, --glob, -o, --to-remote, -r, --remote-jobs, --no-relink и список целей. Для первого CSV достаточно базовой формы без флагов. Флаг --to-remote пригодится позже, когда появится настроенный remote и понадобится залить данные сразу туда, минуя локальный cache.

Проверка результата: cat data/train.csv.dvc показывает YAML с полем md5 и полем size. git log --oneline показывает коммит dataset-v1. dvc status сообщает, что данные в актуальном состоянии. Если dvc status пишет о расхождении, значит содержимое файла изменилось после dvc add и метаданные устарели.

Что фиксировать в Git, а что исключает .gitignore

Правило простое: в Git идут метаданные и код, в .gitignore — содержимое. DVC сам ведёт data/.gitignore и дописывает туда имена отслеживаемых файлов. Руками этот файл трогать не нужно, кроме случаев, когда вы добавляете в игнор посторонние артефакты: логи, временные выгрузки, локальные конфиги с секретами.

Таблица распределения объектов по слоям:

Объект Где живёт Кто создаёт Попадает в Git
train.py, ноутбуки рабочая копия вы да
data/train.csv.dvc рабочая копия dvc add да
data/.gitignore рабочая копия dvc add да
.dvc/config рабочая копия dvc init, dvc remote да
data/train.csv рабочая копия вы нет
содержимое cache .dvc/cache dvc add нет

Секреты в команды и конфиги не пишутся. Ключи доступа к облачному хранилищу держите в переменных окружения или в отдельном файле вне репозитория. Если ключ всё же попал в .dvc/config, его нужно отозвать у провайдера и заменить, поскольку история Git хранит старые значения.

Отдельно про .dvcignore. Этот файл работает как .gitignore, только для обхода дерева командой DVC. Он полезен, когда внутри отслеживаемого каталога лежат временные файлы, которые не должны влиять на хэш. Добавление лишней строки в .dvcignore меняет набор данных, попадающих под хэш, и приводит к новой версии при следующем dvc add.

Проверка корректности игнора: git check-ignore -v data/train.csv покажет строку из data/.gitignore, которая закрывает файл. Если команда ничего не выводит, CSV не игнорируется и может случайно уйти в коммит. Второй контроль — git status --short после dvc add: в списке должны быть только .dvc-файл и изменённый .gitignore.

Вторая версия датасета и согласованный коммит

Вторая версия отличается от первой содержимым. В учебном примере добавляется строка 3,yes. Порядок действий сохраняет согласованность метаданных и кода:

ТЕРМИНАЛ
printf 'id,label\n1,yes\n2,no\n3,yes\n' > data/train.csv
dvc add data/train.csv
git add data/train.csv.dvc
git commit -m "dataset-v2"

Ключевой момент — dvc add перезаписывает .dvc-файл новым хэшем <hash_v2>. Старое содержимое остаётся в cache под хэшем <hash_v1>, поэтому обе версии доступны локально. Коммит dataset-v2 фиксирует в Git новый указатель. Теперь история выглядит так: коммит dataset-v1 ссылается на <hash_v1>, коммит dataset-v2 — на <hash_v2>.

Согласованность означает, что код и данные меняются одним коммитом или парой соседних. Если вы обновили CSV, но забыли закоммитить .dvc-файл, коллега получит старые метаданные и старую версию данных при dvc checkout. Если закоммитили .dvc-файл, но не запушили содержимое в remote, коллега получит метаданные без байтов.

Проверка второй версии: dvc status показывает актуальное состояние, git log --oneline показывает коммиты dataset-v1 и dataset-v2, wc -l data/train.csv считает все строки вместе с заголовком. Сравнить версии можно через dvc diff, если в проекте настроены обе точки истории.

Полезная привычка — писать в сообщении коммита, что именно изменилось в данных. «dataset-v2: добавлена третья запись» читается лучше, чем «update data». Осмысленное сообщение коммита помогает позже найти нужную версию.

Восстановление Git metadata плюс dvc checkout

Справочник команды dvc checkout описывает её назначение прямо: команда обычно нужна после git checkout, git clone или любой другой операции, меняющей текущие dvc.lock или .dvc-файлы в проекте. Она восстанавливает соответствующие версии всех отслеживаемых DVC файлов и каталогов из cache в рабочую копию.

Сначала найдите через git log --oneline хэш коммита с сообщением dataset-v1. В команде ниже замените <коммит> этим хэшем; угловые скобки не вводятся:

ТЕРМИНАЛ
git checkout <коммит>
dvc checkout
wc -l data/train.csv

После git checkout <коммит> рабочая копия содержит .dvc-файл с хэшем <hash_v1>, а сам CSV на диске пока остаётся версией v2. Команда dvc checkout читает метаданные и подтягивает из cache содержимое с хэшем <hash_v1>. Результат — две записи данных, как в эталоне. Обратный переход к dataset-v2 повторяет ту же пару команд.

Синопсис dvc checkout включает флаги --summary, -d, -R, -f, --relink, --allow-missing и список целей. Цели ограничивают, что именно восстанавливать. Команда принимает пути к отслеживаемым файлам и каталогам, включая пути внутри отслеживаемых каталогов, .dvc-файлы и имена стадий из dvc.yaml. Это удобно в большом проекте: dvc checkout data/train.csv.dvc вернёт только один датасет.

Флаг --allow-missing полезен, когда часть данных отсутствует в cache и вы готовы продолжить работу с тем, что есть. Без флага команда сообщит об ошибке и остановится. Флаг -f заставляет перезаписать файлы в рабочей копии, даже если они изменены локально; применяйте его осознанно, поскольку несохранённые правки будут потеряны.

Проверка результата после возврата: dvc status должен показать отсутствие расхождений, wc -l — ожидаемое число строк, git status — чистую рабочую копию. Если dvc status сообщает о missing-файлах, значит содержимого с нужным хэшем нет в cache и его придётся подтянуть из remote.

Remote push/pull и отличие local cache от резервной копии

Локальный cache — рабочее хранилище на вашем диске. В нём находятся объекты, доступные для локального восстановления. Удаление каталога .dvc/cache убирает эту локальную копию объектов, а метаданные в Git остаются. Восстановить данные из одних метаданных невозможно: указатель без байтов бесполезен.

Remote — отдельное хранилище, куда данные копируются командой dvc push и откуда забираются командой dvc pull. Настроенный remote даёт вторую копию содержимого и позволяет коллегам получать данные без вашей машины. Документация DagsHub описывает интеграцию с DVC, включающую полностью настроенное удалённое объектное хранилище под управлением DVC, показ и сравнение отслеживаемых файлов, а также визуализацию пайплайнов.

Типовой цикл работы с remote:

ТЕРМИНАЛ
dvc remote add -d storage s3://my-bucket/dvcstore
dvc push
git push

На другой машине после git clone и git checkout выполняется dvc pull, который забирает нужные объекты из remote в локальный cache и сразу раскладывает их по рабочей копии. Если нужных объектов нет локально и remote недоступен, получить эту версию командой dvc pull не удастся.

Различие между cache и резервной копией принципиально. Cache — рабочий механизм, привязанный к проекту и машине. Резервная копия — отдельное хранилище с независимой судьбой. Один Git-репозиторий с метаданными не гарантирует возврат датасета: при потере cache без remote данные исчезают, хотя история коммитов цела.

Проверка remote: dvc remote list показывает настроенные хранилища, dvc status -c сравнивает cache с remote и сообщает, что нужно запушить или подтянуть. Команда dvc push перед завершением работы закрывает разрыв между локальным состоянием и удалённой копией.

Матрица четырёх случаев наличия metadata/cache/remote и точный контроль строк

Четыре комбинации покрывают большинство ситуаций при восстановлении версии. Таблица показывает, что доступно и какая команда приводит к результату.

Metadata в Git Cache локально Remote Результат Действие
есть есть не нужен локальное восстановление git checkout + dvc checkout
есть нет есть данные подтягиваются git checkout + dvc pull
есть нет нет данных недостаточно восстановить содержимое извне
нет любой любой связи с коммитом нет история утеряна

Разберём каждую строку. Первый случай — обычная работа на своей машине: метаданные в Git, содержимое в cache, переключение версий мгновенное. Второй случай — новая машина или очищенный cache при настроенном remote: dvc pull забирает объекты по хэшам из метаданных. Третий случай — метаданные есть, cache пуст, remote не настроен: команды восстановления не сработают, поскольку брать данные неоткуда. Четвёртый случай — CSV лежит на диске без .dvc-файла и без коммита: связать файл с историей проекта невозможно.

Условие второго случая требует доступного remote с нужным содержимым. Наличие URL и учётных данных само по себе датасет не порождает: если объект с требуемым хэшем в хранилище отсутствует, dvc pull сообщит об ошибке.

Точный контроль строк после каждого сценария:

ТЕРМИНАЛ
wc -l data/train.csv
head -n 3 data/train.csv
dvc status

Для v1 ожидаются 2 записи данных и 3 строки с заголовком; для v2 — 3 записи и 4 строки с заголовком. Эти значения получены подсчётом строк заданного CSV. Команда head показывает фактические строки, dvc status подтверждает соответствие метаданным. Такой тройной контроль ловит ситуацию, когда выполнен только git checkout: файл на диске остаётся от прежней версии, и число строк не совпадёт с ожидаемым.

Практический вывод из матрицы: держите remote настроенным с первого дня проекта. Локальный cache ускоряет работу, remote страхует от потери содержимого. Метаданные в Git без одного из двух хранилищ дают указатель на данные, которых может не оказаться под рукой.

Частые вопросы

Чем DVC отличается от Git LFS?

Оба инструмента решают задачу хранения больших файлов рядом с кодом, но архитектура разная. Git LFS подменяет файл указателем внутри самого Git и хранит содержимое на LFS-сервере. DVC выносит содержимое в отдельный cache и работает поверх обычного Git-репозитория, что даёт гибкость в выборе хранилища. Документация DagsHub описывает DVC как инструмент версионирования для ML-проектов, работающий поверх Git.

Можно ли версионировать датасет без remote?

Да, на одной машине цикл dvc add — git commit — git checkout — dvc checkout работает полностью локально. Локальное восстановление возможно, пока в cache есть нужные объекты. Для обмена в команде удобно настроить remote; защита от потери диска требует независимой копии содержимого.

Что делать, если dvc checkout не находит данные?

Команда ищет содержимое по хэшу из метаданных. Если объекта в cache нет, проверьте dvc status -c — он покажет расхождение с remote. При настроенном remote выполните dvc pull, чтобы забрать недостающие объекты. При отсутствии remote данные придётся восстанавливать из внешней копии.

Нужно ли коммитить файл .dvc отдельно от CSV?

.dvc-файл коммитится в Git, CSV — нет. Обычно dvc add и git add выполняются подряд, а затем идёт один коммит, фиксирующий новую версию метаданных. Разделять эти действия на разные коммиты можно, но тогда между ними репозиторий находится в несогласованном состоянии.

Как откатить датасет к предыдущей версии?

Найдите коммит с нужной версией через git log, выполните git checkout <коммит> и следом dvc checkout. Пара команд вернёт и метаданные, и содержимое. Проверьте результат через wc -l и dvc status, чтобы убедиться в соответствии ожидаемому числу строк.

Читайте также

3 материала