Creazione di un sistema di inferenza scalabile di TensorFlow utilizzando Triton Inference Server e Tesla T4

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Questo tutorial mostra come creare un sistema di inferenza TensorFlow scalabile che utilizzi NVIDIA Tesla T4 e Triton Inference Server (in precedenza chiamato TensorRT Inference Server o TRTIS). Per una panoramica sull'architettura del sistema e per esaminare la terminologia utilizzata per tutta la serie, consulta la parte 1 di questa serie. Per scoprire come misurare le prestazioni e ottimizzare il sistema, consulta la parte 3 di questa serie.

Obiettivi

  • Scarica un modello ResNet-50 addestrato e utilizza l'integrazione di TensorFlow con TensorRT (TF-TRT) per applicare le ottimizzazioni.
  • Crea un sistema di server di inferenza per il modello ResNet-50 utilizzando Triton.
  • Crea un sistema di monitoraggio per Triton utilizzando Prometheus e Grafana.
  • Crea uno strumento di test del carico utilizzando Locust.

Costi

Oltre a utilizzare la GPU NVIDIA T4, questo tutorial utilizza i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi.

Al termine di questo tutorial, non eliminare le risorse che hai creato. Queste risorse sono necessarie nella parte 3 di questa serie.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore dei progetti in Google Cloud Console, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.

  4. Attiva l'API GKE.

    Abilita l'API

  5. Nella pagina del selettore dei progetti in Google Cloud Console, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  6. Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.

  7. Attiva l'API GKE.

    Abilita l'API

Preparazione di un modello ResNet-50

In questo tutorial, utilizzerai un modello ResNet-50 utilizzando il sistema di inferenza. Nella sezione successiva, scarichi il modello preaddestrato. Se preferisci utilizzare questo modello preaddestrato, puoi saltare questa sezione. In caso contrario, se vuoi creare personalmente lo stesso modello, segui la procedura descritta in questa sezione.

Addestra un modello ResNet-50 ed esportalo nel formato SavedModel seguendo Addestramento ResNet su Cloud TPU e apportando le seguenti modifiche:

  1. Sostituisci la funzione di input di pubblicazione image_serving_input_fn in /usr/share/tpu/models/official/resnet/imagenet_input.py con la seguente funzione:

    def image_serving_input_fn():
      """Serving input fn for raw images."""
    
      # The shape of input tensor is changed to NWHC.
      input_tensor = tf.placeholder(
          shape=[None, 224, 224, 3],
          dtype=tf.float32,
          name='input_tensor')
    
      # this line is just for simplicity
      images = input_tensor
    
      return tf.estimator.export.TensorServingInputReceiver(
          features=images, receiver_tensors=input_tensor)
    

    Poiché Triton non è in grado di gestire il formato di stringa base64 in modo efficiente come dati di input, devi modificare il formato del tensore di input da stringa di base64 a NWHC (N, larghezza, altezza, canale). Tieni presente che la prima dimensione dell'opzione shape (6a riga nel codice) deve essere None. Se imposti questa dimensione su un numero costante, il modello non verrà quantificato correttamente con INT8 nel passaggio successivo.

  2. Segui il passaggio Esegui il modello ResNet-50 confalse_imagenet invece di utilizzare il set di dati completo di NetNet perché il completamento della procedura richiede alcuni giorni se utilizzi il set di dati completo. Il modello addestrato utilizzando l'immagine falsa è sufficiente ai fini di questo tutorial.

  3. Modifica il numero di passaggi di addestramento e il numero di iterazioni per loop nel file di configurazione per ridurre il tempo di addestramento. Ad esempio, potresti cambiare /usr/share/tpu/models/official/resnet/configs/cloud/v2-8.yaml nel seguente modo:

    train_steps: 100
    train_batch_size: 1024
    eval_batch_size: 1024
    iterations_per_loop: 100
    skip_host_call: True
    num_cores: 8
    
  4. Quando esegui lo script di addestramento, specifica il percorso di esportazione utilizzando l'opzione --export_dir. Questa opzione indica allo script di esportare il modello addestrato nel formato SavedModel:

    export PYTHONPATH="$PYTHONPATH:/usr/share/tpu/models"
    python /usr/share/tpu/models/official/resnet/resnet_main.py \
        --tpu=${TPU_NAME} \
        --mode=train \
        --data_dir=gs://cloud-tpu-test-datasets/fake_imagenet/ \
        --model_dir=${MODEL_DIR} \
        --export_dir=${MODEL_DIR}/export \
        --config_file=/usr/share/tpu/models/official/resnet/configs/cloud/v2-8.yaml
    

    In questo esempio, quando lo script di addestramento viene completato correttamente, il modello addestrato viene esportato nel formato SavedModel in ${MODEL_DIR}/export in Cloud Storage.

Nella sezione seguente, si presume che il modello sia addestrato con il set di dati falso all'indirizzo gs://cloud-tpu-test-datasets/fake_imagenet/ ed è esportato in gs://solutions-public-assets/tftrt-tutorial/resnet/export/1584366419/. Nei passaggi riportati di seguito, puoi modificare questo URI in base alla tua configurazione.

Creazione di modelli ottimizzati con TF-TRT

In questa sezione ottimizzerai e quanticherai il modello preaddestrato. Nelle sezioni seguenti, viene utilizzato l'ambiente di lavoro creato in questa sezione.

Crea un ambiente di lavoro

Puoi creare il tuo ambiente di lavoro creando un'istanza di Compute Engine utilizzando l'immagine Deep Learning VM. Ottimizza e quantifica il modello ResNet-50 con TensorRT su questa istanza.

  1. Apri Cloud Shell.

    Apri Cloud Shell

  2. Esegui il deployment di un'istanza, sostituendo PROJECT_ID con l'ID del progetto Cloud che hai creato in precedenza:

    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-cu101 \
        --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"
    

    Questo comando avvia un'istanza di Google Cloud utilizzando Tesla T4. Al primo avvio, installa automaticamente il driver GPU NVIDIA, compatibile con TensorRT 5.1.5.

Creare file modello con ottimizzazioni diverse

Puoi applicare le seguenti ottimizzazioni al modello ResNet-50 originale utilizzando TF-TRT:

  • Ottimizzazione grafico
  • Conversione a FP16 oltre all'ottimizzazione del grafico
  • Quantizzazione con INT8 oltre all'ottimizzazione del grafico

Queste ottimizzazioni sono illustrate nella sezione Ottimizzazione del rendimento, parte 1 di questa serie.

  1. In Google Cloud Console, vai a Istanze VM di Compute Engine >.

    Vai a Istanze VM

    Vedrai l'istanza che hai creato nella sezione precedente.

  2. Fai clic su SSH per aprire la console del terminale dell'istanza. Puoi utilizzare questo terminale per eseguire i comandi di questo tutorial.

  3. Nel terminale, clona il repository necessario per questo tutorial e modifica la directory corrente:

    cd $HOME
    git clone https://github.com/GoogleCloudPlatform/gke-tensorflow-inference-system-tutorial
    cd gke-tensorflow-inference-system-tutorial/server
    
  4. Scarica un modello ResNet-50 preaddestrato (o copia il modello che hai creato) in una directory locale:

    mkdir -p models/resnet/original/00001
    gsutil cp -R gs://solutions-public-assets/tftrt-tutorial/resnet/export/1584366419/* models/resnet/original/00001
    
  5. Crea un'immagine container che contiene strumenti di ottimizzazione per TF-TRT:

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

    L'ultimo comando mostra gli ID immagine. Copia l'ID immagine con il nome del repository tft-optimizer. Nel seguente esempio, l'ID immagine è 3fa16b1b864c.

    REPOSITORY                     TAG                 IMAGE ID            CREATED              SIZE
    trt-optimizer                  latest              3fa16b1b864c        About a minute ago   6.96GB
    nvcr.io/nvidia/tensorflow      19.05-py3           01c8c4b0d7ff        2 months ago         6.96GB
    
  6. Applica le ottimizzazioni al modello originale, sostituendo IMAGE-ID con l'ID immagine che hai copiato nel passaggio precedente:

    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
    

    I tre comandi precedenti corrispondono alle tre ottimizzazioni: ottimizzazione del grafico, conversione in FP16 e quantizzazione con INT8. Esiste un altro processo chiamato calibrazione per la quantificazione di INT8. Per tale processo, devi fornire i dati di addestramento specificando l'opzione --calib-image-dir negli ultimi tre comandi. Utilizziamo i dati di addestramento che hai utilizzato per addestrare il modello originale. Il processo di calibrazione richiede poco più di 5 minuti.

    Una volta completati i comandi, i programmi binari del modello ottimizzato vengono memorizzati nella directory ./models/resnet. La struttura della directory è la seguente:

    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
    

La tabella seguente riepiloga la relazione tra directory e ottimizzazioni.

Directory Ottimizzazione
original Modello originale (nessuna ottimizzazione con TF-TRT)
FP32 Ottimizzazione grafico
FP16 Conversione a FP16 oltre all'ottimizzazione del grafico
INT8 Quantizzazione con INT8 oltre all'ottimizzazione del grafico

Deployment di un server di inferenza

In questa sezione eseguirai il deployment dei server Triton con cinque modelli. Per prima cosa, carica in Cloud Storage il programma binario del modello che hai creato nella sezione precedente. Quindi crei un cluster GKE ed esegui il deployment dei server Triton nel cluster.

Carica il programma binario del modello

  1. Carica i programmi binari del modello in un bucket di archiviazione, sostituendo PROJECT_ID con l'ID del tuo progetto Google Cloud:

    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/
    

    In questo passaggio hai caricato un file di configurazione config.pbtxt oltre al programma binario del modello. Ad esempio, quanto segue mostra i contenuti di original/1/model/config.pbtxt:

    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
    }
    

Tieni presente che i seguenti parametri di correzione sono specificati in questo file. Le dimensioni in batch e il numero di gruppi di istanze sono spiegati nella sezione Ottimizzazione delle prestazioni nella parte 1 di questa serie.

  • Nome modello
  • Nome tensore di input e nome tensore di output
  • Allocazione GPU a ogni modello
  • Dimensione del batch e numero di gruppi di istanze

La tabella seguente riepiloga i cinque modelli di cui hai eseguito il deployment in questa sezione.

Nome modello Ottimizzazione
original Modello originale (nessuna ottimizzazione con TF-TRT)
tftrt_fp32 Ottimizzazione del grafico
(dimensione del batch=64, gruppi di istanze=1)
tftrt_fp16 Conversione in FP16 oltre all'ottimizzazione del grafico
(dimensione del batch=64, gruppi di istanze=1)
tftrt_int8 Quantizzazione con INT8 oltre all'ottimizzazione del grafico
(dimensione del batch=64, gruppi di istanze=1)
tftrt_int8_bs16_count4 Quantizzazione con INT8 oltre all'ottimizzazione del grafico
(dimensione del batch=16, gruppi di istanze=4)

Esegui il deployment dei server di inferenza utilizzando Triton

  1. Crea un cluster GKE utilizzando nodi di computing con NVIDIA Tesla 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-pool \
        --num-nodes=1 \
        --machine-type=n1-standard-8 \
        --cluster=tensorrt-cluster \
        --accelerator type=nvidia-tesla-t4,count=1
    

    Questi comandi creano un cluster GKE con 20 nodi e aggiungono un pool di nodi GPU gpu-pool. Il pool di nodi GPU è costituito da una singola istanza n1-standard-8 con GPU NVIDIA Tesla T4. Il numero di istanze GPU deve essere uguale o superiore al numero di pod server di inferenza perché la GPU NVIDIA Tesla T4 non può essere condivisa da più pod sulla stessa istanza. L'opzione --num-nodes nel comando precedente specifica il numero di istanze.

  2. Mostra le informazioni del cluster:

    gcloud container clusters list
    

    L'output è simile al seguente:

    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
    
  3. Mostra le informazioni sul pool di nodi:

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

    L'output è simile al seguente:

    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
    
  4. Abilita il carico di lavoro daemonSet:

    sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin
    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    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
    

    Questo comando carica il driver GPU NVIDIA sui nodi nel pool di nodi GPU. Inoltre, carica automaticamente il driver quando aggiungi un nuovo nodo al pool di nodi GPU.

  5. Esegui il deployment dei server di inferenza sul 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
    
  6. Attendi qualche minuto finché i servizi non saranno disponibili.

  7. Ottieni l'indirizzo clusterIP di Triton e archivialo nella variabile di ambiente che utilizzi nei passaggi seguenti:

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

A questo punto, il server di inferenza pubblica quattro modelli ResNet-50 che hai creato nella sezione Creare file di modelli con ottimizzazioni diverse. I client possono specificare il modello da utilizzare durante l'invio di richieste di inferenza.

Esegui il deployment dei server di monitoraggio con Prometheus e Grafana

  1. Esegui il deployment dei server Prometheus nel 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. Recupera l'URL dell'endpoint del servizio Prometheus. Copia l'endpoint perché lo utilizzi per configurare Grafana nei passaggi seguenti.

    ip_port=$(kubectl get svc prometheus-service \
      -o "jsonpath={.spec['clusterIP']}:{.spec['ports'][0]['port']}" -n monitoring)
    echo "http://${ip_port}"
    
  3. Esegui il deployment dei server Grafana sul cluster:

    kubectl create -f grafana-service.yml -n monitoring
    kubectl create -f grafana-deployment.yml -n monitoring
    
  4. Attendi qualche minuto finché non saranno disponibili tutti i servizi.

  5. Recupera l'URL dell'endpoint del servizio 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}"
    
  6. Apri questo URL da un browser web e accedi con l'ID utente e la password predefiniti (admin e admin). Ti verrà chiesto di modificare la password predefinita.

  7. Fai clic sull'icona Aggiungi la tua prima origine dati e seleziona Prometheus dall'elenco Database delle serie temporali.

  8. Nella scheda Impostazioni, nel campo URL, imposta l'URL dell'endpoint del servizio Prometheus. L'URL endpoint è quello che hai annotato nel passaggio 2.

    URL dell'endpoint del servizio Prometheus.

  9. Fai clic su Salva e prova, quindi sull'icona Grafana per tornare alla schermata Home.

  10. Fai clic sull'icona Crea la tua prima dashboard, quindi su Aggiungi nuovo pannello per aggiungere una metrica di monitoraggio.

  11. Nella scheda Query, in Metrica, inserisci nv_gpu_utilization.

    Imposta una metrica per monitorare l'utilizzo della GPU.

  12. In Opzioni del pannello, per Titolo, inserisci GPU Utilization. Quindi, fai clic sulla freccia sinistra.

    Imposta il titolo del pannello per l'utilizzo della GPU.

    Viene visualizzato il grafico per l'utilizzo della GPU.

    Grafico per l'utilizzo della GPU.

  13. Fai clic sull'icona Aggiungi pannello, fai clic su Aggiungi nuovo pannello e ripeti i passaggi del passaggio 11 per aggiungere un grafico per la metrica nv_gpu_memory_used_bytes con il titolo GPU Memory Used.

Deployment di uno strumento di test del carico

In questa sezione eseguirai il deployment dello strumento di test del carico Locust su GKE e generi carichi di lavoro per misurare le prestazioni dei server di inferenza.

  1. Crea un'immagine Docker contenente librerie client Triton, quindi caricala su 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
    

    Il processo di compilazione richiede poco più di 5 minuti.

  2. Crea un'immagine Docker per generare un carico di lavoro di test e caricala in 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
    

    Questa immagine viene creata dall'immagine che hai creato nel passaggio precedente.

  3. Esegui il deployment dei file Locust service_master.yaml e 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 risorsa configmap viene utilizzata per specificare il modello di machine learning a cui i client inviano le richieste per l'inferenza.

  4. Attendi qualche minuto finché i servizi non saranno disponibili.

  5. Recupera l'indirizzo clusterIP di locust-master e archivialo in una variabile di ambiente:

    export LOCUST_MASTER_IP=$(kubectl get svc locust-master -n locust \
        -o "jsonpath={.spec['clusterIP']}")
    echo ${LOCUST_MASTER_IP}
    
  6. Esegui il deployment del 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
    

    Questi comandi eseguono il deployment di 10 pod client Locust che puoi utilizzare per generare carichi di lavoro di test. Se non riesci a generare un numero sufficiente di richieste con il numero corrente di client, puoi modificare il numero di pod utilizzando il seguente comando:

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

    Quando la capacità di un cluster predefinito non è sufficiente per aumentare il numero di repliche, ti consigliamo di aumentare il numero di nodi nel cluster GKE.

  7. Copia l'URL della console di Locust, quindi apri questo URL in un browser web:

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

    Viene visualizzata la console riportata di seguito. Da questa console puoi generare carichi di lavoro di test.

    Console Locust utilizzata per generare carichi di lavoro di test.

Hai completato la creazione del sistema di inferenza del server. Puoi controllare i pod in esecuzione:

  1. Controlla il pod del server di inferenza:

    kubectl get pods
    

    L'output è simile al seguente:

    NAME                                READY   STATUS    RESTARTS   AGE
    inference-server-67786cddb4-qrw6r   1/1     Running   0          83m
    
  2. Controlla i pod Locust:

    kubectl get pods -n locust
    

    L'output è simile al seguente:

    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
    
  3. Controlla i pod di monitoraggio:

    kubectl get pods -n monitoring
    

    L'output è simile al seguente:

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

Nella parte successiva di questa serie utilizzerai questo sistema server di inferenza per scoprire in che modo le varie ottimizzazioni migliorano le prestazioni e come interpretare tali ottimizzazioni.

Passaggi successivi