Module 4 — Versionnage des données et des modèles
Le régulateur téléphone : « votre modèle a refusé un dossier client mercredi dernier, pouvez-vous me montrer sur quelles données il a été entraîné et avec quelles règles il a été validé ? » Sans versionnage des données, la réponse honnête est : « non ». Sans versionnage du modèle, la réponse honnête est : « nous ne savons même plus lequel a répondu ». Ce module rend ces deux réponses trivialement affirmatives.
Pourquoi Git ne suffit pas pour les données
Git est excellent pour du texte de moins d'un mégaoctet : il compresse bien, il diffe bien, il fusionne bien. Il est catastrophique pour un CSV de 2 Go : chaque version rejoue l'ensemble dans l'historique, le clone prend des heures, le serveur central étouffe.
DVC (Data Version Control) résout ce problème en gardant dans Git
uniquement des pointeurs vers les fichiers, et en stockant les fichiers
eux-mêmes ailleurs (S3, GCS, Azure Blob, un serveur SSH interne). Chaque
pointeur porte l'empreinte de hachage md5 du fichier, ce qui rend le
lien immuable.
# Ajout d'un jeu de données
dvc add data/churn_v3.csv
# git suit uniquement le pointeur
git add data/churn_v3.csv.dvc data/.gitignore
git commit -m "jeu de donnees churn v3 (janvier 2026)"
# Le fichier lui-même part sur le stockage distant
dvc push
Le fichier churn_v3.csv.dvc fait 60 octets et contient l'empreinte du
CSV. N'importe qui, sur n'importe quelle machine, peut faire git clone
puis dvc pull pour retrouver exactement le même CSV. Sans dvc pull,
le pointeur est là mais le contenu n'y est pas : c'est délibéré, cela
laisse le choix de télécharger ou pas selon le besoin.
Le lien commit / snapshot / modèle
La règle qui donne au versionnage sa valeur tient en une phrase : chaque
exécution de MLflow note trois identifiants.
| Identifiant | Ce qu'il désigne | Où on le stocke |
|---|---|---|
| Commit Git | Version exacte du code d'entraînement | mlflow.set_tag("commit_git", ...) |
| Empreinte du snapshot données | Contenu exact du CSV | mlflow.set_tag("donnees_md5", ...) |
run_id MLflow | Modèle produit et ses artefacts | Retourné par mlflow.start_run() |
Ces trois identifiants forment le lignage d'un modèle. Étant donné un
modèle en production, on remonte au run_id, puis au commit, puis au
snapshot. On peut alors relancer bit à bit l'entraînement. Sans l'un des
trois, la reproduction devient une enquête.
Écrire les données comme du code
DVC ne se contente pas de versionner des fichiers ; il permet de
décrire le pipeline qui les produit.
# dvc.yaml
stages:
telecharger:
cmd: python src/telecharger.py
deps: [src/telecharger.py]
outs: [data/brut.csv]
nettoyer:
cmd: python src/nettoyer.py
deps: [src/nettoyer.py, data/brut.csv]
outs: [data/propre.csv]
variables:
cmd: python src/variables.py
deps: [src/variables.py, data/propre.csv]
outs: [data/variables.parquet]
dvc repro rejoue uniquement les étages dont une dépendance a changé. Si
nettoyer.py bouge, seuls nettoyer et variables sont relancés ;
telecharger est sauté. C'est le même principe que make, transposé aux
données.
Versionner le modèle : trois écoles
Fichier .pkl dans DVC. Simple, mais mélange les responsabilités :
le versionnage des données et celui du modèle utilisent le même outil, ce
qui rend les recherches confuses.
Registre MLflow (module 5). Le modèle a son propre cycle de vie
(brouillon, en revalidation, en production, retiré), avec des étapes
formelles et une interface dédiée. C'est ce que la suite du cours utilise.
Une base versionnée dédiée (Weights & Biases, Neptune, DagsHub). Choix
raisonnable pour une grande équipe qui a déjà tranché son outillage ; le
cours en reste à MLflow par souci de continuité.
Quand une base versionnée suffit
Toutes les données ne méritent pas DVC. Une base de données transactionnelle
sur laquelle on tire un SELECT ... WHERE date = '2026-01-15' est déjà
versionnée si l'on stocke la requête et la date. C'est parfois la solution
la plus honnête : plutôt que d'exporter et de figer un CSV, on fige la
requête. Deux conditions rendent ce choix viable : la base est en
lecture seule pour la période concernée (pas de mise à jour rétroactive) et
le connecteur est aussi versionné que le reste.
Un fichier posé sur un partage réseau ou dans Google Drive n'est pas
versionné. Deux collègues qui le remplacent le même après-midi, l'un par
un extrait plus récent, l'autre par une version corrigée, produisent une
divergence silencieuse. DVC ne rend pas la collaboration plus complexe :
il rend la divergence impossible.
En résumé
- Git est fait pour le texte court,
DVCpour les grands fichiers ; le pointeur reste dans Git, le contenu part sur un stockage distant. - Chaque exécution
MLflowporte trois identifiants : commit code, empreinte du snapshot données,run_id. Ces trois-là suffisent au lignage. dvc.yamldécrit le pipeline de données ;dvc reprone rejoue que les étages dont les dépendances ont changé.- Une base versionnée en lecture seule peut remplacer
DVCsi l'on fige également la requête et le connecteur.
Le module 5 formalise le cycle de vie du modèle avec le registre MLflow :
étapes, alias, approbation.