Maîtriser l’ensemble du cycle de vie des projets de machine learning, de la gestion des données au déploiement en production, en appliquant des pratiques robustes inspirées du DevOps.
Le MLOps, pour Machine Learning Operations, est un ensemble de pratiques visant à automatiser, fiabiliser et industrialiser le cycle de vie des modèles de machine learning. Inspiré du DevOps, il s’adapte aux spécificités des projets ML, qui sont plus sensibles à la variabilité des données, au risque de dérive des performances dans le temps, et à la non-déterminisme des résultats.
Le MLOps ne concerne pas seulement le déploiement des modèles, mais englobe toute la chaîne : ingestion des données, expérimentation, entraînement, validation, packaging, mise en production, surveillance, et mise à jour continue.
Il vise à répondre à des enjeux concrets :
Bien que le MLOps s’inspire du DevOps, il s’en distingue sur plusieurs points fondamentaux :
| Élément | DevOps | MLOps |
|---|---|---|
| Entrée principale | Code source | Code + données + hyperparamètres |
| Résultat attendu | Application déterministe | Modèle entraîné avec performance statistique |
| Tests | Fonctionnels/unitaires | Statistiques, validité, robustesse du modèle |
| CI/CD | Build et déploiement logiciel | Entraînement, packaging, déploiement de modèle |
| Monitoring | Logs, erreurs, uptime | Précision, dérive, métriques métier |
| Reproductibilité | Compilation identique | Dépend aussi de la qualité et version des données |
Le MLOps impose donc des outils et workflows spécifiques pour :
Le MLOps structure un cycle de vie complet du machine learning, souvent itératif :
Collecte des données
Exploration & analyse des données
Expérimentation & entraînement
Validation
Packaging du modèle
Déploiement
Monitoring & maintenance
Ce cycle de vie est au cœur du MLOps : il doit être reproductible, automatisé et traçable.
Le MLOps repose sur la collaboration entre plusieurs profils aux compétences complémentaires :
Data Scientist
Conçoit les modèles, les expérimente, les valide sur des jeux de tests.
ML Engineer
Implémente les modèles de façon performante et scalable ; optimise les ressources.
MLOps Engineer
Met en place les pipelines d’entraînement, de test, de déploiement, de monitoring. Automatise l’ensemble du cycle de vie.
Data Engineer
Met à disposition les données nécessaires, construit les pipelines d’ingestion et de transformation.
Software Engineer
Intègre les modèles dans les applications et plateformes produits.
Product Owner / Métier
Définit les objectifs métiers, valide la pertinence des modèles, suit les KPIs en production.
Les outils du MLOps couvrent différents domaines du cycle de vie :
Ces outils peuvent être combinés dans des stacks MLOps cohérentes, selon les besoins et les ressources de l’équipe.
project_name/
├── data/ # Données brutes, transformées (via DVC ou symlink)
├── notebooks/ # Explorations, prototypage
├── src/ # Code source : preprocessing, entraînement, évaluation
│ ├── data/ # Scripts d'ingestion et de preprocessing
│ ├── features/ # Feature engineering
│ ├── models/ # Définition, entraînement et sauvegarde des modèles
│ └── utils/ # Fonctions utilitaires
├── pipelines/ # Pipelines MLflow, Prefect, Airflow, etc.
├── tests/ # Tests unitaires et fonctionnels
├── dvc.yaml # Définition des pipelines de données (si DVC utilisé)
├── requirements.txt # Dépendances du projet
├── Dockerfile # Containerisation du projet
└── README.md # Description et instructions
name: mlops-pipeline on: push: branches: [ main ] jobs: train-and-track: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies run: | pip install -r requirements.txt pip install dvc[gs] mlflow - name: Pull data with DVC run: dvc pull -r myremote - name: Train and log model run: python src/models/train.py - name: Push model to registry run: mlflow register-model -m ./mlruns -n my-model-name
| Besoin | Open-source | Cloud provider |
|---|---|---|
| Versionnage données + modèles | DVC + Git | SageMaker + S3, Vertex AI + GCS |
| Orchestration de pipelines | Airflow, Prefect, Flyte | SageMaker Pipelines, Azure ML |
| Suivi des expérimentations | MLflow, W&B, Neptune.ai | SageMaker Experiments, Vertex |
| Déploiement API modèle | FastAPI + Docker + K8s | SageMaker Endpoint, Azure Endpoint |
| Monitoring post-déploiement | Evidently, Prometheus | Vertex AI Monitoring, Azure Monitor |
Cause : versions de données ou code non figées, pipelines manuels Solution : DVC pour les données, MLflow pour l’expérimentation, scripts versionnés
Cause : dépendances floues, configurations spécifiques non portables Solution : Dockerisation stricte, gestion centralisée des secrets
Cause : manque de monitoring métier Solution : Evidently + Prometheus avec alertes sur les métriques clés
Cause : rôles mal définis, manque d'automatisation Solution : pipelines automatisés, documentation partagée, GitOps appliqué au ML
La première étape d’un pipeline MLOps est l’acquisition des données. Celles-ci peuvent provenir de sources variées :
La collecte peut être automatisée via des outils comme Airflow, Prefect, ou des scripts dédiés intégrés dans un pipeline DVC ou MLflow.
from airflow import DAG from airflow.operators.bash import BashOperator from airflow.utils.dates import days_ago dag = DAG( 'ingest_csv_kaggle', default_args={'owner': 'mlops'}, start_date=days_ago(1), schedule_interval='@daily' ) ingest = BashOperator( task_id='download_data', bash_command='curl -o /data/raw.csv https://url-vers-dataset.csv', dag=dag )
Avant toute utilisation, les données doivent être validées pour éviter les erreurs silencieuses en aval. Les erreurs peuvent inclure :
from great_expectations.dataset import PandasDataset import pandas as pd class MyValidatedDataset(PandasDataset): _expectations_config = { "expect_column_values_to_not_be_null": {"column": "age"}, "expect_column_values_to_be_between": {"column": "age", "min_value": 0, "max_value": 120} } df = pd.read_csv("/data/clean.csv") validated_df = MyValidatedDataset(df) validated_df.validate()
validate_data dans GitHub Actions avec un rapport JSONContrairement au code, les données changent souvent et doivent être versionnées pour garantir la reproductibilité des expériences ML.
dvc init dvc remote add -d gcsremote gcs://bucket/dataset dvc add data/clean.csv git add data/clean.csv.dvc .gitignore git commit -m "Ajout dataset versionné" dvc push
git tag -a "v_dataset_202406" -m "Version stable du dataset de juin 2024" git push origin v_dataset_202406
| Critère | Warehouse | Lake | Lakehouse (hybride) |
|---|---|---|---|
| Coût | Élevé | Faible à modéré | Modéré |
| Performance requêtes | Optimisée (indexation) | Moyenne | Bonne avec Delta Engine |
| Volume & variété | Limité | Massif, tous types | Massif + structuration |
| Use case typique | BI, dashboards | IA, Big Data, logs | MLOps, BI + ML |
Le traitement de données personnelles (noms, e-mails, logs, données médicales, etc.) est soumis à des régulations strictes comme le RGPD.
import hashlib def pseudonymize_email(email: str) -> str: return hashlib.sha256(email.encode()).hexdigest()
Dans le cycle de vie MLOps, il est crucial de garantir que les résultats obtenus dans un environnement (ex. notebook local) soient reproductibles ailleurs (en CI/CD, sur serveur ou en production).
FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install --upgrade pip && pip install -r requirements.txt COPY . . CMD ["python", "src/train.py"]
scikit-learn>=1.0)environment.lock.yaml, Dockerfile) au même titre que le codeUne mauvaise gestion des dépendances est la cause fréquente de bugs non reproductibles ou d’échecs en production.
Pipfile et Pipfile.lockpoetry init poetry add pandas scikit-learn mlflow poetry export -f requirements.txt --output requirements.txt --without-hashes
poetry.lock, Pipfile.lock, etc.) dans tous les environnementspip freeze > requirements.txt uniquement pour archiver un état figépapermill input.ipynb output.ipynb -p learning_rate 0.01 -p n_estimators 100
nbconvert) avant CI/CD.ipynb directementexp/, feat/, hotfix/)pre-commit, black, flake8, mypy.pre-commit-config.yamlrepos: - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-flake8 rev: v6.0.0 hooks: - id: flake8
L’objectif est d’éviter toute régression ou code non conforme dès le push.
.github/workflows/checks.ymlname: checks on: push: branches: [main] pull_request: branches: [main] jobs: lint-and-test: runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v3 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies run: | pip install -r requirements.txt pip install black flake8 mypy pytest - name: Lint run: | black --check . flake8 . mypy src/ - name: Run tests run: pytest tests/
Pour faciliter les releases, communiquer efficacement les changements, et maintenir la documentation Ă jour.
Convention de nommage de commits : Conventional Commits
Outils :
standard-version (JS/npm)cz / commitizen (Python-compatible)semantic-release (automatique avec GitHub Actions)czpip install commitizen cz init # Configure avec pyproject.toml cz bump # Incrémente version + changelog auto cz changelog # Génère ou met à jour CHANGELOG.md
Une bonne approche consiste à versionner et structurer l’ensemble du cycle de vie ML dans un dépôt cohérent et automatisé.
repo/
├── notebooks/ # Explorations initiales (tracking MLflow ou Papermill)
├── src/ # Code de production modulaire
├── models/ # Fichiers de modèles exportés (liens DVC ou MLflow)
├── data/ # Symboliques DVC ou répertoire ignoré
├── tests/ # Tests unitaires, d’intégration, etc.
├── mlruns/ # Logs MLflow (si local)
├── .github/workflows/ # Pipelines CI/CD
├── Dockerfile # Environnement conteneurisé
├── dvc.yaml # Pipelines de traitement data
└── pyproject.toml # Config globale (formatage, version, changelog, etc.)
Toute pull request doit contenir :
Revue obligatoire à deux pairs pour les étapes critiques : ingestion, entraînement, scoring
Tests automatisés requis avant merge, avec rapport dans le commentaire PR
L'entraînement de modèles implique l'exploration d'une multitude de combinaisons : algorithmes, hyperparamètres, jeux de données, stratégies de preprocessing. Documenter et tracer ces expériences est essentiel pour garantir la reproductibilité et identifier les meilleurs résultats.
import mlflow mlflow.start_run() mlflow.log_param("learning_rate", 0.01) mlflow.log_metric("accuracy", 0.91) mlflow.sklearn.log_model(model, "model") mlflow.end_run()
exp_baseline_lr001, tuned_random_forest)mlflow ui ou W&B Reports)Les hyperparamètres influencent fortement la performance d’un modèle. Leur recherche doit être systématisée et reproductible.
optunaimport optuna def objective(trial): lr = trial.suggest_float("lr", 1e-4, 1e-1, log=True) clf = SomeModel(learning_rate=lr) accuracy = cross_val_score(clf, X, y).mean() return accuracy study = optuna.create_study(direction="maximize") study.optimize(objective, n_trials=50)
python train.py --config config.yaml --seed 42
# config.yaml model: type: xgboost max_depth: 7 learning_rate: 0.01 training: test_split: 0.2 n_estimators: 500
Une fois plusieurs modèles entraînés, il est essentiel de comparer leurs performances de manière rigoureuse.
Comparer non seulement la performance, mais aussi :
Documenter toutes les comparaisons dans un changelog expérimental versionné
Garder un modèle « champion » par tâche dans un registre et archiver les anciens
torch.cuda.Profiler, tf.profiler)import torch device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = MyModel().to(device)
Un entraînement en production ne se lance jamais manuellement : il est orchestré.
from airflow import DAG from airflow.operators.python import PythonOperator from datetime import datetime def train_model(): ... # logiques d'entraînement dag = DAG( 'train_model_pipeline', start_date=datetime(2023, 1, 1), schedule_interval='@daily' ) train_task = PythonOperator( task_id='train_model', python_callable=train_model, dag=dag )
dvc.yaml pour les pipelines datatorch.cuda.amp) : accélère sans perte significativefrom torch.cuda.amp import GradScaler, autocast scaler = GradScaler() for inputs, targets in dataloader: optimizer.zero_grad() with autocast(): outputs = model(inputs) loss = criterion(outputs, targets) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()
from pytorch_lightning import Trainer trainer = Trainer( accelerator="gpu", devices=4, strategy="ddp" ) trainer.fit(model, dataloader)
--num_processes=1)Même dans un projet de data science, tout le code doit être testé :
def normalize(x): return (x - x.mean()) / x.std() def test_normalize(): import numpy as np x = np.array([1, 2, 3, 4, 5]) z = normalize(x) assert np.isclose(z.mean(), 0.0, atol=1e-6) assert np.isclose(z.std(), 1.0, atol=1e-6)
Les modèles doivent être évalués au-delà des seules métriques standard.
def test_model_robustness(): X_outlier = generate_abnormal_inputs() predictions = model.predict(X_outlier) assert not np.any(np.isnan(predictions))
Les modèles peuvent perdre en pertinence si la distribution des données change (dérive) ou s’ils amplifient des inégalités (biais).
from evidently.report import Report from evidently.metric_preset import DataDriftPreset report = Report(metrics=[DataDriftPreset()]) report.run(reference_data=df_ref, current_data=df_prod) report.save_html("drift_report.html")
La validation croisée (cross-validation) évalue la généralisation du modèle. Elle doit être systématisée dans les pipelines.
sklearnfrom sklearn.model_selection import cross_validate scores = cross_validate(model, X, y, scoring=["accuracy", "f1"], cv=5, return_train_score=True) print(scores)
Pipeline sklearn, Optuna, PyCaret, etc.)Avant tout déploiement, un modèle doit être exporté dans un format standardisé.
from fastapi import FastAPI from pydantic import BaseModel import joblib app = FastAPI() model = joblib.load("model.joblib") class Input(BaseModel): feature1: float feature2: float @app.post("/predict") def predict(input: Input): data = [[input.feature1, input.feature2]] prediction = model.predict(data) return {"prediction": prediction.tolist()}
FROM python:3.10 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
apiVersion: apps/v1 kind: Deployment metadata: name: ml-api spec: replicas: 3 selector: matchLabels: app: ml-api template: metadata: labels: app: ml-api spec: containers: - name: api image: myorg/ml-api:latest ports: - containerPort: 8080
mlflow models serve -m runs:/<run-id>/model --port 1234
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install deps & MLflow run: pip install -r requirements.txt mlflow - name: Deploy model run: mlflow models serve -m runs:/latest/model --port 5000
v*.*.*)Une fois déployé, un modèle doit être surveillé en continu pour garantir :
from prometheus_client import Counter, Histogram, start_http_server prediction_count = Counter('predictions_total', 'Total predictions made') prediction_latency = Histogram('prediction_latency_seconds', 'Time for prediction') @app.post("/predict") @prediction_latency.time() def predict(input: Input): prediction_count.inc() return {"prediction": model.predict(...)}
Chaque appel au modèle doit être loggé :
@app.middleware("http") async def log_requests(request: Request, call_next): start = time.time() response = await call_next(request) duration = time.time() - start log.info(f"{request.method} {request.url} {duration:.3f}s") return response
Un modèle peut être silencieusement dégradé en production.
groups: - name: model_alerts rules: - alert: HighLatency expr: prediction_latency_seconds_bucket{le="1.0"} < 0.5 for: 5m labels: severity: warning annotations: summary: "Latence de prédiction élevée"
Même les meilleurs modèles doivent être mis à jour périodiquement. En production, cela peut être fait de manière :
def check_drift(): drift = run_drift_detector() return "retrain" if drift else "skip" branch = BranchPythonOperator( task_id='drift_check', python_callable=check_drift, dag=dag )
Surveiller un modèle en production ne se limite pas à vérifier sa disponibilité. Il faut également :
Le monitoring d’un modèle doit être traité comme un produit vivant, évolutif, avec des responsabilités partagées entre data scientists, ingénieurs, et opérationnels.
L'automatisation des workflows est cruciale pour garantir la reproductibilité, la fiabilité et la scalabilité des projets ML. Deux outils sont aujourd'hui largement utilisés : Apache Airflow et Prefect.
from airflow import DAG from airflow.operators.python import PythonOperator from datetime import datetime def preprocess(): # Code de preprocessing pass def train_model(): # Code d'entraînement pass dag = DAG('ml_pipeline', start_date=datetime(2024, 1, 1), schedule_interval='@daily') preprocess_task = PythonOperator(task_id='preprocess', python_callable=preprocess, dag=dag) train_task = PythonOperator(task_id='train', python_callable=train_model, dag=dag) preprocess_task >> train_task
from prefect import flow, task @task def preprocess(): pass @task def train(): pass @flow def ml_flow(): data = preprocess() train() ml_flow()
GitOps consiste à piloter l’ensemble des déploiements via Git comme source unique de vérité. Il est de plus en plus appliqué aux projets ML.
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: ml-deploy spec: source: repoURL: https://github.com/myorg/ml-deploy targetRevision: HEAD path: k8s/ destination: server: https://kubernetes.default.svc namespace: production project: default
Les Feature Stores sont des systèmes spécialisés pour le stockage, la gestion et la réutilisation des variables explicatives.
from feast import FeatureStore store = FeatureStore(repo_path="my_feature_repo") data = store.get_online_features( features=["user_profile:age", "user_profile:gender"], entity_rows=[{"user_id": 1234}] ).to_dict()
Le ML a besoin de pipelines robustes qui intègrent :
name: ml-cicd on: push: branches: - main jobs: train-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Python uses: actions/setup-python@v2 with: python-version: 3.9 - name: Install deps run: pip install -r requirements.txt - name: Train model run: python scripts/train.py - name: Deploy model run: bash deploy.sh
L’automatisation et l’orchestration des workflows ML réduisent les erreurs humaines, améliorent la reproductibilité, et accélèrent le time-to-market des modèles. Ce chapitre fournit les briques pour construire des pipelines robustes et scalables, du prototypage au déploiement.
La sécurité des modèles de ML ne se limite pas à l’accès au modèle lui-même. Il faut aussi protéger l’ensemble du pipeline : code, données, artefacts, endpoints et infrastructure.
Critique dans les systèmes sensibles (santé, finance, justice).
Méthodes :
Intégration de l’explicabilité dans les dashboards ou les systèmes de décision (sous forme d’annotations ou d’analyses).
L’auditabilité vise à assurer une traçabilité complète des actions, transformations et décisions du pipeline ML.
La sécurité, l'éthique et la conformité sont des piliers trop souvent négligés dans le déploiement de modèles ML. Ce chapitre vous permet de comprendre les risques réels, de structurer les réponses techniques et organisationnelles, et de rendre vos systèmes auditables, équitables et légitimes face à la société et au droit.
Ce cas pratique met en œuvre toutes les briques vues précédemment, à travers un projet complet de bout en bout. Nous allons prédire le risque de désabonnement d’un utilisateur dans un service en ligne, en temps quasi-réel.
Anticiper les utilisateurs susceptibles de se désabonner dans les 30 prochains jours afin d'agir proactivement (offre personnalisée, relance, etc.).
Source : événements d’usage collectés en continu (clics, connexions, achats, navigation).
Technologies utilisées :
Instructions détaillées :
version: '2' services: zookeeper: image: confluentinc/cp-zookeeper:latest environment: ZOOKEEPER_CLIENT_PORT: 2181 kafka: image: confluentinc/cp-kafka:latest depends_on: - zookeeper environment: KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
docker-compose up -d{ "name": "s3-sink", "config": { "connector.class": "io.confluent.connect.s3.S3SinkConnector", "topics": "user-events", "s3.bucket.name": "mlops-churn", "s3.part.size": 5242880, "flush.size": 3, "storage.class": "io.confluent.connect.s3.storage.S3Storage", "format.class": "io.confluent.connect.s3.format.json.JsonFormat", "schema.compatibility": "NONE" } }
user-events et vérifier dans S3.Objectif : transformer les données brutes en un format exploitable pour l’entraînement.
Technologies utilisées :
Instructions détaillées :
pip install pyspark
from pyspark.sql import SparkSession from pyspark.sql.functions import col, to_date spark = SparkSession.builder.appName("Preprocessing").getOrCreate() df = spark.read.json("s3a://mlops-churn/raw-events/") cleaned_df = df.filter(col("event_type").isNotNull()) \ .withColumn("event_date", to_date(col("timestamp"))) \ .dropna(subset=["user_id"]) cleaned_df.write.parquet("cleaned-data/")
dvc init dvc add cleaned-data/ git add cleaned-data.dvc .gitignore git commit -m "Ajout données nettoyées"
Objectif : extraire des variables pertinentes, historisées, et cohérentes pour l’entraînement et l’inférence.
Technologies utilisées :
Instructions détaillées :
pip install feast feast init churn_project cd churn_project
# churn_project/feature_repo/entity.py from feast import Entity user = Entity(name="user_id", join_keys=["user_id"]) # churn_project/feature_repo/feature_view.py from feast import FeatureView, Field from feast.types import Float32 from datetime import timedelta user_activity_view = FeatureView( name="user_activity", entities=["user_id"], ttl=timedelta(days=30), schema=[ Field(name="avg_session_duration", dtype=Float32), Field(name="support_tickets_last_30d", dtype=Float32), ], online=True, source=... # Source définie dans data_source.py )
feast apply feast materialize-incremental $(date +%F)
Objectif : entraîner un modèle robuste sur les données et valider ses performances avant packaging.
Technologies utilisées :
Instructions détaillées :
python -m venv env source env/bin/activate pip install pandas scikit-learn xgboost mlflow dvc
import pandas as pd from sklearn.model_selection import train_test_split features = pd.read_parquet("cleaned-data/features.parquet") X = features.drop("churned", axis=1) y = features["churned"] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
import mlflow import xgboost as xgb from sklearn.metrics import roc_auc_score mlflow.start_run() model = xgb.XGBClassifier(eval_metric="auc") model.fit(X_train, y_train) preds = model.predict_proba(X_test)[:, 1] auc = roc_auc_score(y_test, preds) mlflow.log_metric("roc_auc", auc) mlflow.sklearn.log_model(model, "model") mlflow.end_run()
dvc add model.pkl git add model.pkl.dvc git commit -m "Ajout modèle XGBoost"
Objectif : transformer le modèle validé en une API déployable, intégrer dans une chaîne CI/CD, et orchestrer les mises à jour.
Technologies utilisées :
Instructions détaillées :
# api/app.py from fastapi import FastAPI, Request import joblib import pandas as pd app = FastAPI() model = joblib.load("model.pkl") @app.post("/predict") async def predict(request: Request): data = await request.json() df = pd.DataFrame([data]) prediction = model.predict_proba(df)[0][1] return {"churn_probability": prediction}
# Dockerfile FROM python:3.10 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
requirements.txt :
fastapi
uvicorn
pandas
scikit-learn
xgboost
joblib
docker build -t churn-api . docker run -p 8000:8000 churn-api
Test avec curl :
curl -X POST http://localhost:8000/predict \ -H "Content-Type: application/json" \ -d '{"feature1": 0.12, "feature2": 3, ...}'
.github/workflows/deploy.yml)name: Deploy to Kubernetes on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Build Docker image run: docker build -t ghcr.io/your_user/churn-api:latest . - name: Push to GitHub Container Registry run: | echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u your_user --password-stdin docker push ghcr.io/your_user/churn-api:latest
helm create churn-api
Dans values.yaml :
image: repository: ghcr.io/your_user/churn-api tag: latest
Puis :
helm install churn-api ./churn-api
Objectif : surveiller les performances du modèle en production, détecter les dérives, et générer des alertes.
Technologies utilisées :
Instructions détaillées :
from prometheus_client import start_http_server, Summary start_http_server(8001) # endpoint Prometheus REQUEST_TIME = Summary("request_processing_seconds", "Time spent processing request") @app.post("/predict") @REQUEST_TIME.time() async def predict(request: Request): ...
scrape_configs: - job_name: 'churn-api' static_configs: - targets: ['localhost:8001']
from evidently.report import Report from evidently.metric_preset import DataDriftPreset report = Report(metrics=[DataDriftPreset()]) report.run(reference_data=ref_df, current_data=prod_df) report.save_html("drift_report.html")
Automatiser cette étape chaque semaine avec un DAG Airflow.
Ce chapitre explore des sujets avancés du MLOps permettant d’aller au-delà du déploiement initial et d’industrialiser l’approche pour des systèmes ML robustes, scalables et dynamiques. On aborde ici des mécanismes d’apprentissage actif, de tests A/B, d’architecture multi-tenants et une analyse comparative des solutions open-source et cloud.
Mettre en place un système capable de détecter les dérives et déclencher automatiquement le réentraînement du modèle avec les nouvelles données jugées informatives.
Suivi des performances du modèle en production :
Détection de dérive :
Sélection active des exemples :
Réentraînement automatique :
Comparer deux versions d’un modèle en conditions réelles, en mesurant leur impact sur des métriques métiers et techniques.
Stratégies de déploiement :
Suivi des performances comparées :
Infrastructure :
Concevoir une architecture capable de servir plusieurs équipes ou clients avec une infrastructure partagée, tout en garantissant l’isolation, la sécurité et la scalabilité.
Séparation logique ou physique :
Gestion des identités et droits :
Déploiement de modèles multi-instances :
Suivi individualisé :
Aider au choix technologique en comparant les stacks open-source aux solutions cloud managées, selon les besoins du projet.
| Critère | Open-source (ex : MLflow + DVC + Airflow) | Cloud (ex : Vertex AI, SageMaker, Azure ML) |
|---|---|---|
| Coût | Faible à modéré, dépend de l’infra | Élevé, coût à l’usage |
| Courbe d’apprentissage | Plus raide, nécessite DevOps | Interface guidée, abstractions élevées |
| Flexibilité | Totale, personnalisable | Restreinte, dépend du provider |
| Maintenance | À charge de l’équipe | Gérée par le cloud |
| Intégration CI/CD | À construire soi-même | Intégrée à l’écosystème |
| Gouvernance & sécurité | Personnalisable, effort manuel | Standards cloud, IAM intégrés |
| Scalabilité | Exige expertise technique | Native, autoscaling intégré |