Lisez notre article sur

.

MLflow est un outil couramment utilisé pour le suivi des expériences d'apprentissage automatique, le versionnage des modèles et le service. Dans notre premier article de la série “Serving ML models at scale”, nous expliquons comment déployer l'instance de suivi sur Kubernetes et l'utiliser pour enregistrer les expériences et stocker les modèles.

Partie 1 - Comment déployer une instance de suivi Mlflow sur Kubernetes ?

Introduction

Mlflow est un outil largement utilisé dans la communauté data science/ML pour suivre les expériences et gérer les modèles d'apprentissage automatique à différents stades. Grâce à lui, nous pouvons stocker des métriques, des modèles et des artefacts pour comparer facilement les performances des modèles et gérer leurs cycles de vie. En outre, Mlflow fournit un module pour servir les modèles en tant que point d'extrémité d'API, ce qui facilite leur intégration dans n'importe quel produit ou application web.

Cela dit, l'utilisation de l'apprentissage automatique dans les produits en ligne est cool, mais en fonction de la taille du modèle, de sa nature (ML, deep learning,... ) et de la charge (demandes des utilisateurs), il pourrait être difficile de dimensionner les ressources nécessaires et de garantir un temps de réponse raisonnable. Par conséquent, l'utilisation d'une infrastructure évolutive telle que les clusters Kubernetes est essentielle pour maintenir la disponibilité et la performance du service dans la phase d'inférence.

Dans ce contexte, nous publions une série de trois articles dans lesquels nous répondons aux questions suivantes :

  • Comment déployer et utiliser l'instance de suivi Mlflow sur Kubernetes ?
  • Comment servir des modèles d'apprentissage automatique en tant qu'API en utilisant Mlflow ?
  • Comment gérer un grand nombre de requêtes et rendre notre tâche d'inférence évolutive pour des produits industrialisés ?

Commençons donc ce premier article par une présentation de Kubernetes et de ses composants et passons par le déploiement d'une instance de suivi vers des modèles de logs.

Vue d'ensemble de Kubernetes

Kubernetes est un projet open-source lancé par Google en 2014. Il s'agit d'un système de contrôle et d'orchestration de conteneurs qui permet le déploiement, la mise à l'échelle et la planification automatiques d'applications. Son architecture est la suivante :

Image

Maître: Il gère les configurations d'entrée, planifie les applications conteneurisées sur les différents nœuds et surveille leurs états. Le maître est composé de :

  • Serveur API : permet l'interaction avec le cluster et valide les commandes envoyées par le développeur pour mettre à jour le cluster ou l'état de l'application.
  • Planificateur: décide les nœuds sur lesquels les nouveaux objets doivent être exécutés pour garantir la stabilité et l'équilibrage de la charge.
  • Etcd : une base de données clé-valeur database qui stocke les différentes configurations et états des ressources
  • Responsable du contrôle :surveille l'état de la grappe et les différentes ressources et s'assure que l'état actuel correspond à l'état souhaité.

Nœuds : ce sont les nœuds d'exécution dans lesquels vivent les conteneurs déployés. Leurs principaux composants sont les suivants

  • Cosse : sont l'unité d'exécution fondamentale de base dans Kubernetes. Un pod encapsule une application sous la forme d'un conteneur unique ou de plusieurs conteneurs qui fonctionnent ensemble avec des volumes de stockage et des réseaux partagés.
  • Kubelet :est un pour inspecter l'état des conteneurs et communiquer avec le maître Kubernetes.

C'est le choix idéal lorsqu'une application comporte plusieurs services qui communiquent entre eux, car il garantit que chaque service dispose de son propre environnement conteneurisé avec un ensemble de règles pour interagir avec les autres. En outre, il offre la possibilité intéressante de faire évoluer une application sans se soucier de la gestion ou de la synchronisation de nouveaux services et d'équilibrer les ressources entre différentes machines.

D'un point de vue de haut niveau, en tant que scientifiques data ou ingénieurs ML, nous interagirons avec Kubernetes via son API serveur en utilisant des commandes CLI ou des fichiers de configuration YAML, soit pour déployer et exposer des applications, soit pour obtenir les états de nos ressources.

Pré-requis pratiques

Pour ce travail pratique, nous utiliserons GCP comme fournisseur cloud. Tout d'abord, nous devons :

1. Créer les éléments d'infrastructure

  • mlflow_gke : un seau pour stocker les fichiers, datasets...
  • mlflow-k8s: un cluster GKE à trois nœuds (e2-highcpu-4) pour déployer à la fois le module de suivi et le modèle d'apprentissage automatique.

  • test de charge : un cluster GKE à trois nœuds (e2-standard-2) pour effectuer des tests de charge. Il sera utilisé dans le troisième article de cette série.

Image

2. Configurez le poste de travail local

  • Installez les exigences python pour interagir avec GCP et mlflow cli

    pip install mlflow gcsfs google-cloud google-cloud-storage kubernetes
  • Avoir gcloud et kubectl configuré avec les identifiants pour accéder au projet GCP et aux clusters
  • Le CLI Helm est installé et initialisé. S'il vous plaît trouvez ici les instructions au cas où vous n'auriez pas encore le client.

3. Clonez le dépôt du projet hands-on pour obtenir le code.

Déploiement de l'instance de suivi Mlflow

1. Configurez l'environnement du cluster

  • Créez un compte de service pour permettre l'interaction avec les GCS.
    Cela peut se faire via la console google cloud, sous la rubrique section iam. Nous devons créer un compte de service avec les droits d'administration de l'objet de stockage, générer une clé d'authentification et la télécharger sous la forme keyfile.json.
  • Monter le fichier d'authentification en tant que secret
    Les secrets nous permettent de traiter les informations d'identification de manière sécurisée, de sorte qu'elles ne soient visibles que par les ressources concernées. Pour cela, nous allons créer un volume secret et exposer le fichier d'authentification uniquement aux conteneurs nécessaires.
    kubectl create secret generic gcsfs-creds -from-file=./keyfile.json
Image

2. Suivi du déploiement du serveur

  • Magasin Postgres
    Postgre sert d'élément de stockage dorsal pour mlflow afin de sauvegarder les modèles metadata et les métriques.
    Pour le déployer, nous utiliserons Helm : un gestionnaire de ressources pour Kubernetes où de nombreuses applications sont disponibles sous forme de tableaux ou de modèles qui pourraient être configurés avec de simples commandes.

    #docs : https://artifacthub.io/packages/helm/bitnami/postgresqlhelm repo add bitnami https://charts.bitnami.com/bitnamihelm install mlf-db bitnami/postgresql --set postgresqlDatabase=mlflow_db --set postgresqlPassword=mlflow --set service.type=NodePort
  • Instance de suivi
    Nous utiliserons également les graphiques Helm pour déployer le serveur de suivi, mais d'abord, nous devons construire une image docker avec la version que nous voulons afin qu'elle puisse être téléchargée et déployée par Helm. Notez que pour Postgres, l'image était déjà sur un dépôt public, cependant ici nous allons créer notre propre image.

    cd mlflow-serving-exampledocker build --tag $/mlflow-tracking-server:v1 --file dockerfile_mlflow_tracking .docker push $/mlflow-tracking-server:v1

Une fois l'image poussée dans le registre d'images, nous pouvons la déployer sur le cluster via helm en utilisant les commandes ci-dessous.

helm repo add mlflow-tracking https://artefactory-global.github.io/mlflow-tracking-server/helm install mlf-ts mlflow-tracking/mlflow-tracking-server
--set env.mlflowArtifactPath=$
--set env.mlflowDBAddr=mlf-db-postgresql
--set env.mlflowUser=postgres
--set env.mlflowPass=mlflow
--set env.mlflowDBName=mlflow_db
--set env.mlflowDBPort=5432
--set service.type=LoadBalancer
--set image.repository=$/mlflow-tracking-server
--set image.tag=v1

Maintenant, Mlflow devrait être opérationnel et l'interface utilisateur devrait être accessible via l'IP de l'équilibreur de charge. Nous pouvons vérifier l'IP assignée en utilisant kubectl get services.ANous pouvons également déboguer le déploiement en accédant aux journaux. via kubectl describe pods.
Jusqu'à présent, notre architecture actuelle ressemble à ce qui suit :

Image

Veuillez noter que les équilibreurs de charge sont accessibles à n'importe qui sur internet, il est donc essentiel de penser à sécuriser notre instance de suivi en ajoutant une couche d'authentification. Cela peut être fait avec l'option proxy tenant compte de l'identité sur GCP mais ne sera pas abordé dans cet article.

3. Création d'un modèle de base

Maintenant que notre infrastructure et notre instance Mlflow sont prêtes, nous pouvons essayer d'exécuter un modèle ML simple et l'enregistrer dans le registre des modèles pour une utilisation ultérieure.
Nous utiliserons l'ensemble dataset sur la qualité du vin, qui est composé d'environ 4900 échantillons et de 11 caractéristiques reflétant les caractéristiques du vin. Les étiquettes vont de 3 à 9 et peuvent être considérées comme des notes.
Il s'agit d'un exemple classique, dans lequel nous formons un modèle de régression Xgboost et le stockons avec ses paramètres et métriques. Le code complet peut être trouvé dans ce document carnet de notes.
Vous avez peut-être remarqué que l'intégration de Mlflow est simple et qu'elle peut être résumée dans l'extrait de code ci-dessous qui invoque mlflow.start_run(), mlflow.log_param(), mlflow.log_metric() et mlflow.xgboost.log_model()pour respectivement créer une nouvelle expérience, stocker les paramètres d'entraînement, les mesures d'évaluation et le modèle entraîné lui-même.

avec mlflow.start_run() comme run : # Démarrer la session mlflow mlflow.log_param("max_depth", max_depth) mlflow.log_param("min_child_weight", min_child_weight) mlflow.log_param("estimators", estimators) # Créer et ajuster le modèle model = xgb.XGBRegressor( max_depth=max_depth, min_child_weight=min_child_weight, n_estimateurs=estimateurs random_state=42) model.fit(X_train, y_train) Métriques MLflow # predictions = model.predict(X_test) rmse = np.sqrt(mean_squared_error(y_test, predictions)) mlflow.log_metric("rmse", rmse) Modèle logarithmique # mlflow.xgboost.log_model(model, "xgboost-model", registered_model_name = model_name)

En exécutant le carnet fourni, une nouvelle ligne sera ajoutée dans l'interface de l'instance de suivi qui correspond à la nouvelle expérience.

Image

Enfin, en supposant que nous soyons satisfaits des performances du modèle, nous pouvons le charger à partir de l'instance de suivi et l'utiliser pour l'inférence en Python. Ceci pourrait être fait également avec le notebook partagé précédemment. Notez que dans cet exemple, nous avons chargé le modèle en utilisant le run ID mais gardez à l'esprit que Mlflow offre également d'autres façons intéressantes d'identifier les modèles par des tags, des versions, ou des étapes. Pour plus de détails, veuillez vous référer à la documentation du registre des modèles. ici.

Conclusion

Tout au long de cet article, nous avons réussi à déployer une instance de suivi Mlflow pour gérer nos expériences scientifiques data et nous avons passé en revue un exemple rapide montrant comment enregistrer un modèle et le sauvegarder pour une inférence future sur python. Dans le prochain article de cette série, nous apprendrons comment servir ce modèle en tant qu'API. Cela a une grande importance car cela facilite l'interaction avec le modèle et son intégration dans un produit ou une application. De plus, le fait de le faire sur Kubernetes garantit qu'il reste facilement évolutif et capable de gérer différents niveaux de charge.

Moyen Blog par Artefact.

Cet article a été initialement publié sur Medium.com.
Suivez-nous sur notre Medium Blog !