Déployer un système d'inférence TensorFlow évolutif

Last reviewed 2023-11-02 UTC

Ce document explique comment déployer l'architecture de référence décrite dans la section Système d'inférence TensorFlow évolutif.

Cette série est destinée aux développeurs qui connaissent déjà les frameworks de Google Kubernetes Engine et de machine learning (ML), y compris TensorFlow et NVIDIA TensorRT.

Une fois ce déploiement terminé, consultez la section Mesurer et régler les performances d'un système d'inférence TensorFlow.

Architecture

Le schéma suivant illustre l'architecture du système d'inférence.

Architecture du système d'inférence.

Cloud Load Balancing envoie le trafic de la requête vers le cluster GKE le plus proche. Le cluster contient un pod pour chaque nœud. Dans chaque pod, un serveur d'inférence Triton fournit un service d'inférence (pour diffuser des modèles ResNet-50) et un GPU NVIDIA T4 améliore les performances. Les serveurs de surveillance du cluster collectent des données de métriques sur l'utilisation du GPU et de la mémoire.

Pour en savoir plus, consultez la section Système d'inférence TensorFlow évolutif.

Objectifs

  • Télécharger un modèle ResNet-50 pré-entraîné et utiliser l'intégration de TensorFlow avec TensorRT (TF-TRT) pour appliquer des optimisations
  • Diffuser un modèle ResNet-50 à partir d'un serveur d'inférence NVIDIA Triton
  • Créer un système de surveillance pour Triton à l'aide de Prometheus et de Grafana.
  • Créer un outil de test de charge à l'aide de Locust.

Coûts

Outre le GPU NVIDIA T4, vous utilisez les composants facturables Google Cloud suivants dans ce déploiement :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.

Une fois ce déploiement terminé, ne supprimez pas les ressources que vous avez créées. Vous aurez besoin de ces ressources pour mesurer et régler le déploiement.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activez l'API GKE

    Activer l'API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  7. Activez l'API GKE

    Activer l'API

Créer des modèles optimisés avec TF-TRT

Dans cette section, vous allez créer un environnement de travail et optimiser le modèle pré-entraîné.

Le modèle pré-entraîné utilise l'ensemble de données factice situé à l'adresse gs://cloud-tpu-test-datasets/fake_imagenet/. Il existe également une copie du modèle pré-entraîné dans l'emplacement Cloud Storage située à l'adresse gs://solutions-public-assets/tftrt-tutorial/resnet/export/1584366419/.

Créer un environnement de travail

Pour votre environnement de travail, vous créez une instance Compute Engine à l'aide de Deep Learning VM Image. Vous optimisez et quantifiez le modèle ResNet-50 avec TensorRT sur cette instance.

  1. Dans la console Google Cloud, activez Cloud Shell.

    Activer Cloud Shell

  2. Déployez une instance nommée working-vm :

    gcloud config set project PROJECT_ID
    gcloud config set compute/zone us-west1-b
    gcloud compute instances create working-vm \
        --scopes cloud-platform \
        --image-family common-cu113 \
        --image-project deeplearning-platform-release \
        --machine-type n1-standard-8 \
        --min-cpu-platform="Intel Skylake" \
        --accelerator=type=nvidia-tesla-t4,count=1 \
        --boot-disk-size=200GB \
        --maintenance-policy=TERMINATE \
        --metadata="install-nvidia-driver=True"
    

    Remplacez PROJECT_ID par l'ID du projet Google Cloud que vous avez créé précédemment.

    Cette commande lance une instance Compute Engine à l'aide de NVIDIA T4. Au premier démarrage, elle installe automatiquement le pilote de GPU NVIDIA compatible avec TensorRT 5.1.5.

Créer des fichiers de modèle avec différentes optimisations

Dans cette section, vous allez appliquer les optimisations suivantes au modèle ResNet-50 d'origine à l'aide de TF-TRT :

  • Optimisation des graphes
  • Conversion en FP16 avec l'optimisation du graphique
  • Quantification avec INT8 avec l'optimisation du graphique

Pour en savoir plus sur ces optimisations, consultez la section Optimisation des performances.

  1. Dans la console Google Cloud, accédez à Compute Engine > Instances de VM.

    Accéder à la page "Instances de VM"

    L'instance working-vm que vous avez créée précédemment s'affiche.

  2. Pour ouvrir la console (terminal) de l'instance, cliquez sur SSH.

    Utilisez ce terminal pour exécuter les autres commandes de ce document.

  3. Dans le terminal, clonez le dépôt requis et modifiez le répertoire actuel :

    cd $HOME
    git clone https://github.com/GoogleCloudPlatform/gke-tensorflow-inference-system-tutorial
    cd gke-tensorflow-inference-system-tutorial/server
    
  4. Téléchargez le modèle ResNet-50 pré-entraîné dans un répertoire local :

    mkdir -p models/resnet/original/00001
    gsutil cp -R gs://solutions-public-assets/tftrt-tutorial/resnet/export/1584366419/* models/resnet/original/00001
    
  5. Créez une image de conteneur contenant des outils d'optimisation pour TF-TRT :

    docker build ./ -t trt-optimizer
    docker image list
    

    La dernière commande affiche une table des dépôts.

  6. Dans la table, dans la ligne du dépôt tft-optimizer, copiez l'ID de l'image.

  7. Appliquez les optimisations (optimisation du graphique, conversion en FP16 et quantification avec INT8) au modèle d'origine :

    export IMAGE_ID=IMAGE_ID
    
    nvidia-docker run --rm \
        -v `pwd`/models/:/workspace/models ${IMAGE_ID} \
        --input-model-dir='models/resnet/original/00001' \
        --output-dir='models/resnet' \
        --precision-mode='FP32' \
        --batch-size=64
    
    nvidia-docker run --rm \
        -v `pwd`/models/:/workspace/models ${IMAGE_ID} \
        --input-model-dir='models/resnet/original/00001' \
        --output-dir='models/resnet' \
        --precision-mode='FP16' \
        --batch-size=64
    
    nvidia-docker run --rm \
        -v `pwd`/models/:/workspace/models ${IMAGE_ID} \
        --input-model-dir='models/resnet/original/00001' \
        --output-dir='models/resnet' \
        --precision-mode='INT8' \
        --batch-size=64 \
        --calib-image-dir='gs://cloud-tpu-test-datasets/fake_imagenet/' \
        --calibration-epochs=10
    

    Remplacez IMAGE_ID par l'ID d'image de tft-optimizer que vous avez copié à l'étape précédente.

    L'option --calib-image-dir spécifie l'emplacement des données d'entraînement utilisées pour le modèle pré-entraîné. Les mêmes données d'entraînement sont utilisées en vue d'un calibrage pour la quantification INT8. Le processus de calibrage peut prendre environ cinq minutes.

    Une fois l'exécution des commandes terminée, la dernière ligne de sortie ressemble à ce qui suit, où les modèles optimisés sont enregistrés dans ./models/resnet :

    INFO:tensorflow:SavedModel written to: models/resnet/INT8/00001/saved_model.pb
    

    La structure du répertoire est semblable à celle-ci :

    models
    └── resnet
        ├── FP16
        │   └── 00001
        │       ├── saved_model.pb
        │       └── variables
        ├── FP32
        │   └── 00001
        │       ├── saved_model.pb
        │       └── variables
        ├── INT8
        │   └── 00001
        │       ├── saved_model.pb
        │       └── variables
        └── original
            └── 00001
                ├── saved_model.pb
                └── variables
                    ├── variables.data-00000-of-00001
                    └── variables.index
    

Le tableau suivant récapitule la relation entre les répertoires et les optimisations.

Annuaire Optimisation
FP16 Conversion en FP16 en plus de l'optimisation du graphique
FP32 Optimisation des graphes
INT8 Quantification avec INT8 en plus de l'optimisation du graphique
original Modèle d'origine (sans optimisation avec TF-TRT)

Déployer un serveur d'inférence

Dans cette section, vous allez déployer des serveurs Triton avec cinq modèles. Commencez par importer le binaire du modèle que vous avez créé à la section précédente dans Cloud Storage. Créez ensuite un cluster GKE et déployez des serveurs Triton sur celui-ci.

Importer le binaire du modèle

  • Dans le terminal SSH, importez les binaires du modèle et les fichiers de configuration config.pbtxt dans un bucket de stockage :

    export PROJECT_ID=PROJECT_ID
    export BUCKET_NAME=${PROJECT_ID}-models
    
    mkdir -p original/1/model/
    cp -r models/resnet/original/00001/* original/1/model/
    cp original/config.pbtxt original/1/model/
    cp original/imagenet1k_labels.txt original/1/model/
    
    mkdir -p tftrt_fp32/1/model/
    cp -r models/resnet/FP32/00001/* tftrt_fp32/1/model/
    cp tftrt_fp32/config.pbtxt tftrt_fp32/1/model/
    cp tftrt_fp32/imagenet1k_labels.txt tftrt_fp32/1/model/
    
    mkdir -p tftrt_fp16/1/model/
    cp -r models/resnet/FP16/00001/* tftrt_fp16/1/model/
    cp tftrt_fp16/config.pbtxt tftrt_fp16/1/model/
    cp tftrt_fp16/imagenet1k_labels.txt tftrt_fp16/1/model/
    
    mkdir -p tftrt_int8/1/model/
    cp -r models/resnet/INT8/00001/* tftrt_int8/1/model/
    cp tftrt_int8/config.pbtxt tftrt_int8/1/model/
    cp tftrt_int8/imagenet1k_labels.txt tftrt_int8/1/model/
    
    mkdir -p tftrt_int8_bs16_count4/1/model/
    cp -r models/resnet/INT8/00001/* tftrt_int8_bs16_count4/1/model/
    cp tftrt_int8_bs16_count4/config.pbtxt tftrt_int8_bs16_count4/1/model/
    cp tftrt_int8_bs16_count4/imagenet1k_labels.txt tftrt_int8_bs16_count4/1/model/
    
    gsutil mb gs://${BUCKET_NAME}
    gsutil -m cp -R original tftrt_fp32 tftrt_fp16 tftrt_int8 tftrt_int8_bs16_count4 \
        gs://${BUCKET_NAME}/resnet/
    

    Remplacez PROJECT_ID par l'ID du projet Google Cloud que vous avez créé précédemment.

    Les paramètres de réglage suivants sont spécifiés dans les fichiers config.pbtxt :

    • Nom du modèle
    • Nom du Tensor d'entrée et nom du Tensor de sortie
    • Allocation de GPU à chaque modèle
    • Taille de lot et nombre de groupes d'instances

    Par exemple, le fichier original/1/model/config.pbtxt contient les éléments suivants :

    name: "original"
    platform: "tensorflow_savedmodel"
    max_batch_size: 64
    input {
        name: "input"
        data_type: TYPE_FP32
        format: FORMAT_NHWC
        dims: [ 224, 224, 3 ]
    }
    output {
        name: "probabilities"
        data_type: TYPE_FP32
        dims: 1000
        label_filename: "imagenet1k_labels.txt"
    }
    default_model_filename: "model"
    instance_group [
      {
        count: 1
        kind: KIND_GPU
      }
    ]
    dynamic_batching {
      preferred_batch_size: [ 64 ]
      max_queue_delay_microseconds: 20000
    }
    

Pour en savoir plus sur la taille de lot et le nombre de groupes d'instances, consultez la section Optimisation des performances.

Le tableau suivant récapitule les cinq modèles que vous avez déployés dans cette section.

Nom du modèle Optimisation
original Modèle d'origine (sans optimisation avec TF-TRT)
tftrt_fp32 Optimisation du graphique
(taille du lot=64, groupes d'instances=1)
tftrt_fp16 Conversion en FP16 en plus de l'optimisation du graphique
(taille du lot=64, groupes d'instances=1)
tftrt_int8 Quantification avec INT8 en plus de l'optimisation du graphique
(taille du lot=64, groupes d'instances=1)
tftrt_int8_bs16_count4 Quantification avec INT8 en plus de l'optimisation du graphique
(taille du lot=16, groupes d'instances=4)

Déployer des serveurs d'inférence à l'aide de Triton

  1. Dans le terminal SSH, installez et configurez le package d'authentification, qui gère les clusters GKE :

    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin
    
  2. Créez un cluster GKE et un pool de nœuds GPU avec des nœuds de calcul utilisant un GPU NVIDIA T4 :

    gcloud auth login
    gcloud config set compute/zone us-west1-b
    gcloud container clusters create tensorrt-cluster \
        --num-nodes=20
    gcloud container node-pools create t4-gpu-pool \
        --num-nodes=1 \
        --machine-type=n1-standard-8 \
        --cluster=tensorrt-cluster \
        --accelerator type=nvidia-tesla-t4,count=1
    

    L'option --num-nodes spécifie 20 instances pour le cluster GKE et une instance pour le pool de nœuds GPU t4-gpu-pool.

    Le pool de nœuds GPU est composé d'une seule instance n1-standard-8 avec un GPU NVIDIA T4. Le nombre d'instances de GPU doit être supérieur ou égal au nombre de pods de serveur d'inférence, car le GPU NVIDIA T4 ne peut pas être partagé par plusieurs pods sur la même instance.

  3. Affichez les informations sur le cluster :

    gcloud container clusters list
    

    Le résultat ressemble à ce qui suit :

    NAME              LOCATION    MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION    NUM_NODES  STATUS
    tensorrt-cluster  us-west1-b  1.14.10-gke.17  XX.XX.XX.XX    n1-standard-1  1.14.10-gke.17  21         RUNNING
    
  4. Affichez les informations relatives au pool de nœuds :

    gcloud container node-pools list --cluster tensorrt-cluster
    

    Le résultat ressemble à ce qui suit :

    NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
    default-pool  n1-standard-1  100           1.14.10-gke.17
    t4-pool       n1-standard-8  100           1.14.10-gke.17
    
  5. Activez la charge de travail daemonSet :

    gcloud container clusters get-credentials tensorrt-cluster
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml
    

    Cette commande charge le pilote de GPU NVIDIA sur les nœuds du pool de nœuds GPU. De plus, elle charge automatiquement le pilote lorsque vous ajoutez un nouveau nœud au pool de nœuds GPU.

  6. Déployez des serveurs d'inférence sur le cluster :

    sed -i.bak "s/YOUR-BUCKET-NAME/${PROJECT_ID}-models/" trtis_deploy.yaml
    kubectl create -f trtis_service.yaml
    kubectl create -f trtis_deploy.yaml
    
  7. Attendez quelques minutes jusqu'à ce que les services soient disponibles.

  8. Obtenez l'adresse clusterIP de Triton et stockez-la dans une variable d'environnement :

    export TRITON_IP=$(kubectl get svc inference-server \
      -o "jsonpath={.spec['clusterIP']}")
    echo ${TRITON_IP}
    

À ce stade, le serveur d'inférence diffuse quatre modèles ResNet-50 que vous avez créés dans la section Créer des fichiers de modèle avec différentes optimisations. Les clients peuvent spécifier le modèle à utiliser lors de l'envoi de requêtes d'inférence.

Déployer des serveurs de surveillance à l'aide de Prometheus et Grafana

  1. Dans le terminal SSH, déployez des serveurs Prometheus sur le cluster :

    sed -i.bak "s/CLUSTER-IP/${TRITON_IP}/" prometheus-configmap.yml
    kubectl create namespace monitoring
    kubectl apply -f prometheus-service.yml -n monitoring
    kubectl create -f clusterRole.yml
    kubectl create -f prometheus-configmap.yml -n monitoring
    kubectl create -f prometheus-deployment.yml -n monitoring
    
  2. Obtenez l'URL du point de terminaison du service Prometheus.

    ip_port=$(kubectl get svc prometheus-service \
      -o "jsonpath={.spec['clusterIP']}:{.spec['ports'][0]['port']}" -n monitoring)
    echo "http://${ip_port}"
    

    Notez l'URL du point de terminaison Prometheus, car vous l'utiliserez pour configurer Grafana ultérieurement.

  3. Déployez des serveurs Grafana sur le cluster :

    kubectl create -f grafana-service.yml -n monitoring
    kubectl create -f grafana-deployment.yml -n monitoring
    
  4. Attendez quelques minutes jusqu'à ce que tous les services soient disponibles.

  5. Obtenez l'URL du point de terminaison du service Grafana.

    ip_port=$(kubectl get svc grafana-service \
      -o "jsonpath={.status['loadBalancer']['ingress'][0]['ip']}:{.spec['ports'][0]['port']}" -n monitoring)
    echo "http://${ip_port}"
    

    Notez l'URL du point de terminaison Grafana à utiliser à l'étape suivante.

  6. Dans un navigateur Web, accédez à l'URL Grafana que vous avez notée à l'étape précédente.

  7. Connectez-vous avec l'ID utilisateur et le mot de passe par défaut (admin et admin). Lorsque vous y êtes invité, modifiez le mot de passe par défaut.

  8. Cliquez sur Ajouter votre première source de données, puis sélectionnez Prometheus dans la liste Bases de données de séries temporelles.

  9. Dans l'onglet Paramètres, dans le champ URL, saisissez l'URL du point de terminaison Prometheus que vous avez notée précédemment.

  10. Cliquez sur Enregistrer et tester, puis revenez à l'écran d'accueil.

  11. Ajoutez une métrique de surveillance pour nv_gpu_utilization :

    1. Cliquez sur Créer votre premier tableau de bord, puis sur Ajouter une visualisation.
    2. Dans la liste Source de données, sélectionnez Prometheus.
    3. Dans l'onglet Requête, dans le champ Métrique, saisissez nv_gpu_utilization.

    4. Dans le champ Titre de la section Options du panneau, saisissez GPU Utilization, puis cliquez sur Appliquer.

      La page affiche un panneau concernant l'utilisation du GPU.

  12. Ajoutez une métrique de surveillance pour nv_gpu_memory_used_bytes :

    1. Cliquez sur Ajouter, puis sélectionnez Visualisation.
    2. Dans l'onglet Requête, dans le champ Métrique, saisissez nv_gpu_memory_used_bytes.

    3. Dans le champ Titre de la section Options du panneau, saisissez GPU Memory Used, puis cliquez sur Enregistrer.

  13. Pour ajouter le tableau de bord, cliquez sur Enregistrer dans le panneau Enregistrer le tableau de bord.

    Les graphiques d'utilisation du GPU et de la mémoire GPU utilisée s'affichent.

Déployer un outil de test de charge

Dans cette section, vous allez déployer l'outil de test de charge Locust sur GKE et générer une charge de travail pour mesurer les performances des serveurs d'inférence.

  1. Dans le terminal SSH, créez une image Docker contenant des bibliothèques clientes Triton, puis importez-la dans Container Registry :

    cd ../client
    git clone https://github.com/triton-inference-server/server
    cd server
    git checkout r19.05
    sed -i.bak "s/bootstrap.pypa.io\/get-pip.py/bootstrap.pypa.io\/pip\/2.7\/get-pip.py/" Dockerfile.client
    docker build -t tritonserver_client -f Dockerfile.client .
    gcloud auth configure-docker
    docker tag tritonserver_client \
        gcr.io/${PROJECT_ID}/tritonserver_client
    docker push gcr.io/${PROJECT_ID}/tritonserver_client
    

    Le processus de compilation peut prendre environ cinq minutes. Une fois le processus terminé, une invite de commande s'affiche dans le terminal SSH.

  2. Une fois le processus de compilation terminé, créez une image Docker pour générer la charge de travail de test, puis importez-la dans Container Registry :

    cd ..
    sed -i.bak "s/YOUR-PROJECT-ID/${PROJECT_ID}/" Dockerfile
    docker build -t locust_tester -f Dockerfile .
    docker tag locust_tester gcr.io/${PROJECT_ID}/locust_tester
    docker push gcr.io/${PROJECT_ID}/locust_tester
    

    Ne modifiez pas et ne remplacez pas YOUR-PROJECT-ID dans les commandes.

    Cette image est créée à partir de l'image que vous avez créée à l'étape précédente.

  3. Déployez les fichiers Locust service_master.yaml et deployment_master.yaml :

    sed -i.bak "s/YOUR-PROJECT-ID/${PROJECT_ID}/" deployment_master.yaml
    sed -i.bak "s/CLUSTER-IP-TRTIS/${TRITON_IP}/" deployment_master.yaml
    
    kubectl create namespace locust
    kubectl create configmap locust-config --from-literal model=original --from-literal saddr=${TRITON_IP} --from-literal rps=10 -n locust
    
    kubectl apply -f service_master.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    

    La ressource configmap permet de spécifier le modèle de machine learning auquel les clients envoient des requêtes d'inférence.

  4. Attendez quelques minutes jusqu'à ce que les services soient disponibles.

  5. Obtenez l'adresse clusterIP du client locust-master et stockez cette adresse dans une variable d'environnement :

    export LOCUST_MASTER_IP=$(kubectl get svc locust-master -n locust \
        -o "jsonpath={.spec['clusterIP']}")
    echo ${LOCUST_MASTER_IP}
    
  6. Déployez le client Locust :

    sed -i.bak "s/YOUR-PROJECT-ID/${PROJECT_ID}/" deployment_slave.yaml
    sed -i.bak "s/CLUSTER-IP-LOCUST-MASTER/${LOCUST_MASTER_IP}/" deployment_slave.yaml
    kubectl apply -f deployment_slave.yaml -n locust
    

    Ces commandes déploient dix pods clients Locust que vous pouvez utiliser pour générer des charges de travail de test. Si vous ne pouvez pas générer suffisamment de requêtes avec le nombre actuel de clients, vous pouvez modifier le nombre de pods à l'aide de la commande suivante :

    kubectl scale deployment/locust-slave --replicas=20 -n locust
    

    Lorsque la capacité d'un cluster par défaut est insuffisante pour augmenter le nombre d'instances dupliquées, nous vous recommandons d'augmenter le nombre de nœuds dans le cluster GKE.

  7. Copiez l'URL de la console Locust, puis ouvrez-la dans un navigateur Web :

    export LOCUST_IP=$(kubectl get svc locust-master -n locust \
         -o "jsonpath={.status.loadBalancer.ingress[0].ip}")
    echo "http://${LOCUST_IP}:8089"
    

    La console Locust s'ouvre et vous pouvez générer des charges de travail de test depuis la console.

Vérifier les pods en cours d'exécution

Pour vous assurer que les composants sont déployés correctement, vérifiez que les pods sont en cours d'exécution.

  1. Dans le terminal SSH, vérifiez le pod du serveur d'inférence :

    kubectl get pods
    

    Le résultat ressemble à ce qui suit :

    NAME                                READY   STATUS    RESTARTS   AGE
    inference-server-67786cddb4-qrw6r   1/1     Running   0          83m
    

    Si vous n'obtenez pas le résultat attendu, assurez-vous d'avoir suivi la procédure décrite dans la section Déployer des serveurs d'inférence à l'aide de Triton.

  2. Vérifiez les pods Locust :

    kubectl get pods -n locust
    

    Le résultat ressemble à ce qui suit :

    NAME                                READY   STATUS    RESTARTS   AGE
    locust-master-75f6f6d4bc-ttllr      1/1     Running   0          10m
    locust-slave-76ddb664d9-8275p       1/1     Running   0          2m36s
    locust-slave-76ddb664d9-f45ww       1/1     Running   0          2m36s
    locust-slave-76ddb664d9-q95z9       1/1     Running   0          2m36s
    

    Si vous n'obtenez pas le résultat attendu, assurez-vous d'avoir suivi la procédure décrite dans la section Déployer un outil de test de charge.

  3. Vérifiez les pods de surveillance :

    kubectl get pods -n monitoring
    

    Le résultat ressemble à ce qui suit :

    NAME                                     READY   STATUS    RESTARTS   AGE
    grafana-deployment-644bbcb84-k6t7v       1/1     Running   0          79m
    prometheus-deployment-544b9b9f98-hl7q8   1/1     Running   0          81m
    

    Si vous n'obtenez pas le résultat attendu, assurez-vous d'avoir suivi la procédure décrite dans la section Déployer des serveurs de surveillance avec Prometheus et Grafana.

Dans la partie suivante de cette série, vous utiliserez ce système de serveurs d'inférence pour découvrir comment différentes optimisations améliorent les performances et comment les interpréter. Pour les étapes suivantes, consultez la section Mesurer et régler les performances d'un système d'inférence TensorFlow.

Étapes suivantes