DVC (Data Version Control) versionne les données comme Git versionne le code, sans mettre les données dans Git. Il écrit dans le dépôt un petit fichier pointeur qui contient l'empreinte du jeu, et envoie le jeu lui-même dans un stockage objet S3. Revenir à un ancien commit Git permet alors de retrouver, octet pour octet, les données qui allaient avec.
Cette leçon fait suite à celle sur le
projet reproductible : le code, la graine
et les bibliothèques sont fixés, il reste la source de variation la plus
traître, les données. Public : intermédiaire. On y suit un fichier avec
dvc add, on le pousse dans un bucket Garage, on le restitue sur un clone
vierge, puis on retrouve une version antérieure.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Expliquer pourquoi Git ne convient pas aux données volumineuses et ce que DVC y ajoute.
- Suivre un fichier avec
dvc addet lire le pointeur qu'il écrit. - Configurer un remote S3 sans mettre les clés d'accès dans le dépôt.
- Pousser et récupérer un jeu avec
dvc pushetdvc pull. - Retrouver une version antérieure d'un jeu par
git checkoutpuisdvc checkout. - Contrôler que cache local, bucket et dépôt sont synchronisés avec
dvc status.
Quels sont les prérequis ?
Section intitulée « Quels sont les prérequis ? »La leçon suppose la leçon sur le
projet reproductible (uv, empreinte
SHA-256, .gitignore) et la pratique de Git avec un dépôt distant
(collaborer avec des remotes).
Il faut aussi Docker, car le lab fournit un stockage S3 local sous forme de
conteneur. Un bucket S3 est un espace de stockage objet adressé par un nom ;
Garage en est une implémentation légère, et
le comparatif S3 aide à choisir en
production. Les versions mesurées : DVC 3.67.1, dvc-s3 3.3.0,
Garage v2.4.1.
Pourquoi ne pas mettre les données dans Git ?
Section intitulée « Pourquoi ne pas mettre les données dans Git ? »Git est conçu pour de petits fichiers texte dont chaque version se compare ligne à ligne ; un jeu de données lourd ou binaire le fait gonfler sans rien lui apprendre. Chaque nouvelle version du fichier alourdit l'historique, tout clone télécharge cet historique en entier, et personne ne peut relire un diff de plusieurs millions de lignes de CSV.
DVC garde de Git ce qu'il fait bien (l'historique, les branches, le lien avec le
commit) et déplace ailleurs ce qui pèse. Le dépôt ne contient plus que le
fichier pointeur, quelques lignes de texte qui désignent le contenu par son
empreinte. Les données, elles, vont dans un remote, ici un bucket S3.
Le pointeur est versionné avec le code : le commit qui change le code et le
commit qui change le jeu sont donc les mêmes, et un git checkout suffit à
dire « donne-moi les données de ce moment-là ».
Comment DVC, Git et S3 se partagent-ils le travail ?
Section intitulée « Comment DVC, Git et S3 se partagent-ils le travail ? »Le fichier de données reste sur le poste mais Git l'ignore ; Git reçoit le pointeur et la configuration du remote, S3 reçoit le contenu. Trois emplacements, trois rôles, et une empreinte qui les relie.
Sur le schéma, dvc add copie le fichier dans le cache local
(.dvc/cache). Suivez les flèches épaisses : dvc push envoie ce cache vers
le bucket, dvc fetch remplit le cache depuis le bucket, et dvc checkout
restitue le fichier dans le poste. dvc pull enchaîne les deux : fetch puis
checkout, d'où le « 1 file fetched and 1 file added » qu'il affiche. La flèche pointillée est celle de Git : le
clone récupère le pointeur, jamais les données. C'est pourquoi un clone sans
dvc pull n'a pas le jeu.
Comment suivre un fichier avec DVC ?
Section intitulée « Comment suivre un fichier avec DVC ? »dvc add calcule l'empreinte du fichier, le copie dans le cache local de
DVC (.dvc/cache), écrit le pointeur et demande à Git d'ignorer le fichier.
On l'exécute après avoir installé DVC dans l'environnement uv (uv add dvc dvc-s3, le second paquet apportant le support S3), puis initialisé Git et DVC
dans le projet :
uv add dvc dvc-s3git inituv run dvc initmkdir -p datauv run python genere-metriques.py --graine 42 --lignes 5000 --sortie data/metriques.csvsed -i '/^data\/metriques.csv$/d' .gitignoreuv run dvc add data/metriques.csvLe mkdir -p data est indispensable : le générateur n'écrit pas dans un
dossier absent. Le sed retire du .gitignore racine la ligne posée dans la leçon
précédente : le CSV change de propriétaire, c'est maintenant DVC qui l'ignore.
Si la ligne reste, dvc add réussit sans message, mais il n'écrit pas le
data/.gitignore, et le git add data/.gitignore plus bas échoue avec
fatal: pathspec 'data/.gitignore' did not match any files.
dvc init crée le répertoire .dvc/ avec la configuration, qui se
versionne. dvc add écrit le pointeur data/metriques.csv.dvc et ajoute le
fichier de données à un data/.gitignore. Le pointeur a cette forme :
outs:- md5: <empreinte MD5 du fichier> size: <taille en octets> hash: md5 path: metriques.csvDVC identifie les fichiers par une empreinte MD5, différente du SHA-256 que le lab utilise pour ses vérifications : les deux désignent le même contenu, mais seule la première est écrite dans le pointeur. C'est ce pointeur, et non le CSV, qui entre dans Git.
Comment configurer un remote S3 sans mettre les clés dans le dépôt ?
Section intitulée « Comment configurer un remote S3 sans mettre les clés dans le dépôt ? »Le remote est déclaré dans .dvc/config (adresse, région, point d'accès), les
clés viennent de l'environnement. Le dépôt peut ainsi voyager avec sa
configuration sans jamais porter un secret. Pour le bucket Garage du lab :
uv run dvc remote add -d stockage s3://dvc-donneesuv run dvc remote modify stockage endpointurl http://127.0.0.1:3900uv run dvc remote modify stockage region garageL'option -d fait de stockage le remote par défaut. Le point d'accès
(endpointurl) est nécessaire parce que le stockage n'est pas AWS ; la région
garage est celle que le conteneur Garage déclare. Les clés d'accès se
fournissent par les variables AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY,
que DVC, MLflow et boto3 lisent telles quelles. Le lab les met dans un fichier
.env généré, ignoré par Git, que le script scripts/socle-demarrer.sh
crée en même temps qu'il démarre le stockage (voir « Mettre en pratique »). Dans
le terminal où vous lancez DVC, chargez-le ainsi, <catalogue> désignant le
dossier du catalogue de labs :
set -a && . <catalogue>/shared/socle/.env && set +aCes variables n'existent que dans ce terminal : un nouveau terminal, ou un clone ouvert ailleurs, demande de refaire ce chargement.
Comment pousser le jeu et le retrouver sur un clone vierge ?
Section intitulée « Comment pousser le jeu et le retrouver sur un clone vierge ? »On commite le pointeur, puis dvc push envoie le contenu au bucket ; un
clone récupère ensuite le pointeur par Git et le contenu par dvc pull. Ces
deux gestes sont indissociables : un commit sans push laisse un pointeur qui ne
désigne rien d'accessible aux autres.
git add data/metriques.csv.dvc data/.gitignore .dvc pyproject.toml uv.lock genere-metriques.py .gitignoregit commit -m "Jeu de données, graine 42"uv run dvc pushLe commit embarque aussi le verrou uv.lock : sans lui, le clone ne saurait
pas quel environnement reconstruire. Après le commit, git status ne doit
lister aucun fichier. Sur le lab, dvc push annonce un fichier poussé. Sur un
autre poste, ou dans un dossier neuf (avec les variables d'accès chargées,
comme plus haut) :
git clone <depot> clone && cd cloneuv run dvc pullsha256sum data/metriques.csvdvc pull annonce un fichier récupéré, et l'empreinte SHA-256 doit être
celle mesurée avant le push : 550be1a3… pour la graine 42. C'est la preuve que
le clone a les octets exacts, pas seulement un fichier du même nom.
Comment retrouver une version antérieure du jeu ?
Section intitulée « Comment retrouver une version antérieure du jeu ? »Chaque commit Git désigne, par son pointeur, une version précise des données : revenir au commit revient aux données. Le scénario du lab est celui d'un jeu régénéré avec une autre graine. On suit la nouvelle version comme la première, dans un second commit :
uv run python genere-metriques.py --graine 43 --lignes 5000 --sortie data/metriques.csvuv run dvc add data/metriques.csvgit add data/metriques.csv.dvcgit commit -m "Jeu de données, graine 43"uv run dvc pushLe jeu de la graine 43 a une empreinte SHA-256 qui commence par 65e665e5.
Le bucket contient maintenant deux versions. Pour revenir à la
première :
git checkout <commit-graine-42>uv run dvc checkoutgit checkout remet l'ancien pointeur (Git signale un HEAD détaché, sans
gravité : git switch - revient ensuite à la branche), dvc checkout remplace
le fichier de données par la version qu'il désigne, prise dans le cache
local. Sur un clone
vierge qui n'a jamais eu cette version, c'est dvc pull qui la télécharge. Le
retour à la graine 42 redonne l'empreinte 550be1a3…. La même procédure permet
de retrouver, plus tard, le jeu qui a servi à entraîner un modèle donné : il
suffit d'avoir le commit.
Comment vérifier que tout est synchronisé ?
Section intitulée « Comment vérifier que tout est synchronisé ? »dvc status compare le dépôt au cache local, dvc status -c compare le cache
au remote. Les deux réponses ne se ressemblent pas, et les confondre est une
erreur courante : une sortie « up to date » ne dit rien du bucket.
| Commande | Ce qu'elle compare | Réponse quand tout va bien |
|---|---|---|
dvc status | pointeurs et fichiers du projet | Data and pipelines are up to date. |
dvc status -c | cache local et remote | Cache and remote 'stockage' are in sync. |
Le contenu du bucket se contrôle aussi côté Garage. Garage n'a pas de
shell dans son conteneur : toute commande passe par docker compose exec
depuis le dossier du socle. La commande
docker compose exec -T garage /garage bucket info dvc-donnees affiche une
ligne Objects: qui doit compter les objets des deux versions.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Correction |
|---|---|---|
dvc pull échoue avec une erreur d'accès | Variables AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY absentes de l'environnement | Charger le .env du socle avant la commande |
dvc pull ne trouve pas le bucket | endpointurl ou region manquant dans .dvc/config | Relancer les deux dvc remote modify et commiter .dvc/config |
| Le clone n'a pas le fichier de données | dvc pull jamais lancé : Git ne transporte que le pointeur | Lancer dvc pull |
dvc status -c signale des fichiers à pousser | Le commit a été fait sans dvc push | Lancer dvc push |
git status montre data/metriques.csv | Le fichier n'a pas été suivi par dvc add | Lancer dvc add, puis commiter pointeur et data/.gitignore |
dvc add refuse un fichier déjà suivi par Git | Le CSV est déjà dans l'historique Git | git rm --cached data/metriques.csv et commiter, puis dvc add (DVC suggère git rm -r --cached) |
Mettre en pratique
Section intitulée « Mettre en pratique »Le lab part d'un jeu de graine 42 qui a été écrasé : il faut le mettre sous
DVC avec un remote S3 Garage, conserver deux versions (graines 42 et 43)
dans deux commits distincts, puis prouver qu'un clone vierge restitue le jeu
courant par dvc pull et que le retour au premier commit restitue le jeu de
graine 42. La validation lit le dépôt Git (qui doit rester propre), le
contenu du bucket, dvc status et dvc status -c sans écart, et les
empreintes des fichiers, jamais les commandes tapées. Avant dsoxlab run,
lancez le script scripts/socle-demarrer.sh du catalogue, qui démarre Garage ;
scripts/socle-arreter.sh l'arrête à la fin.
À retenir
Section intitulée « À retenir »- Git ne convient pas aux données lourdes ; DVC met un pointeur dans le dépôt et le contenu dans un remote.
dvc addsuit le fichier, écritfichier.dvcet fait ignorer le fichier par Git.- Un commit versionne le pointeur : revenir au commit, c'est revenir aux données.
dvc pushenvoie au remote,dvc pullrécupère ; un commit sans push laisse les autres sans données.- Un remote S3 non AWS demande
endpointurletregiondans.dvc/config; les clés restent dans l'environnement. dvc statusne dit rien du bucket : c'estdvc status -cqui compare cache et remote (in sync).- Retrouver une version :
git checkout <commit>puisdvc checkout(oudvc pullsur un clone qui ne l'a jamais eue).
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Pipeline DVC : rejouer un entraînement ML à l'identique
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications