Concrètement, qu’est-ce que MLFlow peut apporter à votre équipe ? Après avoir abordé la partie théorique de cet outil nous vous apportons aujourd’hui un retour pratique sur l’utilisation de MLFlow à la fois dans un contexte Cloud (MLFlow managé par Databricks) et on-premise (MLFlow en local – Python).

 

Présentation du cas d’usage de MLFlow

Pour illustrer l’utilisation pratique de MLFlow, nous avons imaginé le cas d’usage suivant : une société du CAC40 souhaite mettre en place un projet de prédiction des cours de la bourse visant à analyser les perturbations subies au cours des derniers mois, tout en évaluant l’impact des mesures prises par les gouvernements pour tenter d’endiguer l’épidémie de COVID.

Nous nous sommes basés sur deux datasets :

Le pré-traitement et la jointure de ces deux datasets seront détaillés dans un prochain article.

La démarche consiste à étudier les modèles permettant :

  • dans un premier temps, de prédire le cours de l’action de la société cotée avec les données uniquement financières (Yahoo Finance);
  • puis de corréler ces données financières avec les mesures prises par les gouvernements, afin de tenter d’anticiper leurs impacts sur la bourse.

 

Nous allons vous présenter cette étude à travers deux outils pour comparer leurs possibilités dans deux scénarios :

  • Le scénario Cloud :
    • MLFlow managé par Databricks ;
  • Le scénario on-premise :
    • Déployer MLFlow en local.

 

Contexte Cloud : MLFlow managé par Databricks

Pour pouvoir utiliser MLFlow dans votre environnement Databricks, assurez-vous au préalable d’avoir :

  • Soit importé la bibliothèque mlflow==1.7.0 via PyPI :

  • Soit utilisé directement la version 7.3 ML de Databricks runtime :

Ensuite, importez votre dataset – table argent ou or…

… et préparez votre dataset en le divisant en datasets d’entrainement et de test pour vos modèles :

from sklearn.model_selection import train_test_split

 

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

 

Vous pouvez commencer à utiliser MLFlow en rajoutant seulement quelques lignes de code à votre pipeline habituel :

  1. Utilisez :
mlflow.start_run()

pour commencer une expérience ;

  1. Entrainez votre modèle ;
  2. Enregistrez les paramètres utilisés :
mlflow.log_param()
  1. Enregistrez votre modèle :
mlflow.sklearn.log_model()
  1. Enregistrez également la/les métrique(s) permettant d’évaluer vos modèles :
mlflow.log_metric()

 

Comment placer les modèles dans notre use case ?

Le but de notre étude est de construire un modèle permettant de prédire le volume de transactions (colonne « Volume » du dataset Yahoo Finance) en fonction des mesures prises par les gouvernements pendant la pandémie de COVID. Nous allons pour cela comparer plusieurs modèles de régression relativement simples :

  • une régression linéaire “classique”
  • une régression polynomiale en faisant varier la valeur de alpha (régularisation)
for i in np.arange(0, 1, 0.1):

  # start mlflow run

  with mlflow.start_run(run_name="Finance Covid Experiment") as run:

 

    ## 1. Models:

   

    # 1.a. Run 1 - Linear Regression

    #modelname = "linear regression"

    #model = LinearRegression(n_jobs= -1)

    #mlflow.log_param("n_jobs", -1)

   

    # 1.b. Run 2 - Quadratic Regression

    modelname = "quadratic regression"

    print("model:",modelname)

    model = make_pipeline(PolynomialFeatures(2), Ridge(alpha=i))

    mlflow.log_param("alpha", i)

    print("alpha:",i)

   

   

    ## 2. Train / Test / Predict with each model :

    model.fit(X_train, y_train)

    confidencemodel = model.score(X_test, y_test)

    print("confidence:",confidencemodel)




    predictions = model.predict(X_test)




    ## 4. Log model

    mlflow.sklearn.log_model(model, clfname)




    ## 5. Metrics

    # 5.a. Create metrics

    mse = mean_squared_error(y_test, predictions)

    print(f"mse: {mse}")




    rmse = (np.sqrt(mean_squared_error(y_test, predictions)))

    print(f"rmse: {rmse}")




    r2 = r2_score(y_test, predictions)

    print(f"r2: {r2}")




    # 5.b. Log metrics

    mlflow.log_metric("mse", mse)

    mlflow.log_metric("rmse", rmse)

    mlflow.log_metric("r2", r2)







    ## 6. Register experiment and runs

    runID = run.info.run_uuid

    experimentID = run.info.experiment_id




    print(f"MLflow Run id: `{runID}` ; Experiment Id: `{experimentID}`")

 

Le score de sortie de ce dernier modèle est correct (confiance ~96%), mais il est obtenu suite à de nombreuses modifications qui – dans la réalité – peuvent être très difficiles à retracer (changement de paramètres, de modèles, etc. – vous pouvez voir dans le code ci-dessus une partie des modèles testés). Et dans un projet, il s’agit souvent de milliers de modèles – aussi bien en phase de développement que de production – dont la gestion est un véritable casse-tête !

C’est ici qu’interviennent plusieurs composants de MLFlow managé par Databricks qui vous mettent à disposition :

  • Une historisation de vos modèles, en traçant les modifications intervenues, et notamment :
    – Les changements de modèles (comme dans notre cas d’usage, le passage aux différents modèles de régression : linéaire, polynomiale, etc.) ;
    – Les changements de paramètres du modèle ;
  • Un versioningde vos modèles, ainsi que la possibilité de tagger la version comme étant une version de « Staging » ou de « Production » ;
  • Un partage et une collaboration facilités entre les différents membres d’un projet ;
  • La sauvegarde de vos modèles dans des artifacts contenant notamment le modèle au format pkl.

Vous pouvez accéder à l’interface MLFlow après avoir exécuté le code présenté ci-dessus. Un log apparait dans le volet « Experiment » à droite de votre notebook Databricks :

 

MLFlow : une interface claire et lisible

En accédant à l’interface MLFlow présentée ci-dessus, vous pouvez, en un coup d’œil :

  • Identifier votre projet (« Experiment ID ») ;
  • Localiser l’artifact créé (« Artifact Localisation ») ;
  • Localiser la source et la version du code lié au modèle (ainsi que le timestamp et l’utilisateur ayant exécuté le notebook) ;
  • Comparer les résultats de vos métriques utilisées pour évaluer votre modèle.

Dans notre cas d’usage, si nous voulons par exemple facilement sélectionner parmi tous nos essais les meilleurs modèles et hyperparamètres, nous pouvons sélectionner les différents runs enregistrés dans l’interface MLFlow pour comparer leurs résultats (“Compare”).

Nous pouvons ainsi apprécier visuellement la meilleure valeur pour le paramètre alpha du modèle de régression Ridge :

En cliquant sur la dernière exécution, vous pouvez voir s’afficher les artifacts créés et leur contenu. Dans chaque artifact créé, vous aurez :

  • La sauvegarde de votre modèle au format pkl : « model.pkl » ;
  • Un fichier contenant les configurations de l’environnement : « conda.yaml » ;
  • Et un fichier contenant les modes de (re)déploiement du modèle disponibles (flavors). Par exemple le modèle sklearn enregistré dans notre use-case peut être déployé en environnement Python (pyfunc) ou en Spark.

Vous pouvez ensuite enregistrer ces modèles…

… pour les retrouver dans la partie « Registered Models » (blade « Models » de votre Databricks). Vous pouvez alors les versionner et leur assigner un tag pour les distinguer de l’environnement de développement (tag « Staging ») ou de production (tag « Production ») :

Une fois vos modèles enregistrés et versionnés, il sera très facile de les distinguer et de les charger en fonction de leur utilité.

Ainsi, pour réutiliser notre modèle polynomial le plus performant, il suffit de le charger en indiquant :

  • son nom,
  • sa version,
  • et, facultativement, le « stage » (« Staging » ou « Production »).
import mlflow.pyfunc




model_name = "Model quadratic regression"

stage = "Production




model = mlflow.pyfunc.load_model(

  model_uri=f"models:/{model_name}/{stage}

)

model.predict(data)

Voici également une autre fonctionnalité très utile pour vos projets : vous pouvez très rapidement transiter un modèle de “Staging” en “Production” et inversement – avec un système de validation des requêtes de transition :

 

Si vous souhaitez aller plus loin sur la transition des modèles en production-stage, nous vous invitons à consulter cette documentation Databricks.

L’intégration de MLFlow par Databricks permet donc de simplifier de manière significative la gouvernance des modèles ML. Au travers de ses différents composants de tracking, de versionning, de collaboration et de déploiement, Databricks redonne aux équipes projets le contrôle sur le cycle de vie complet de leurs modèles.

 

 

Contexte on-premise : déployer MLFlow en local (Python)

 

Il est possible d’utiliser MLFlow ailleurs que dans une solution propriétaire. On peut ainsi, par exemple, s’en servir dans un simple script Python.

Pour commencer, il est nécessaire d’installer MLFlow pour l’utiliser dans son environnement Python :

pip install mlflow

A partir de là, on aura plus qu’à entrainer ses modèles. Grâce à MLFlow on pourra suivre des métriques, sauvegarder différents runs, garder les logs des expériences. Il suffit de procéder ainsi :

from mlflow import log_metric, log_param, log_artifacts




log_param("alpha", 0.05)




log_metric("RMSE", rmse)

log_metric("R²", r2)

log_metric("MAE", MAE)

Il est possible de tout sauvegarder en local ou sur un server de tracking distant, à l’aide de cette commande :

mlflow.set_tracking_uri("http://YOUR-SERVER:4040")

mlflow.set_experiment("my-experiment")

Tout reste observable via l’UI intégré de MLFlow, en tapant la commande dans la console de votre IDE et en cliquant sur l’url qui apparait :

mlflow ui

Nous avons accès à plusieurs vues très utiles : liste des expériences, liste des runs par expérience, différentes métriques et leur représentation graphique, historique des paramètres utilisés pendant l’entrainement des modèles, etc.


Utiliser MLFlow dans vos scripts d’entrainement

 

Vous trouverez ci-dessous le code permettant d’importer MLFlow et sauvegarder les métriques, les paramètres et autres informations importantes pendant l’entrainement.

with mlflow.start_run(run_name="yfinance-covid") as run:

    # Log a parameter (key-value pair)

    log_param("alpha", alpha)

    # train the model

    pipeline = make_pipeline(PolynomialFeatures(2),Ridge())

    pipeline.fit(X_train, y_train) 

    mlflow.sklearn.log_model(pipeline, "ridge")

    predictions = pipeline.predict(X_test)

    rmse = (np.sqrt(mean_squared_error(y_test, predictions)))

    r2 = r2_score(y_test, predictions)

    mae = mean_absolute_error(y_test, predictions)

    # Log a metric; metrics can be updated throughout the run

    log_metric("RMSE", rmse)

    log_metric("R²", r2)

    log_metric("MAE", MAE)

    # Log an artifact (output file)

    if not os.path.exists("outputs"):

        os.makedirs("outputs")

    with open("outputs/test.txt", "w") as f:

        f.write("Everything is OK!")

    log_artifacts("outputs")

Quand on lance le premier run (en local), on remarque la création d’un nouveau dossier :

Toutes les informations nécessaires à MLFlow à propos de l’expérience seront stockées dans le dossier mlruns, disponible localement. Grâce à lui, MLFlow peut générer un dashboard concentrant toutes les informations concernant nos runs.

 

Application à MLFlow UI

 

En haut à gauche de l’interface vous trouverez la liste des expériences. Si elle n’est pas expressément nommée, notre expérience s’appellera « Default », comme sur l’image qui suit :




Notre carnet de bord affiche la liste des runs, avec les valeurs pour chaque paramètre et métrique.

On peut ainsi garder une trace de nos expériences et voir quel est le meilleur jeu de paramètres pour un modèle donné.
En cliquant sur un run, on peut voir ses paramètres, métriques et autres logs :

 

 

MLFlow en pratique : l’essentiel à retenir

 

​Quelle que soit la solution que vous utiliserez (Databricks ou on-premise/local), vous pourrez profiter des avantages de MLFLow :

  • La création d’un historique pour chacune de vos expériences de ML ;
  • Le versioning de vos différents modèles de ML et la possibilité de les stocker ;
  • La possibilité de faire du tracking sur différentes métriques.

 

Ces différents atouts font de MLFlow un outil indispensable pour quiconque veut introduire du MLOps dans ses projets.

 

✍️ Cet article a été co-rédigé par nos experts data : Nathalie Fouet, Adrien Forte, Yann Bilissor (Cellenza) et Pierre Haddad (Databricks).