> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-fr/mlops-et-deploiement/mlflow.md).

# MLflow

**MLflow** est une plate-forme open-source pour gérer l'ensemble du **cycle de vie de l'apprentissage automatique** — depuis le suivi des expériences et la gestion des versions des modèles jusqu'au déploiement et à la surveillance. Utilisé par des milliers d'organisations dans le monde, MLflow apporte de la structure et de la reproductibilité aux flux de travail ML. Exécutez-le sur le cloud GPU de Clore.ai pour obtenir un serveur de suivi centralisé aux côtés de vos tâches d'entraînement.

***

## Qu'est-ce que MLflow ?

MLflow fournit quatre composants principaux :

| Composant               | Description                                                                |
| ----------------------- | -------------------------------------------------------------------------- |
| **Suivi**               | Enregistrez les paramètres, métriques, artefacts et code des exécutions ML |
| **Projets**             | Packager le code pour des exécutions reproductibles                        |
| **Modèles**             | Format standard de modèle pour le déploiement entre frameworks             |
| **Registre de modèles** | Magasin centralisé de modèles avec gestion des versions et cycle de vie    |

**Frameworks pris en charge (autologging intégré) :**

* PyTorch, TensorFlow/Keras
* Scikit-learn, XGBoost, LightGBM
* HuggingFace Transformers
* Spark MLlib, statsmodels, Prophet

***

## Prérequis

| Exigence | Valeur                                                       |
| -------- | ------------------------------------------------------------ |
| VRAM GPU | N'importe lequel (le serveur MLflow lui-même est lié au CPU) |
| Stockage | 20 Go+ (pour les artefacts)                                  |
| RAM      | 4 Go minimum pour le serveur                                 |
| Ports    | 22 (SSH), 5000 (interface MLflow)                            |

{% hint style="info" %}
Le serveur de suivi MLflow est léger. Vous pouvez l'exécuter sur une petite instance CPU et y connecter vos tâches d'entraînement GPU. Alternativement, hébergez-le sur la même instance GPU que votre entraînement.
{% endhint %}

***

## Étape 1 — Louer un serveur sur Clore.ai

1. Connectez-vous à [clore.ai](https://clore.ai).
2. Cliquez **Place de marché**.
3. Pour un serveur de suivi dédié : filtrez par RAM ≥ 8 Go (GPU optionnel).
4. Pour co-localisé : utilisez votre instance d'entraînement existante.
5. Définir l'image Docker : **`ghcr.io/mlflow/mlflow:latest`**
6. Définir les ports ouverts : `22` (SSH) et `5000` (Interface MLflow).
7. Cliquez **Louez**.

***

## Étape 2 — Lancer le serveur de suivi MLflow

L'officiel `ghcr.io/mlflow/mlflow` image requiert une substitution de commande de démarrage.

### Dans la configuration Docker de Clore.ai

Définissez la **commande** (ou substitution de point d'entrée) sur :

```bash
bash -c "apt-get update -q && apt-get install -y -q openssh-server && \
    mkdir /var/run/sshd && \
    echo 'root:clore123' | chpasswd && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
    service ssh start && \
    mlflow server \
        --host 0.0.0.0 \
        --port 5000 \
        --default-artifact-root /mlflow/artifacts \
        --backend-store-uri sqlite:////mlflow/mlflow.db"
```

### Alternative : Dockerfile personnalisé

```dockerfile
FROM ghcr.io/mlflow/mlflow:latest

RUN apt-get update && apt-get install -y \
    openssh-server \
    && rm -rf /var/lib/apt/lists/*

# Configurer SSH
RUN mkdir /var/run/sshd && \
    echo 'root:clore123' | chpasswd && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# Packages Python supplémentaires
RUN pip install boto3 psycopg2-binary

RUN mkdir -p /mlflow/artifacts

EXPOSE 22 5000

CMD service ssh start && \
    mlflow server \
        --host 0.0.0.0 \
        --port 5000 \
        --default-artifact-root /mlflow/artifacts \
        --backend-store-uri sqlite:////mlflow/mlflow.db
```

***

## Étape 3 — Accéder à l'interface MLflow

Ouvrez votre navigateur :

```
http://<clore-host>:<public-port-5000>
```

Vous devriez voir le tableau de bord des expériences MLflow.

{% hint style="info" %}
Le backend SQLite par défaut (`mlflow.db`) stocke toutes les métadonnées des exécutions localement. Pour une utilisation en production ou en équipe, passez à PostgreSQL — voir Configuration avancée ci-dessous.
{% endhint %}

***

## Étape 4 — Enregistrez votre première expérience

### Connectez-vous depuis une tâche d'entraînement distante

Sur votre machine d'entraînement (ou une autre instance Clore.ai), définissez l'URI de suivi :

```bash
export MLFLOW_TRACKING_URI=http://<clore-host>:<public-port-5000>
```

### Journalisation d'expérience PyTorch basique

```python
import mlflow
import mlflow.pytorch
import torch
import torch.nn as nn
import torch.optim as optim

# Connectez-vous au serveur MLflow
mlflow.set_tracking_uri("http://<clore-host>:<public-port-5000>")
mlflow.set_experiment("my-first-experiment")

# Définir un modèle simple
class SimpleNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super().__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, output_size)
    
    def forward(self, x):
        return self.fc2(self.relu(self.fc1(x)))

# Entraînement avec suivi MLflow
with mlflow.start_run(run_name="training-run-001"):
    # Enregistrez les hyperparamètres
    params = {
        "learning_rate": 0.001,
        "batch_size": 64,
        "epochs": 100,
        "hidden_size": 256,
        "optimizer": "adam"
    }
    mlflow.log_params(params)
    
    # Initialiser le modèle
    model = SimpleNet(784, 256, 10).cuda()
    optimizer = optim.Adam(model.parameters(), lr=params["learning_rate"])
    criterion = nn.CrossEntropyLoss()
    
    # Boucle d'entraînement
    for epoch in range(params["epochs"]):
        loss = torch.tensor(0.5 / (epoch + 1))  # Simulé
        accuracy = 0.7 + epoch * 0.003
        
        # Enregistrez les métriques à chaque époque
        mlflow.log_metrics({
            "train_loss": loss.item(),
            "train_accuracy": accuracy,
        }, step=epoch)
    
    # Enregistrez le modèle final
    mlflow.pytorch.log_model(model, "model")
    
    # Enregistrez les métriques finales
    mlflow.log_metric("final_accuracy", accuracy)
    
    print(f"Exécution enregistrée dans MLflow. ID : {mlflow.active_run().info.run_id}")
```

### Autologging pour HuggingFace Transformers

```python
import mlflow
from transformers import TrainingArguments, Trainer

mlflow.set_tracking_uri("http://<clore-host>:<public-port-5000>")
mlflow.set_experiment("llm-finetuning")

# Activez l'autologging — enregistre automatiquement les params, métriques et le modèle
mlflow.transformers.autolog()

training_args = TrainingArguments(
    output_dir="./results",
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    learning_rate=2e-5,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir="./logs",
    logging_steps=10,
    evaluation_strategy="epoch",
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
)

with mlflow.start_run():
    trainer.train()
```

***

## Étape 5 — Scikit-learn avec autologging

```python
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits

mlflow.set_tracking_uri("http://<clore-host>:<public-port-5000>")
mlflow.set_experiment("sklearn-experiments")

# Tout autologger
mlflow.sklearn.autolog()

X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

with mlflow.start_run(run_name="random-forest-v1"):
    rf = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
    rf.fit(X_train, y_train)
    
    score = rf.score(X_test, y_test)
    print(f"Précision de test : {score:.4f}")
    # Tous les paramètres, métriques et le modèle enregistrés automatiquement !
```

***

## Étape 6 — Registre de modèles

Enregistrez et gérez les versions de modèles via l'interface ou l'API :

```python
import mlflow

client = mlflow.MlflowClient("http://<clore-host>:<public-port-5000>")

# Enregistrer un modèle à partir d'une exécution
run_id = "your-run-id-here"
model_uri = f"runs:/{run_id}/model"

registered = mlflow.register_model(
    model_uri=model_uri,
    name="production-classifier"
)

print(f"Version : {registered.version}")

# Changer l'état du modèle
client.transition_model_version_stage(
    name="production-classifier",
    version=registered.version,
    stage="Production"
)

# Charger un modèle en production n'importe où
model = mlflow.pyfunc.load_model(
    model_uri="models:/production-classifier/Production"
)
```

***

## Étape 7 — Servir un modèle

MLflow peut servir n'importe quel modèle enregistré en tant qu'API REST :

```bash
# Sur l'instance du serveur MLflow
export MLFLOW_TRACKING_URI=http://localhost:5000

mlflow models serve \
    --model-uri "models:/production-classifier/Production" \
    --host 0.0.0.0 \
    --port 5001 \
    --no-conda
```

Testez le modèle servi :

```bash
curl -X POST http://<clore-host>:5001/invocations \
    -H "Content-Type: application/json" \
    -d '{"inputs": [[1.0, 2.0, 3.0, ...]]}'
```

***

## Configuration avancée

### Backend PostgreSQL (Production)

```bash
# Lancer avec PostgreSQL
mlflow server \
    --host 0.0.0.0 \
    --port 5000 \
    --backend-store-uri postgresql://user:password@db-host/mlflow \
    --default-artifact-root s3://my-bucket/mlflow-artifacts
```

### Stockage d'artefacts S3

```bash
pip install boto3

export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret

mlflow server \
    --host 0.0.0.0 \
    --port 5000 \
    --default-artifact-root s3://my-mlflow-bucket/artifacts \
    --backend-store-uri sqlite:////mlflow/mlflow.db
```

### Authentification (Entreprise)

```bash
pip install mlflow[auth]

mlflow server \
    --host 0.0.0.0 \
    --port 5000 \
    --app-name basic-auth \
    --backend-store-uri sqlite:////mlflow/mlflow.db \
    --default-artifact-root /mlflow/artifacts
```

***

## Comparer des exécutions dans l'interface

1. Ouvrez l'interface MLflow à `http://<clore-host>:<port>`
2. Sélectionnez une expérience depuis le panneau de gauche
3. Cochez les cases à côté de plusieurs exécutions
4. Cliquez **Comparer** pour voir métriques et paramètres côte à côte
5. Utilisez le **Graphiques** onglet pour une comparaison visuelle

***

## Dépannage

### Impossible de se connecter au serveur de suivi

```
mlflow.exceptions.MlflowException : la requête API a échoué avec le code d'état 503
```

**Solutions :**

* Vérifiez que le port 5000 est ouvert et transféré dans Clore.ai
* Vérifiez que le serveur est en cours d'exécution : `ps aux | grep mlflow`
* Tester la connectivité : `curl http://<clore-host>:<port>/health`

### Échec du téléchargement d'artefact

**Solution :** Assurez-vous que le répertoire d'artefacts est accessible en écriture :

```bash
chmod 777 /mlflow/artifacts
```

### Erreur SQLite verrouillée (écritures concurrentes)

**Solution :** Passez à PostgreSQL pour les configurations multi-utilisateurs :

```bash
pip install psycopg2-binary
```

### Registre de modèles non visible

**Solution :** Vérifiez que vous utilisez un `--backend-store-uri` qui prend en charge le registre (SQLite ou PostgreSQL — pas seulement un chemin local).

***

## Estimation des coûts

| Instance    | Cas d’utilisation           | Prix estimé | Remarques                      |
| ----------- | --------------------------- | ----------- | ------------------------------ |
| CPU 4 cœurs | Serveur de suivi uniquement | \~0,05 $/h  | Très léger                     |
| RTX 3080    | Entraînement co-localisé    | \~0,10 $/h  | Entraînement + MLflow          |
| RTX 4090    | Entraînement lourd + suivi  | \~0,35 $/h  | Configuration la plus courante |

{% hint style="info" %}
Exécutez MLflow sur une instance CPU bon marché et pointez toutes vos tâches d'entraînement GPU vers celui-ci. Ainsi, le serveur de suivi tourne en continu sans consommer de crédits GPU coûteux.
{% endhint %}

***

## Ressources utiles

* [Documentation officielle de MLflow](https://mlflow.org/docs/latest/index.html)
* [MLflow GitHub](https://github.com/mlflow/mlflow)
* [MLflow Docker Hub](https://github.com/mlflow/mlflow/pkgs/container/mlflow)
* [Guide du registre de modèles MLflow](https://mlflow.org/docs/latest/model-registry.html)
* [Référence de l'API de suivi MLflow](https://mlflow.org/docs/latest/python_api/mlflow.html)

***

## Recommandations GPU Clore.ai

| Cas d’utilisation            | GPU recommandé  | Coût estimé sur Clore.ai |
| ---------------------------- | --------------- | ------------------------ |
| Développement/Test           | RTX 3090 (24GB) | \~$0.12/gpu/hr           |
| Entraînement en production   | RTX 4090 (24GB) | \~$0.70/gpu/hr           |
| Expériences à grande échelle | A100 80GB       | \~$1.20/gpu/hr           |

> 💡 Tous les exemples de ce guide peuvent être déployés sur [Clore.ai](https://clore.ai/marketplace) serveurs GPU. Parcourez les GPU disponibles et louez à l’heure — sans engagement, avec accès root complet.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-fr/mlops-et-deploiement/mlflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
