Environnements : uv, lockfiles et CUDA
Pourquoi c'est pire en ML qu'ailleurs
L'écosystème data cumule : des paquets compilés (numpy, torch — des binaires par OS/architecture), des variantes par version CUDA (torch+cu121 ≠ torch+cpu), et des chaînes de dépendances profondes qui cassent en silence. Sans discipline, ton projet devient irreproductible en trois semaines.
La stack 2026 : uv
uv (par Astral, les auteurs de ruff) a remplacé pip/venv/poetry dans la plupart des équipes : résolution ~100× plus rapide, lockfile universel, gestion des versions de Python elle-même.
uv init mon-projet && cd mon-projet
uv add pandas scikit-learn # résout + épingle dans uv.lock
uv add torch --index pytorch-cu121 # la variante GPU explicite
uv run python train.py # exécute DANS l'environnement, sans activate
uv sync # reconstruit l'env exact depuis le lock (CI, collègue)
Les trois règles d'or
- Un projet = un environnement — jamais d'installation dans le Python système ;
- Le lockfile fait foi —
uv.lockcommité, CI et Docker installent depuis lui ; - La variante torch est un choix explicite — cpu, cu121, cu124… la documenter dans le README évite le classique « ça tourne pas sur le serveur » (qui est en réalité : mauvaise variante CUDA).
Dans le Dockerfile
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev # layer caché tant que le lock ne change pas
COPY src/ ./src # le code change souvent, les deps non
Exactement ton pattern npm ci : lock d'abord, code ensuite, cache des layers préservé.
Pourquoi les dépendances ML sont-elles plus fragiles que la moyenne ?