feat(ml): enregistrer le modèle dans le MLflow Model Registry

This commit is contained in:
Valentin
2026-09-21 14:52:00 +02:00
parent 268496a8c4
commit 9312d3b60f
6 changed files with 74 additions and 1 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ ml/models/*
!ml/models/.gitkeep
ml/mlruns/
ml/mlartifacts/
ml/mlflow.db
ml/mlflow.db*
# IDE et OS
.idea/
+5
View File
@@ -0,0 +1,5 @@
.venv
data
mlruns
mlflow.db*
models
+3
View File
@@ -0,0 +1,3 @@
FROM python:3.12-slim
RUN pip install --no-cache-dir mlflow==3.16.1 psycopg2-binary
EXPOSE 5000
+31
View File
@@ -57,6 +57,37 @@ validation. La coupure est **chronologique**, jamais un tirage aleatoire de lign
aleatoire laisserait des lignes de validation "voir" des lignes d'entrainement via leurs
lags/moyennes glissantes, une fuite qui masquerait un surapprentissage.
## Serveur MLflow (conteneur)
Un serveur MLflow (PostgreSQL pour les metadonnees, volume pour les artefacts) se lance avec
Docker. Prerequis : Docker Desktop demarre.
```
cd ml
docker compose -f docker-compose.mlflow.yml up -d --build
```
Interface : http://localhost:5000. Entrainer vers ce serveur :
```
uv run python -m enervision_ml.train --csv data/all_sites_combined.csv --mlflow-tracking-uri http://localhost:5000
```
Arreter : `docker compose -f docker-compose.mlflow.yml down` (ajouter `-v` pour effacer aussi les
runs et les modeles).
Pour voir les runs dans l'interface (MLflow 3.x) :
- Passer le selecteur en haut a gauche sur **Model training**. Le mode **GenAI** affiche des
traces LLM et reste vide pour un entrainement LightGBM.
- **Runs** liste les entrainements, **Models** les artefacts de modele de chaque run (tous nommes
`model`), et **Model registry** les versions numerotees de `consumption-forecast-lightgbm`.
Limites : les identifiants PostgreSQL (`mlflow` / `mlflow`) du compose ne conviennent qu'au
developpement local. Un deploiement partage demandera des secrets, de l'authentification et un
stockage d'artefacts dedie (S3/MinIO). Le port 5000 doit etre libre : arreter `mlflow ui` avant,
ou changer le mapping (`"5001:5000"`) dans le compose.
## Commandes
```bash
+33
View File
@@ -0,0 +1,33 @@
services:
mlflow-db:
image: postgres:16
environment:
POSTGRES_USER: mlflow
POSTGRES_PASSWORD: mlflow
POSTGRES_DB: mlflow
volumes:
- mlflow-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mlflow"]
interval: 5s
retries: 10
mlflow:
build: .
depends_on:
mlflow-db:
condition: service_healthy
ports:
- "5000:5000"
volumes:
- mlflow-artifacts:/mlartifacts
command: >
mlflow server
--host 0.0.0.0 --port 5000
--backend-store-uri postgresql://mlflow:mlflow@mlflow-db:5432/mlflow
--artifacts-destination /mlartifacts
--serve-artifacts
volumes:
mlflow-db-data:
mlflow-artifacts:
+1
View File
@@ -77,6 +77,7 @@ def test_train_runs_end_to_end_on_synthetic_data_and_beats_a_dummy_baseline(
assert baseline_metrics["n_observations"] == model_metrics["n_observations"]
assert model_metrics["mae"] < baseline_metrics["mae"]
def test_train_raises_when_the_validation_window_is_empty(tmp_path: Path) -> None:
depart = datetime(2026, 1, 1, tzinfo=UTC)
frame = make_frame("site-a", heures=50, depart=depart) # trop court pour un lag de 168h