À quoi ça sert

Git versionne très bien du code : du texte, des petits fichiers. Mais en MLOps, tu as aussi besoin de versionner deux autres choses :

  • Des datasets (un CSV de 500 Mo, un dossier d'images de 5 Go…).
  • Des modèles entraînés (un .pt PyTorch ou un .joblib scikit-learn de plusieurs centaines de Mo).

Tu ne peux pas mettre ces fichiers dans Git :

  • GitHub bloque les fichiers de plus de 100 Mo.
  • Chaque modification d'un binaire est stockée intégralement dans l'historique Git → le repo gonfle de manière exponentielle.
  • Cloner le repo devient insupportable après quelques mois.

DVC dédouble la stratégie : Git stocke des petits fichiers pointeurs (quelques lignes, un hash, des métadonnées) qu'on commit normalement, et les vrais fichiers binaires sont stockés ailleurs — sur un remote DVC, qui peut être MinIO, S3, Google Drive, un serveur SSH ou même un simple dossier local.

DVC vs Git LFS ?

Git LFS (Large File Storage) résout aussi le problème des gros fichiers, mais est couplé à GitHub (quota payant dès quelques Go) et n'apporte rien d'autre. DVC est gratuit, agnostique au backend de stockage, et propose en bonus des pipelines reproductibles (versionner aussi les étapes d'entraînement, pas juste les fichiers). En MLOps moderne, DVC s'est imposé.

Un exemple d'usage

Tu entraînes un modèle scikit-learn sur un dataset. Tu obtiens 87% d'accuracy, tu commits. Trois mois plus tard, tu modifies le code, l'accuracy tombe à 82%. Tu veux comparer exactement les deux versions.

bash
# Versionner le dataset et le modèle
dvc add data/train.csv
dvc add models/classifier.joblib

# DVC a créé deux petits fichiers pointeurs :
#   data/train.csv.dvc
#   models/classifier.joblib.dvc
# C'est ces .dvc qu'on commit dans Git.

git add data/train.csv.dvc models/classifier.joblib.dvc .gitignore
git commit -m "feat: modèle v1 (acc 87%)"

# Envoyer les vrais fichiers vers le remote (ex: MinIO)
dvc push

# 3 mois plus tard : revenir à la v1
git checkout <commit-v1>
dvc pull        # récupère le dataset ET le modèle de cette version

Avec Git seul, tu aurais le code des deux versions mais pas les modèles entraînés — il faudrait ré-entraîner pour comparer. Avec DVC, le checkout d'un commit ancien restaure aussi les données et le modèle de l'époque. C'est ça la vraie reproductibilité MLOps.

How-to : installer et utiliser DVC

  1. Installer DVC

    DVC est un outil global (comme Ruff ou pre-commit). On l'installe avec UV :

    bash
    uv tool install dvc

    Pour certains backends de stockage, il faut un extra :

    bash
    uv tool install "dvc[s3]"       # pour MinIO/S3
    uv tool install "dvc[gdrive]"   # pour Google Drive
    uv tool install "dvc[ssh]"      # pour un serveur SSH
  2. Initialiser DVC dans un repo Git

    Comme git init, à faire une fois par projet — dans un repo Git déjà initialisé :

    bash
    dvc init

    Ça crée un dossier .dvc/ (config DVC, à committer) et ajoute quelques lignes au .gitignore. Première étape suffit pour le reste.

  3. Versionner un fichier ou un dossier

    La commande clé, et le mime parfait de git add :

    bash
    dvc add data/raw/                  # un dossier entier
    dvc add models/best.pt              # un fichier précis

    Pour chaque cible, DVC crée un fichier <nom>.dvc à côté (quelques lignes de YAML, avec un hash MD5 du contenu). Le vrai fichier passe en .gitignore — c'est le fichier .dvc qui se commit dans Git, pas le binaire.

    bash
    git add data/raw.dvc .gitignore
    git commit -m "data: snapshot initial du dataset"
  4. Configurer un remote

    Le remote est l'endroit où DVC envoie les vrais fichiers. Le plus simple pour démarrer : un dossier local (utile pour tester) :

    bash
    dvc remote add -d local /tmp/dvc-storage

    Pour un vrai projet, on utilise un stockage S3-compatible — MinIO auto-hébergé est parfait :

    bash
    dvc remote add -d minio s3://mon-bucket/dvc
    dvc remote modify minio endpointurl http://localhost:9000
    dvc remote modify minio access_key_id "…"
    dvc remote modify --local minio secret_access_key "…"
    Secret : --local plutôt que dans .dvc/config

    Le flag --local écrit dans .dvc/config.local, gitignoré par défaut. C'est là qu'on met les vrais secrets (clé d'accès), pas dans .dvc/config qui est versionné. Même logique que .env avec Pydantic.

  5. Push et pull

    bash
    # Envoyer les vrais fichiers vers le remote
    dvc push
    
    # Sur une autre machine, après git clone + dvc init :
    dvc pull        # récupère les fichiers depuis le remote

    Workflow d'équipe type : git push + dvc push côté contributeur, git pull + dvc pull côté destinataire. Les deux outils sont indépendants mais complémentaires.

  6. Voir l'état des données

    bash
    dvc status                   # équivalent de git status
    dvc diff <commit>            # diff côté data entre 2 commits
    dvc list . data              # lister le contenu d'un dossier DVC
  7. Définir un pipeline reproductible

    Au-delà de versionner des fichiers, DVC sait aussi versionner les étapes qui les produisent. On déclare un pipeline dans un dvc.yaml à la racine :

    yaml (dvc.yaml)
    stages:
      prepare:
        cmd: python src/prepare.py data/raw data/processed
        deps:
          - src/prepare.py
          - data/raw
        outs:
          - data/processed
    
      train:
        cmd: python src/train.py data/processed models/best.pt
        deps:
          - src/train.py
          - data/processed
        outs:
          - models/best.pt
        metrics:
          - metrics.json

    dvc repro rejoue le pipeline en ne ré-exécutant que les étapes dont les inputs ont changé (un peu comme un Makefile, mais conscient des données). Très utile pour ne pas ré-entraîner inutilement.

  8. Comparer des expériences

    DVC propose aussi un sous-système d'expériences (dvc exp run, dvc exp show) qui ressemble à MLflow côté tracking, mais lié à Git. C'est utile sur des projets simples ; sur des projets plus gros, on préfère souvent MLflow pour le tracking et garder DVC pour le pur versioning de fichiers.

Aide-mémoire

bash (de base)
dvc init                       # une fois par repo
dvc add <path>                 # versionner un fichier/dossier
dvc status                     # état des données
dvc push, dvc pull              # sync avec le remote
bash (remotes)
dvc remote add -d <name> <url>
dvc remote modify <name> key value
dvc remote list
bash (pipelines)
dvc stage add -n train ...     # créer une étape
dvc repro                      # rejouer ce qui a changé
dvc dag                        # visualiser le pipeline
bash (workflow Git+DVC)
dvc add data/  &&  git add data.dvc .gitignore
git commit -m "data: …"  &&  dvc push  &&  git push

DVC et le reste de l'écosystème

  • GitHub / GitLab — DVC vit en plus de Git, pas à la place. Tu continues à pusher ton code dans Git, et tu pushes en parallèle les data/modèles dans le remote DVC.
  • MLflow — complémentaire, pas concurrent. MLflow track les runs (paramètres, métriques, artefacts). DVC versionne les fichiers source (datasets, modèles finaux). Combo classique : DVC pour la reproductibilité du dataset, MLflow pour le suivi des entraînements.
  • MinIO / Supabase Storage — candidats parfaits comme remote DVC. MinIO en self-hosted évite de dépendre d'un cloud externe ; les credentials se gèrent via .dvc/config.local.
  • pre-commit — peut lancer dvc status avant chaque commit pour vérifier que les data DVC sont à jour, et bloquer si quelqu'un oublie un dvc push.
  • CI/CD — un job CI peut rejouer un pipeline dvc repro et vérifier que les métriques ne régressent pas (dvc metrics diff). C'est le pattern « MLOps niveau intermédiaire » qu'on voit en formation.
  • Prefect — orchestre des runs ; DVC versionne les artefacts produits. Un flow Prefect peut appeler dvc push à la fin pour archiver les résultats.
Quand DVC vaut le coup, quand il n'en vaut pas

Vaut le coup : tu as des datasets ou modèles qui évoluent, tu veux pouvoir comparer plusieurs versions d'entraînement, tu travailles en équipe sur le même projet ML. N'en vaut pas le coup : un projet jouet avec un seul dataset figé, ou un projet où le dataset est public et re-téléchargeable depuis une source officielle (Kaggle, HF) — dans ce cas, un script de download suffit, pas la peine d'ajouter DVC.

Pour aller plus loin