Kubeflow Pipelines – Synthèse de problèmes sur GitHub

1. Introduction

Kubeflow est un kit d'outils de machine learning pour Kubernetes. Ce projet vise à simplifier le déploiement des workflows de machine learning (ML) sur Kubernetes, et à les rendre portables et évolutifs. L'objectif est de fournir un moyen simple de déployer les meilleurs systèmes Open Source pour le ML sur diverses infrastructures.

Un workflow de machine learning peut comporter de nombreuses étapes qui dépendent les unes des autres, de la préparation et de l'analyse des données, en passant par l'entraînement, l'évaluation et le déploiement. Il est difficile de composer et de suivre ces processus de manière ad hoc (par exemple, dans un ensemble de notebooks ou de scripts), et des aspects comme l'audit et la reproductibilité deviennent de plus en plus problématiques.Kubeflow Pipelines (KFP) aide à résoudre ces problèmes en permettant de déployer des pipelines de machine learning robustes et reproductibles, ainsi que la surveillance, l'audit, le suivi des versions et la reproductibilité. Cloud AI Pipelines facilite la configuration d'une installation KFP.

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez créer une application Web qui résume les problèmes de GitHub en utilisant Kubeflow Pipelines pour entraîner et diffuser un modèle. Il est basé sur un exemple du dépôt d'exemples Kubeflow. À la fin de cet atelier, votre infrastructure comprendra les éléments suivants :

  • Un cluster Google Kubernetes Engine (GKE) sur lequel Kubeflow Pipelines est installé (via Cloud AI Pipelines)
  • Pipeline qui entraîne un modèle Tensor2Tensor sur des GPU
  • Un conteneur d'inférence qui fournit des prédictions à partir du modèle entraîné
  • Une UI qui interprète les prédictions pour fournir des résumés des problèmes GitHub
  • Un notebook qui crée un pipeline à partir de zéro à l'aide du SDK Kubeflow Pipelines (KFP)

Points abordés

Le pipeline que vous allez créer entraîne un modèle Tensor2Tensor à partir de données GitHub relatives aux problèmes afin d'apprendre à prédire les titres des problèmes à partir des instances de problèmes. Il exporte ensuite le modèle entraîné et déploie le modèle exporté à l'aide de Tensorflow Serving. La dernière étape du pipeline lance une application Web, qui interagit avec l'instance TF-Serving afin d'obtenir des prédictions du modèle.

  • Installer Kubeflow Pipelines sur un cluster GKE
  • Créer et exécuter des workflows de ML à l'aide de Kubeflow Pipelines
  • Définir et exécuter des pipelines à partir d'un notebook AI Platform

Prérequis

2. Configuration

Cloud Shell

Accédez à la console GCP dans le navigateur et connectez-vous à l'aide des identifiants de votre projet:

Cliquez sur "Sélectionner un projet" afin de travailler sur votre projet d'atelier de programmation.

4f23e1fe87a47cb2.png

Cliquez ensuite sur "Activer Cloud Shell" située dans l'angle supérieur droit de la console pour démarrer une session Cloud Shell.

ecf212797974dd31.png

Lorsque vous démarrez Cloud Shell, le nom du projet est indiqué. Vérifiez que ce paramètre est correct.

Pour trouver l'ID de votre projet, accédez au panneau de configuration de la console GCP. Si l'écran est vide, cliquez sur "Oui". à l'invite pour créer un tableau de bord.

115cdf745978ad.png

Ensuite, dans le terminal Cloud Shell, exécutez les commandes suivantes, si nécessaire, pour configurer gcloud afin qu'il utilise le bon projet:

export PROJECT_ID=<your_project_id>
gcloud config set project ${PROJECT_ID}

Créer un bucket de stockage

créer un bucket Cloud Storage pour stocker les fichiers du pipeline. Vous devrez utiliser un ID unique. Il est donc pratique de définir un nom de bucket incluant l'ID de votre projet. Créez le bucket à l'aide de la commande gsutil mb (make bucket) :

export PROJECT_ID=<your_project_id>
export BUCKET_NAME=kubeflow-${PROJECT_ID}
gsutil mb gs://${BUCKET_NAME}

Vous pouvez également créer un bucket via la console GCP.

Facultatif**: Créer un jeton GitHub**

Cet atelier de programmation appelle l'API GitHub pour récupérer des données accessibles au public. Pour éviter la limitation du débit, en particulier lors d'événements où un grand nombre de requêtes anonymisées sont envoyées aux API GitHub, configurez un jeton d'accès sans autorisation. Vous disposerez ainsi d'une autorisation personnelle et ne serez plus considéré comme un utilisateur anonyme.

  1. Accédez à https://github.com/settings/tokens et générez un nouveau jeton sans champ d'application.
  2. Conservez-le en lieu sûr. Si vous le perdez, vous devrez le supprimer et en créer un autre.

Si vous ignorez cette étape, l'atelier continuera de fonctionner, mais vos options de génération de données d'entrée pour tester votre modèle seront un peu plus limitées.

Facultatif: Épingler les tableaux de bord utiles

Dans la console GCP, épinglez les tableaux de bord Kubernetes Engine et Stockage pour y accéder plus facilement.

2a50622902d75f6a.png

Créer une installation AI Platform Pipelines (Kubeflow Pipelines hébergé)

Suivez les instructions de la section "Avant de commencer" et "Configurer votre instance" sur cette page pour configurer une instance GKE sur laquelle KFP est installé. Veillez à cocher la case Autoriser l'accès aux API Cloud suivantes comme indiqué dans la documentation. (Si vous ne le faites pas, l'exemple de pipeline ne s'exécutera pas correctement.) Laissez l'espace de noms d'installation default.

Vous devez choisir une zone compatible avec les Nvidia k80s. Vous pouvez utiliser us-central1-a ou us-central1-c par défaut.

Une fois l'installation terminée, notez le nom du cluster et la zone GKE répertoriés pour votre installation dans le tableau de bord AI Pipelines. Pour plus de commodité, définissez les variables d'environnement sur ces valeurs.

6f0729a4fdee88ac.png

export ZONE=<your zone>
export CLUSTER_NAME=<your cluster name>

Configurez kubectl de façon à utiliser les identifiants de votre nouveau cluster GKE

Une fois le cluster GKE créé, configurez kubectl de sorte qu'il utilise les identifiants du nouveau cluster en exécutant la commande suivante dans Cloud Shell:

gcloud container clusters get-credentials ${CLUSTER_NAME} \
  --project ${PROJECT_ID} \
  --zone ${ZONE}

Vous pouvez également cliquer sur le nom du cluster dans le tableau de bord AI Pipelines pour accéder à sa page GKE, puis cliquer sur "Connecter" en haut de la page. Dans le pop-up, collez la commande dans Cloud Shell.

Cette commande configure votre contexte kubectl afin que vous puissiez interagir avec votre cluster. Pour vérifier la configuration, exécutez la commande suivante:

kubectl get nodes -o wide

Les nœuds affichant l'état Ready doivent s'afficher, ainsi que d'autres informations sur l'âge du nœud, la version, l'adresse IP externe, l'image de l'OS, la version du noyau et l'environnement d'exécution du conteneur.

Configurer le cluster pour installer le pilote Nvidia sur les pools de nœuds compatibles GPU

Nous allons ensuite appliquer un daemonset au cluster, qui installera le pilote Nvidia sur tous les nœuds de cluster compatibles GPU:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml

Exécutez ensuite la commande suivante, qui donne aux composants KFP l'autorisation de créer des ressources Kubernetes:

kubectl create clusterrolebinding sa-admin --clusterrole=cluster-admin --serviceaccount=kubeflow:pipeline-runner

Créer un pool de nœuds GPU

Ensuite, nous allons configurer un pool de nœuds GPU d'une taille de 1:

gcloud container node-pools create gpu-pool \
    --cluster=${CLUSTER_NAME} \
    --zone ${ZONE} \
    --num-nodes=1 \
    --machine-type n1-highmem-8 \
    --scopes cloud-platform --verbosity error \
    --accelerator=type=nvidia-tesla-k80,count=1

3. Exécuter un pipeline à partir du tableau de bord des pipelines

Ouvrir le tableau de bord des pipelines

Dans la console Cloud, accédez au panneau Pipelines, si ce n'est pas déjà fait. Cliquez ensuite sur OUVRIR LE TABLEAU DE BORD DES PIPELINES. de votre installation, puis cliquez sur Pipelines dans la barre de menu de gauche. Si une erreur de chargement s'affiche, actualisez l'onglet. Une nouvelle page semblable à celle-ci doit s'afficher:

7bb5a9cf0773c3bc.png

Description du pipeline

Le pipeline que vous allez exécuter comporte plusieurs étapes (consultez l'annexe de cet atelier de programmation pour plus de détails):

  1. Un point de contrôle de modèle existant est copié dans votre bucket.
  2. Un modèle Tensor2Tensor est entraîné à l'aide de données prétraitées.
  • L'entraînement commence à partir du point de contrôle du modèle existant copié à la première étape, puis effectue l'entraînement pour encore quelques centaines de pas. (L'entraînement complet prendrait trop de temps au cours de l'atelier de programmation.)
  • Une fois l'entraînement terminé, l'étape du pipeline exporte le modèle dans un format adapté à l'inférence par TensorFlow Serving.
  1. Une instance de diffusion TensorFlow est déployée à l'aide de ce modèle.
  2. Une application Web est lancée pour interagir avec le modèle diffusé afin de récupérer des prédictions.

Télécharger et compiler le pipeline

Dans cette section, nous allons voir comment compiler une définition de pipeline. La première chose à faire est d'installer le SDK KFP. Exécutez la commande suivante dans Cloud Shell:

pip3 install -U kfp

Pour télécharger le fichier de définition du pipeline, exécutez cette commande à partir de Cloud Shell:

curl -O https://raw.githubusercontent.com/amygdala/kubeflow-examples/ghsumm/github_issue_summarization/pipelines/example_pipelines/gh_summ_hosted_kfp.py

Ensuite, compilez le fichier de définition du pipeline en l'exécutant comme suit:

python3 gh_summ_hosted_kfp.py

Le fichier gh_summ_hosted_kfp.py.tar.gz apparaît comme résultat.

Importer le pipeline compilé

Dans l'interface utilisateur Web de Kubeflow Pipelines, cliquez sur Upload pipeline (Importer un pipeline), puis sélectionnez Import by URL (Importer par URL). Copiez, puis collez l'URL suivante, qui pointe vers le même pipeline que celui que vous venez de compiler. L'importation d'un fichier à partir de Cloud Shell s'effectue en quelques étapes supplémentaires. Nous utilisons donc un raccourci.

https://storage.googleapis.com/aju-dev-demos-codelabs/KF/compiled_pipelines/gh_summ_hosted_kfp.py.tar.gz

Attribuez un nom au pipeline (par exemple, gh_summ).

867fdbe248d13bab.png

Exécuter le pipeline

Cliquez sur le pipeline importé dans la liste (ce qui vous permet d'afficher le graphique statique du pipeline), puis cliquez sur Créer un test pour créer un test à l'aide du pipeline. Un test permet de regrouper des exécutions sémantiquement liées.

d4b5b1a043d32d4a.png

Attribuez un nom au test (par exemple, le même que celui du pipeline, gh_summ), puis cliquez sur Suivant pour créer le test.

d9f7d2177efad53.png

Une page s'affiche, dans laquelle vous pouvez saisir les paramètres d'une exécution et la démarrer.

Vous pouvez exécuter les commandes suivantes dans Cloud Shell pour renseigner plus facilement les paramètres.

gcloud config get-value project
echo "gs://${BUCKET_NAME}/codelab"

Le nom de l'exécution est renseigné automatiquement, mais vous pouvez lui en attribuer un autre si vous le souhaitez.

Renseignez ensuite les trois champs de paramètre:

  • project
  • (facultatif) github-token
  • working-dir

Pour le répertoire de travail, saisissez un chemin d'accès sous le bucket GCS que vous avez créé. Inclure "gs://" préfixe. Dans le champ github-token, saisissez le jeton que vous avez éventuellement généré précédemment, ou laissez la chaîne d'espace réservé telle quelle si vous n'avez pas généré de jeton.

8676afba6fd32ac1.png

Après avoir rempli les champs, cliquez sur Start (Démarrer), puis sur l'exécution répertoriée pour en afficher les détails. Lorsqu'une étape du pipeline est en cours d'exécution, vous pouvez cliquer dessus pour obtenir plus d'informations à son sujet, y compris pour consulter les journaux de son pod. Vous pouvez également consulter les journaux d'une étape du pipeline via le lien vers ses journaux Cloud Logging (Stackdriver), même si le nœud du cluster a été supprimé.

db2dc819ac0f5c1.png

Afficher la définition du pipeline

Vous pouvez examiner de plus près comment il est structuré et ce qu'il fait pendant l'exécution du pipeline. Vous trouverez plus de détails dans la section Annexe de l'atelier de programmation.

Afficher les informations sur l'entraînement de modèle dans TensorBoard

Une fois l'étape d'entraînement terminée, sélectionnez l'onglet Visualizations (Visualisations) correspondant, cliquez sur le bouton bleu Start TensorBoard (Démarrer TensorBoard), puis sur Open TensorBoard (Ouvrir TensorBoard).

6cb511540a64b9e5.png

d55eb03c4d04f64d.png

Explorer le tableau de bord "Artefacts et exécutions"

Kubeflow Pipelines enregistre automatiquement les métadonnées sur les étapes du pipeline au fur et à mesure de son exécution. Les informations d'Artifact et d'Artifact sont enregistrées. Cliquez sur ces entrées dans la barre de navigation de gauche du tableau de bord pour les explorer plus en détail.

3002c4055cc8960b.png

Pour les artefacts, vous pouvez afficher à la fois un panneau de présentation et un panneau d'explorateur de traçabilité.

7885776e899d1183.png

40c4f7e5b6545dec.png

Afficher l'application Web créée par le pipeline et effectuer des prédictions

La dernière étape du pipeline déploie une application Web, qui fournit une UI permettant d'interroger le modèle entraîné (diffusé via TF Serving) afin d'effectuer des prédictions.

Une fois le pipeline terminé, connectez-vous à l'application Web via un transfert de port vers son service (il s'agit d'un transfert de port, car pour cet atelier de programmation, le service webapp n'est pas configuré pour disposer d'un point de terminaison externe).

Recherchez le nom du service en exécutant la commande suivante dans Cloud Shell:

kubectl get services

Recherchez un nom de service semblable à celui-ci: ghsumm-*-webappsvc dans la liste.

Ensuite, dans Cloud Shell, effectuez un transfert de port vers ce service comme suit, en modifiant la commande suivante pour qu'elle utilise le nom de votre variable webappsvc:

kubectl port-forward svc/ghsumm-xxxxx-webappsvc 8080:80

Une fois le transfert de port en cours d'exécution, cliquez sur "Aperçu" située au-dessus du volet Cloud Shell, puis dans le menu déroulant, cliquez sur "Prévisualiser sur le port 8080".

65572bb3b12627cc.png

Vous devriez voir une page comme celle-ci s'afficher dans un nouvel onglet:

902ad2d555281508.png

Cliquez sur le bouton Populate Random Issue (Remplir un problème aléatoire) pour récupérer un bloc de texte. Cliquez sur Generate TItle (Générer un titre) pour appeler le modèle entraîné et afficher une prédiction.

b7c39ce51ee603bd.png

Si les paramètres de votre pipeline incluaient un jeton GitHub valide, vous pouvez également saisir une URL GitHub dans le deuxième champ, puis cliquer sur "Generate Title" (Générer un titre). Si vous n'avez pas configuré de jeton GitHub valide, utilisez uniquement la commande "Populate Random Issue" (Renseigner le problème aléatoire). .

4. Exécuter un pipeline à partir d'un notebook AI Platform

Vous pouvez également définir et exécuter de manière interactive des pipelines Kubeflow à partir d'un notebook Jupyter à l'aide du SDK KFP. AI Platform Notebooks, que nous allons utiliser pour cet atelier de programmation, vous simplifie la tâche.

Créer une instance de notebook

Nous allons créer une instance de notebook à partir de Cloud Shell à l'aide de son API. Vous pouvez également créer un notebook via la console Cloud. Pour en savoir plus, consultez la documentation.

Définissez les variables d'environnement suivantes dans Cloud Shell:

export INSTANCE_NAME="kfp-ghsumm"
export VM_IMAGE_PROJECT="deeplearning-platform-release"
export VM_IMAGE_FAMILY="tf2-2-3-cpu"
export MACHINE_TYPE="n1-standard-4"
export LOCATION="us-central1-c"

Ensuite, à partir de Cloud Shell, exécutez la commande suivante pour créer l'instance de notebook:

gcloud beta notebooks instances create $INSTANCE_NAME \
  --vm-image-project=$VM_IMAGE_PROJECT \
  --vm-image-family=$VM_IMAGE_FAMILY \
  --machine-type=$MACHINE_TYPE --location=$LOCATION

Lorsque vous exécutez cette commande pour la première fois, vous pouvez être invité à activer l'API notebooks pour votre projet. Répondre "y" si c'est le cas.

Après quelques minutes, votre serveur de notebooks sera opérationnel. Vos instances de notebook sont répertoriées dans Cloud Console.

206adf3905413dfa.png

Importer le notebook de l'atelier de programmation

Une fois l'instance de notebook créée, cliquez sur ce lien pour importer le notebook Jupyter de l'atelier de programmation. Sélectionnez l'instance de notebook à utiliser. Le notebook s'ouvre automatiquement.

Exécuter le notebook

Suivez les instructions fournies dans le notebook pour la suite de l'atelier. Notez que dans la section "Configuration" du notebook, vous devez saisir vos propres valeurs avant d'exécuter le reste du notebook.

(Si vous utilisez votre propre projet, n'oubliez pas de revenir et de suivre la section "Effectuer un nettoyage" de cet atelier.)

5. Effectuer un nettoyage

Vous n'avez pas besoin de le faire si vous utilisez un compte temporaire d'atelier de programmation, mais vous pouvez supprimer votre installation de pipelines et votre notebook si vous utilisez votre propre projet.

Supprimer le cluster GKE Pipelines

Vous pouvez supprimer le cluster Pipelines depuis la console Cloud. (Vous avez la possibilité de simplement supprimer l'installation de Pipelines si vous souhaitez réutiliser le cluster GKE.)

Supprimer l'instance AI Notebook

Si vous avez exécuté "Notebook" vous pouvez SUPPRIMER ou ARRÊTER l'instance de notebook depuis la console Cloud.

Facultatif: Supprimer le jeton GitHub

Accédez à https://github.com/settings/tokens et supprimez le jeton généré.

6. Annexes

Aperçu du code

Définir le pipeline

Le pipeline utilisé dans cet atelier de programmation est défini sur cette page.

Voyons comment il est défini, ainsi que ses composants (étapes). Nous en présenterons quelques-uns, mais consultez la documentation pour en savoir plus.

Les étapes du pipeline Kubeflow sont basées sur des conteneurs. Lorsque vous créez un pipeline, vous pouvez utiliser des composants prédéfinis avec des images de conteneur déjà créées, ou créer vos propres composants. Pour cet atelier de programmation, nous avons créé le nôtre.

Quatre étapes du pipeline sont définies à partir de composants réutilisables, accessibles via leurs fichiers de définition de composants. Dans ce premier extrait de code, nous accédons à ces fichiers de définition de composants via leur URL, et nous utilisons ces définitions pour créer des opérations. que nous utiliserons pour créer une étape du pipeline.

import kfp.dsl as dsl
import kfp.gcp as gcp
import kfp.components as comp

...

copydata_op = comp.load_component_from_url(
  'https://raw.githubusercontent.com/kubeflow/examples/master/github_issue_summarization/pipelines/components/t2t/datacopy_component.yaml'
  )

train_op = comp.load_component_from_url(
  'https://raw.githubusercontent.com/kubeflow/examples/master/github_issue_summarization/pipelines/components/t2t/train_component.yaml'
  )

Vous trouverez ci-dessous l'une des définitions des composants, correspondant à l'opération d'entraînement, au format YAML. Comme vous pouvez le constater, ses entrées, ses sorties, son image de conteneur et ses arguments de point d'entrée du conteneur sont définis.

name: Train T2T model
description: |
  A Kubeflow Pipeline component to train a Tensor2Tensor
  model
metadata:
  labels:
    add-pod-env: 'true'
inputs:
  - name: train_steps
    description: '...'
    type: Integer
    default: 2019300
  - name: data_dir
    description: '...'
    type: GCSPath
  - name: model_dir
    description: '...'
    type: GCSPath
  - name: action
    description: '...'
    type: String
  - name: deploy_webapp
    description: '...'
    type: String
outputs:
  - name: launch_server
    description: '...'
    type: String
  - name: train_output_path
    description: '...'
    type: GCSPath
  - name: MLPipeline UI metadata
    type: UI metadata
implementation:
  container:
    image: gcr.io/google-samples/ml-pipeline-t2ttrain:v3ap
    args: [
      --data-dir, {inputValue: data_dir},
      --action, {inputValue: action},
      --model-dir, {inputValue: model_dir},
      --train-steps, {inputValue: train_steps},
      --deploy-webapp, {inputValue: deploy_webapp},
      --train-output-path, {outputPath: train_output_path}
    ]
    env:
      KFP_POD_NAME: "{{pod.name}}"
    fileOutputs:
      launch_server: /tmp/output
      MLPipeline UI metadata: /mlpipeline-ui-metadata.json

Vous pouvez également définir une étape du pipeline via le constructeur dsl.ContainerOp, comme nous le verrons ci-dessous.

Vous trouverez ci-dessous l'essentiel de la définition du pipeline. Nous définissons les entrées du pipeline (et leurs valeurs par défaut). Ensuite, nous définissons les étapes du pipeline. Dans la plupart des cas, nous utilisons défini ci-dessus, mais nous définissons aussi étape intégrée via ContainerOp, en spécifiant directement l'image de conteneur et les arguments de point d'entrée.

Vous pouvez constater que les étapes train, log_model et serve accèdent aux sorties des étapes précédentes en tant qu'entrées. Pour en savoir plus sur la spécification de ces règles, cliquez ici.

@dsl.pipeline(
 name='Github issue summarization',
 description='Demonstrate Tensor2Tensor-based training and TF-Serving'
)
def gh_summ(  #pylint: disable=unused-argument
 train_steps: 'Integer' = 2019300,
 project: str = 'YOUR_PROJECT_HERE',
 github_token: str = 'YOUR_GITHUB_TOKEN_HERE',
 working_dir: 'GCSPath' = 'gs://YOUR_GCS_DIR_HERE',
 checkpoint_dir: 'GCSPath' = 'gs://aju-dev-demos-codelabs/kubecon/model_output_tbase.bak2019000/',
 deploy_webapp: str = 'true',
 data_dir: 'GCSPath' = 'gs://aju-dev-demos-codelabs/kubecon/t2t_data_gh_all/'
 ):


 copydata = copydata_op(
   data_dir=data_dir,
   checkpoint_dir=checkpoint_dir,
   model_dir='%s/%s/model_output' % (working_dir, dsl.RUN_ID_PLACEHOLDER),
   action=COPY_ACTION,
   )


 train = train_op(
   data_dir=data_dir,
   model_dir=copydata.outputs['copy_output_path'],
   action=TRAIN_ACTION, train_steps=train_steps,
   deploy_webapp=deploy_webapp
   )

 serve = dsl.ContainerOp(
     name='serve',
     image='gcr.io/google-samples/ml-pipeline-kubeflow-tfserve:v6',
     arguments=["--model_name", 'ghsumm-%s' % (dsl.RUN_ID_PLACEHOLDER,),
         "--model_path", train.outputs['train_output_path']
         ]
     )

 train.set_gpu_limit(1)

Notez que nous exigeons l'option "train" à exécuter sur un nœud du cluster disposant d'au moins un GPU.

  train.set_gpu_limit(1)

La dernière étape du pipeline, également définie de façon intégrée, est conditionnelle. Elle s'exécutera après "serve" est terminée, uniquement si la sortie launch_server de l'étape d'entraînement est la chaîne "true". Il lance l'application Web de prédiction, que nous avons utilisée pour demander des résumés des problèmes à partir du modèle T2T entraîné.

 with dsl.Condition(train.outputs['launch_server'] == 'true'):
   webapp = dsl.ContainerOp(
       name='webapp',
       image='gcr.io/google-samples/ml-pipeline-webapp-launcher:v1',
       arguments=["--model_name", 'ghsumm-%s' % (dsl.RUN_ID_PLACEHOLDER,),
           "--github_token", github_token]

       )
   webapp.after(serve)

Définitions des images de conteneurs du composant

La documentation de Kubeflow Pipelines décrit quelques bonnes pratiques pour créer vos propres composants. Dans le cadre de ce processus, vous devez définir et créer une image de conteneur. Pour consulter les étapes des composants du pipeline de cet atelier de programmation, cliquez ici. Les définitions de Dockerfile se trouvent dans les sous-répertoires containers. Exemple : cliquez ici.

Utiliser des VM préemptives avec des GPU pour l'entraînement

Les VM préemptives sont des instances de VM Compute Engine qui durent jusqu'à 24 heures et n'offrent aucune garantie de disponibilité. Les tarifs des VM préemptives sont inférieurs à ceux des VM Compute Engine standards.

Avec Google Kubernetes Engine (GKE), il est facile de configurer un cluster ou un pool de nœuds utilisant des VM préemptives. Vous pouvez configurer ce type de pool de nœuds avec des GPU connectés aux instances préemptives. Ils fonctionnent de la même manière que les nœuds standards compatibles GPU, mais les GPU ne persistent que pendant la durée de vie de l'instance.

Vous pouvez configurer un pool de nœuds préemptifs compatibles GPU pour votre cluster. Pour ce faire, exécutez une commande semblable à la suivante, modifiez-la en indiquant le nom et la zone de votre cluster, puis ajustez le type et le nombre d'accélérateurs en fonction de vos besoins. Vous pouvez éventuellement définir le pool de nœuds pour qu'il effectue l'autoscaling en fonction des charges de travail actuelles.

gcloud container node-pools create preemptible-gpu-pool \
    --cluster=<your-cluster-name> \
    --zone <your-cluster-zone> \
    --enable-autoscaling --max-nodes=4 --min-nodes=0 \
    --machine-type n1-highmem-8 \
    --preemptible \
    --node-taints=preemptible=true:NoSchedule \
    --scopes cloud-platform --verbosity error \
    --accelerator=type=nvidia-tesla-k80,count=4

Vous pouvez également configurer un pool de nœuds via la console Cloud.

Définir un pipeline Kubeflow qui utilise les nœuds GKE préemptifs

Si vous exécutez Kubeflow sur GKE, vous pouvez désormais facilement définir et exécuter Kubeflow Pipelines, dans lequel une ou plusieurs étapes du pipeline (composants) s'exécutent sur des nœuds préemptifs, ce qui réduit le coût d'exécution d'un job. Pour que l'utilisation de VM préemptives donne des résultats corrects, les étapes que vous identifiez comme étant préemptives doivent être idempotentes (c'est-à-dire que si vous exécutez une étape plusieurs fois, vous obtiendrez le même résultat) ou faire un point de contrôle afin que l'étape puisse reprendre là où elle s'était arrêtée en cas d'interruption.

Lorsque vous définissez un pipeline Kubeflow, vous pouvez indiquer qu'une étape donnée doit s'exécuter sur un nœud préemptif en modifiant l'opération comme suit:

your_pipelines_op.apply(gcp.use_preemptible_nodepool())

Pour en savoir plus, consultez la documentation.

Si le nœud est préempté, vous souhaiterez probablement effectuer cette étape plusieurs fois. Vous pouvez le faire comme suit : ici, nous spécifions 5 tentatives.

your_pipelines_op.set_gpu_limit(1).apply(gcp.use_preemptible_nodepool()).set_retry(5)

Modifiez le pipeline Kubeflow que nous avons utilisé dans cet atelier de programmation pour exécuter l'étape d'entraînement sur une VM préemptive.

Modifiez la ligne suivante dans la spécification du pipeline pour utiliser en plus un pool de nœuds préemptif (assurez-vous d'en avoir créé un comme indiqué ci-dessus) ci-dessus, et réessayez cinq fois:

  train.set_gpu_limit(1)

Ensuite, recompilez le pipeline, importez la nouvelle version (attribuez-lui un nouveau nom), puis exécutez la nouvelle version du pipeline.