Partager via


Déployer et exécuter des modèles MLflow dans des travaux Spark

Cet article explique comment déployer et exécuter votre modèle MLflow dans des travaux Spark pour effectuer l’inférence sur de grandes quantités de données ou dans le cadre de travaux de data wrangling.

À propos de cet exemple

Cet exemple montre comment déployer un modèle MLflow inscrit dans Azure Machine Learning sur des travaux Spark s’exécutant dans des clusters Spark managés (préversion), Azure Databricks ou Azure Synapse Analytics pour effectuer l’inférence sur de grandes quantités de données.

Ce modèle est basé sur le jeu de données UCI Heart Disease. La base de données contient 76 attributs, mais nous utilisons un sous-ensemble de 14 d’entre eux. Le modèle tente de prédire la présence de maladie cardiaque chez un patient. Il est entier compris entre 0 (aucune présence de maladie) et 1 (présence de maladie). Il a été entraîné à l’aide d’un classifieur XGBBoost et tout le prétraitement requis a été empaqueté en tant que pipeline scikit-learn, ce qui fait de ce modèle un pipeline de bout en bout qui passe des données brutes aux prédictions.

Les informations de cet article sont basées sur des exemples de code contenus dans le référentiel azureml-examples. Pour exécuter les commandes localement sans avoir à copier/coller les fichiers, clonez le dépôt, puis remplacez les répertoires par sdk/using-mlflow/deploy.

git clone https://github.com/Azure/azureml-examples --depth 1
cd sdk/python/using-mlflow/deploy

Prérequis

Avant de suivre les étapes décrites dans cet article, vérifiez que vous disposez des composants requis suivants :

  • Installer le package du SDK MLflow mlflow et le plug-in azureml-mlflow d’Azure Machine Learning pour MLflow de la manière suivante :

    pip install mlflow azureml-mlflow
    

    Conseil

    Vous pouvez utiliser le package mlflow-skinny qui est un package MLflow léger sans dépendances de stockage SQL, de serveur, d’interface utilisateur ou de science des données. Ce package est recommandé pour les utilisateurs qui ont principalement besoin des fonctionnalités de suivi et de journalisation de MLflow, sans importer la suite complète de fonctionnalités, notamment les déploiements.

  • Créez un espace de travail Azure Machine Learning. Pour créer un espace de travail, consultez Créer les ressources dont vous avez besoin pour commencer. Examinez les autorisations d’accès nécessaires pour effectuer vos opérations MLflow dans votre espace de travail.

  • Pour effectuer un suivi à distance, autrement dit, pour suivre des expériences qui s’exécutent en dehors d’Azure Machine Learning, configurez MLflow pour qu’il pointe vers l’URI de suivi de votre espace de travail Azure Machine Learning. Pour plus d’informations sur la connexion de MLflow à votre espace de travail, consultez Configurer MLflow pour Azure Machine Learning.

  • Vous devez disposer d’un modèle MLflow inscrit dans votre espace de travail. En particulier, cet exemple inscrit un modèle entraîné pour le jeu de données Diabète.

Se connecter à un espace de travail

Tout d’abord, nous allons nous connecter à l’espace de travail Azure Machine Learning où est inscrit votre modèle.

Le suivi est déjà configuré pour vous. Vos informations d’identification par défaut seront également utilisées dans le cadre de l’utilisation de MLflow.

Inscription du modèle

Nous avons besoin d’un modèle inscrit dans le registre Azure Machine Learning pour effectuer l’inférence. Dans ce cas, nous avons déjà une copie locale du modèle dans le référentiel. Nous devons donc uniquement publier le modèle dans le Registre dans l’espace de travail. Vous pouvez ignorer cette étape si le modèle que vous essayez de déployer est déjà inscrit.

model_name = 'heart-classifier'
model_local_path = "model"

registered_model = mlflow_client.create_model_version(
    name=model_name, source=f"file://{model_local_path}"
)
version = registered_model.version

Si votre modèle a été journalisé à l’intérieur d’une exécution, vous pouvez également l’inscrire directement.

Conseil

Pour inscrire le modèle, vous devez connaître son emplacement de stockage. Si vous utilisez la fonctionnalité autolog de MLflow, le chemin d’accès dépend du type et de l’infrastructure du modèle utilisé. Nous vous recommandons de vérifier la sortie des travaux pour identifier le nom de ce dossier. Vous pouvez rechercher le dossier qui contient un fichier nommé MLModel. Si vous journalisez manuellement vos modèles à l’aide de log_model, le chemin d’accès est l’argument que vous passez à cette méthode. En tant qu’exemple, si vous consignez le modèle à l’aide de mlflow.sklearn.log_model(my_model, "classifier"), le chemin d’accès où le modèle est stocké est classifier.

model_name = 'heart-classifier'

registered_model = mlflow_client.create_model_version(
    name=model_name, source=f"runs://{RUN_ID}/{MODEL_PATH}"
)
version = registered_model.version

Notes

Le chemin MODEL_PATH est l’emplacement où le modèle a été stocké dans l’exécution.


Obtenir les données d’entrée à évaluer

Nous aurons besoin quelques données d’entrée sur lesquelles exécuter nos travaux. Dans cet exemple, nous allons télécharger des exemples de données à partir d’Internet et les placer dans un stockage partagé utilisé par le cluster Spark.

import urllib

urllib.request.urlretrieve("https://azuremlexampledata.blob.core.windows.net/data/heart-disease-uci/data/heart.csv", "/tmp/data")

Déplacez les données vers un compte de stockage monté disponible pour l’ensemble du cluster.

dbutils.fs.mv("file:/tmp/data", "dbfs:/")

Important

Dans le code précédent, l’outil dbutils, disponible dans le cluster Azure Databricks, est utilisé. Utilisez l’outil approprié en fonction de la plateforme que vous utilisez.

Les données d’entrée sont ensuite placées dans le dossier suivant :

input_data_path = "dbfs:/data"

Exécuter le modèle dans des clusters Spark

La section suivante explique comment exécuter des modèles MLflow inscrits dans Azure Machine Learning dans des travaux Spark.

  1. Vérifiez que les bibliothèques suivantes sont installées dans le cluster :

    - mlflow<3,>=2.1
    - cloudpickle==2.2.0
    - scikit-learn==1.2.0
    - xgboost==1.7.2
    
  2. Nous allons utiliser un notebook pour montrer comment créer une routine de scoring avec un modèle MLflow inscrit dans Azure Machine Learning. Créez un notebook et utilisez PySpark comme langage par défaut.

  3. Importez les espaces de noms requis :

    import mlflow
    import pyspark.sql.functions as f
    
  4. Configurez l’URI du modèle. L’URI suivant apporte un modèle nommé heart-classifier dans sa version la plus récente.

    model_uri = "models:/heart-classifier/latest"
    
  5. Chargez le modèle comme fonction définie par l’utilisateur. Une fonction définie par l’utilisateur permet de réutiliser une logique personnalisée dans l’environnement utilisateur.

    predict_function = mlflow.pyfunc.spark_udf(spark, model_uri, result_type='double') 
    

    Conseil

    Utilisez l’argument result_type pour contrôler le type retourné par la fonction predict().

  6. Lisez les données que vous souhaitez évaluer :

    df = spark.read.option("header", "true").option("inferSchema", "true").csv(input_data_path).drop("target")
    

    Dans notre cas, les données d’entrée sont au format CSV et placées dans le dossier dbfs:/data/. Par ailleurs, nous supprimons la colonne target, car ce jeu de données contient la variable cible à prédire. Dans les scénarios de production, vos données n’incluront pas cette colonne.

  7. Exécutez la fonction predict_function et placez les prédictions dans une nouvelle colonne. Dans le cas présent, nous plaçons les prédictions dans la colonne predictions.

    df.withColumn("predictions", score_function(*df.columns))
    

    Conseil

    predict_function reçoit comme arguments les colonnes requises. Dans notre cas, toutes les colonnes du tableau de données sont attendues par le modèle. df.columns est donc utilisé. Si votre modèle nécessite un sous-ensemble des colonnes, vous pouvez les introduire manuellement. Si votre modèle a une signature, les types doivent être compatibles avec les entrées et les types attendus.

  8. Vous pouvez réécrire vos prédictions dans le stockage :

    scored_data_path = "dbfs:/scored-data"
    scored_data.to_csv(scored_data_path)
    

Exécuter le modèle dans un travail Spark autonome dans Azure Machine Learning

Azure Machine Learning prend en charge la création d’un travail Spark autonome et la création d’un composant Spark réutilisable, qui peut être utilisé dans des pipelines Azure Machine Learning. Dans cet exemple, nous allons déployer un travail de scoring qui s’exécute dans un travail Spark autonome Azure Machine Learning et exécute un modèle MLflow pour effectuer l’inférence.

Notes

Pour en savoir plus sur les travaux Spark dans Azure Machine Learning, consultez Soumettre des travaux Spark dans Azure Machine Learning (préversion).

  1. Un travail Spark nécessite un script Python qui prend des arguments. Créer un script de scoring :

    score.py

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--model")
    parser.add_argument("--input_data")
    parser.add_argument("--scored_data")
    
    args = parser.parse_args()
    print(args.model)
    print(args.input_data)
    
    # Load the model as an UDF function
    predict_function = mlflow.pyfunc.spark_udf(spark, args.model, env_manager="conda")
    
    # Read the data you want to score
    df = spark.read.option("header", "true").option("inferSchema", "true").csv(input_data).drop("target")
    
    # Run the function `predict_function` and place the predictions on a new column
    scored_data = df.withColumn("predictions", score_function(*df.columns))
    
    # Save the predictions
    scored_data.to_csv(args.scored_data)
    

    Le script ci-dessus prend trois arguments : --model, --input_data et --scored_data. Les deux premiers sont des entrées. Ils représentent le modèle que nous voulons exécuter et les données d’entrée. Le dernier est une sortie. Il s’agit du dossier de sortie où les prédictions seront placées.

    Conseil

    Installation des packages Python : Le script de scoring précédent charge le modèle MLflow dans une fonction définie par l’utilisateur, mais il indique le paramètre env_manager="conda". Quand ce paramètre est défini, MLflow restaure les packages requis comme spécifié dans la définition du modèle dans un environnement isolé où seule la fonction définie par l’utilisateur s’exécute. Pour obtenir des informations plus détaillées, consultez la documentation mlflow.pyfunc.spark_udf.

  2. Créez une définition de travail :

    mlflow-score-spark-job.yml

    $schema: http://azureml/sdk-2-0/SparkJob.json
    type: spark
    
    code: ./src
    entry:
      file: score.py
    
    conf:
      spark.driver.cores: 1
      spark.driver.memory: 2g
      spark.executor.cores: 2
      spark.executor.memory: 2g
      spark.executor.instances: 2
    
    inputs:
      model:
        type: mlflow_model
        path: azureml:heart-classifier@latest
      input_data:
        type: uri_file
        path: https://azuremlexampledata.blob.core.windows.net/data/heart-disease-uci/data/heart.csv
        mode: direct
    
    outputs:
      scored_data:
        type: uri_folder
    
    args: >-
      --model ${{inputs.model}}
      --input_data ${{inputs.input_data}}
      --scored_data ${{outputs.scored_data}}
    
    identity:
      type: user_identity
    
    resources:
      instance_type: standard_e4s_v3
      runtime_version: "3.2"
    

    Conseil

    Pour utiliser un pool Synapse Spark attaché, définissez compute la propriété dans l’exemple de fichier de spécification YAML illustré ci-dessus au lieu de la propriétéresources.

  3. Les fichiers YAML ci-dessus peuvent être utilisés dans la commande az ml job create avec le paramètre --file pour créer un travail Spark autonome comme indiqué ici :

    az ml job create -f mlflow-score-spark-job.yml
    

Étapes suivantes