Misura e ottimizza le prestazioni di un sistema di inferenza TensorFlow

Last reviewed 2023-11-02 UTC

Questo documento descrive come misurare le prestazioni di TensorFlow di inferenza che hai creato Esegui il deployment di un sistema di inferenza TensorFlow scalabile. Mostra inoltre come applicare l'ottimizzazione dei parametri per migliorare la velocità effettiva del sistema.

Il deployment si basa sull'architettura di riferimento descritta in Sistema di inferenza TensorFlow scalabile.

Questa serie è rivolta agli sviluppatori che conoscono Google Kubernetes Engine e di machine learning (ML), tra cui TensorFlow e TensorRT.

Questo documento non è allo scopo di fornire i dati sulle prestazioni di un particolare sistema. Invece, offre indicazioni generali sul processo di misurazione delle prestazioni. Le metriche sul rendimento visualizzate, ad esempio le richieste totali al secondo (RPS) e Tempi di risposta (ms), varieranno a seconda del modello addestrato, del software le versioni e le configurazioni hardware che utilizzi.

Architettura

Per una panoramica dell'architettura del sistema di inferenza TensorFlow, consulta Sistema di inferenza TensorFlow scalabile.

Obiettivi

  • Definisci l'obiettivo di rendimento e le metriche
  • Misurare il rendimento di riferimento
  • Ottimizza il grafico
  • Misura conversione FP16
  • Misura la quantizzazione di INT8
  • Modifica il numero di istanze

Costi

Per i dettagli sui costi associati al deployment, consulta Costi.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

Assicurati di aver già completato i passaggi descritti in Deployment di un sistema di inferenza TensorFlow scalabile.

In questo documento vengono utilizzati i seguenti strumenti:

Imposta la directory

  1. Nella console Google Cloud, vai a Compute Engine > Istanze VM.

    Vai a Istanze VM

    Vedrai l'istanza working-vm che hai creato.

  2. Per aprire la console del terminale dell'istanza, fai clic su SSH.

  3. Nel terminale SSH, imposta la directory corrente sulla sottodirectory client:

    cd $HOME/gke-tensorflow-inference-system-tutorial/client
    

    In questo documento vengono eseguiti tutti i comandi da questa directory.

Definisci l'obiettivo di rendimento

Quando misuri le prestazioni dei sistemi di inferenza, devi definire l'obiettivo di rendimento e le metriche di prestazioni appropriate in base all'uso caso del sistema. A scopo dimostrativo, il presente documento utilizza le seguenti informazioni: obiettivi di rendimento:

  • Almeno il 95% delle richieste riceve risposte entro 100 ms.
  • La velocità effettiva totale, rappresentata dalle richieste al secondo (RPS), migliora senza interrompere il obiettivo precedente.

Utilizzando queste ipotesi, misuri e migliori la velocità effettiva del seguente ResNet-50 modelli con ottimizzazioni diverse. Quando un client invia richieste di inferenza, specifica il modello usando il nome del modello in questa tabella.

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 a 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)

Misurare il rendimento di riferimento

Inizierai utilizzando TF-TRT come riferimento per misurare le prestazioni del modello originale non ottimizzato. Confronti le prestazioni di altri modelli con dell'originale per valutare quantitativamente il miglioramento del rendimento. Quando hai eseguito il deployment di Locust, era già configurato per inviare richieste per modello originale.

  1. Apri la console Locust che hai preparato in Deployment di uno strumento di test del carico.

  2. Verifica che il numero di client (indicati come schiavi) sia 10.

    Se il numero è inferiore a 10, i clienti all'avvio. In questo caso, attendi qualche minuto finché non diventi 10.

  3. Misura il rendimento:

    1. Nel campo Numero di utenti da simulare, inserisci 3000.
    2. Nel campo Frequenza di trattenuta, inserisci 5.
    3. aumentare di 5 al secondo il numero di utilizzi simulati fino a raggiungere 3000, fai clic su Inizia lo swarming.

  4. Fai clic su Grafici.

    I grafici mostrano i risultati del rendimento. Tieni presente che, anche se il valore delle richieste totali al secondo aumenta in modo lineare, il valore Tempi di risposta (ms) aumenta di conseguenza.

    Sto avviando un nuovo sciame di locuste.

  5. Quando il 95% percentile di tempi di risposta supera 100 ms, fai clic Interrompi per arrestare la simulazione.

    Se tieni il puntatore sopra puoi controllare il numero di richieste al secondo corrispondente a quando il valore del 95% del percentile dei tempi di risposta ha superato i 100 ms.

    Ad esempio, nello screenshot seguente, il numero di richieste al secondo è 253,1.

    Grafico che mostra 253,1 richieste al secondo.

    Ti consigliamo di ripetere la misurazione più volte e calcolare una media per tenere conto delle fluttuazioni.

  6. Nel terminale SSH, riavvia Locust:

    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    
  7. Per ripetere la misurazione, ripeti questa procedura.

Ottimizza i grafici

In questa sezione misurerai le prestazioni del modello tftrt_fp32, che è ottimizzato con TF-TRT per l'ottimizzazione del grafico. Questa è un'ottimizzazione comune compatibile con la maggior parte delle schede GPU NVIDIA.

  1. Nel terminale SSH, riavvia lo strumento di test del carico:

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_fp32 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    

    La risorsa configmap specifica il modello come tftrt_fp32.

  2. Riavvia il server Triton:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Attendi qualche minuto finché i processi del server non sono pronti.

  3. Controlla lo stato del server:

    kubectl get pods
    

    L'output è simile al seguente, in cui la colonna READY mostra il valore stato del server:

    NAME                                READY   STATUS    RESTARTS   AGE
    inference-server-74b85c8c84-r5xhm   1/1     Running   0          46s
    

    Il valore 1/1 nella colonna READY indica che il server è pronto.

  4. Misura il rendimento:

    1. Nel campo Numero di utenti da simulare, inserisci 3000.
    2. Nel campo Frequenza di trattenuta, inserisci 5.
    3. aumentare di 5 al secondo il numero di utilizzi simulati fino a raggiungere 3000, fai clic su Inizia lo swarming.

    I grafici mostrano il miglioramento del rendimento del grafico TF-TRT e ottimizzazione.

    Ad esempio, il grafico potrebbe mostrare che il numero di richieste al secondo è ora 381 con un tempo di risposta mediano di 59 ms.

Converti in FP16

In questa sezione misurerai le prestazioni del modello tftrt_fp16, che è ottimizzato con TF-TRT per l'ottimizzazione del grafico e la conversione FP16. Si tratta di un per NVIDIA T4.

  1. Nel terminale SSH, riavvia lo strumento di test del carico:

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_fp16 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    
  2. Riavvia il server Triton:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Attendi qualche minuto finché i processi del server non sono pronti.

  3. Misura il rendimento:

    1. Nel campo Numero di utenti da simulare, inserisci 3000.
    2. Nel campo Frequenza di trattenuta, inserisci 5.
    3. aumentare di 5 al secondo il numero di utilizzi simulati fino a raggiungere 3000, fai clic su Inizia lo swarming.

    I grafici mostrano il miglioramento del rendimento della conversione dell'FP16 in oltre all'ottimizzazione del grafico TF-TRT.

    Ad esempio, il grafico potrebbe mostrare che il numero di richieste al secondo è 1072.5 con un tempo di risposta mediano di 63 ms.

Quantifica con INT8

In questa sezione misurerai le prestazioni del modello tftrt_int8, che è ottimizzato con TF-TRT per l'ottimizzazione del grafico e la quantizzazione INT8. Questo è disponibile per NVIDIA T4.

  1. Nel terminale SSH, riavvia lo strumento di test del carico.

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_int8 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    
  2. Riavvia il server Triton:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Attendi qualche minuto finché i processi del server non sono pronti.

  3. Misura il rendimento:

    1. Nel campo Numero di utenti da simulare, inserisci 3000.
    2. Nel campo Frequenza di trattenuta, inserisci 5.
    3. aumentare di 5 al secondo il numero di utilizzi simulati fino a raggiungere 3000, fai clic su Inizia lo swarming.

    I grafici mostrano i risultati del rendimento.

    Ad esempio, il grafico potrebbe mostrare che il numero di richieste al secondo è 1085.4 con un tempo di risposta mediano di 32 ms.

    In questo esempio, il risultato non è un aumento significativo del rendimento quando rispetto alla conversione dell'obiettivo FP16. In teoria, NVIDIA T4 La GPU è in grado di gestire i modelli di quantizzazione INT8 più velocemente dei modelli di conversione FP16. In questo caso, potrebbe esserci un collo di bottiglia diverso dalle prestazioni della GPU. Tu può confermarlo dai dati sull'utilizzo delle GPU Fitbit.com. Ad esempio, se l'utilizzo è inferiore al 40%, significa che non può utilizzare appieno le prestazioni della GPU.

    Come mostrato nella prossima sezione, per alleggerire questo collo di bottiglia aumentando il numero di gruppi di istanze. Ad esempio, aumenta il numero di gruppi di istanze da 1 a 4 e la dimensione del batch diminuirà da 64 a 16. Questo approccio mantiene il numero totale di richieste elaborate su una singola GPU a 64.

Modifica il numero di istanze

In questa sezione misurerai le prestazioni del modello tftrt_int8_bs16_count4. Questo modello ha la stessa struttura di tftrt_int8, ma modificherai la dimensione del batch e il numero di gruppi di istanze come descritto in Quantizzazione con INT8.

  1. Nel terminale SSH, riavvia Locust:

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_int8_bs16_count4 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    kubectl scale deployment/locust-slave --replicas=20 -n locust
    

    In questo comando, utilizzerai la risorsa configmap per specificare il modello come tftrt_int8_bs16_count4. Aumenti anche il numero di locuste di pod client per generare carichi di lavoro sufficienti a misurare le prestazioni limitazione del modello.

  2. Riavvia il server Triton:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Attendi qualche minuto finché i processi del server non sono pronti.

  3. Misura il rendimento:

    1. Nel campo Numero di utenti da simulare, inserisci 3000.
    2. Nel campo Frequenza di trattenuta, inserisci 15. Per questo modello potrebbe essere necessario molto tempo per raggiungere il limite di prestazioni se la Frequenza di tratteggio è impostata su 5.
    3. aumentare di 5 al secondo il numero di utilizzi simulati fino a raggiungere 3000, fai clic su Inizia lo swarming.

    I grafici mostrano i risultati del rendimento.

    Ad esempio, il grafico potrebbe mostrare che il numero di richieste al secondo è 2236.6 con un tempo di risposta mediano di 38 ms.

    Modificando il numero di istanze, puoi quasi raddoppiare le richieste al secondo. Nota che l'utilizzo delle GPU è aumentato su Grafana dashboard (ad esempio, l'utilizzo potrebbe raggiungere il 75%).

Prestazioni e più nodi

Quando esegui la scalabilità con più nodi, misuri le prestazioni di un singolo pod. Poiché i processi di inferenza vengono eseguiti in modo indipendente su pod diversi in modo condiviso, possiamo supporre che la velocità effettiva totale in modo lineare con il numero di pod. Questo presupposto si applica purché non siano presenti colli di bottiglia come la larghezza di banda della rete tra i client e i server di inferenza.

Tuttavia, è importante capire come vengono bilanciate le richieste di inferenza tra in più server di inferenza. Triton utilizza il protocollo gRPC per stabilire un TCP connessione tra un client e un server. Poiché Triton riutilizza lo standard connessione per l'invio di più richieste di inferenza, richieste da un vengono inviati sempre allo stesso server. Per distribuire richieste per più devi usare più client.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate. di questa serie, puoi eliminare il progetto.

Elimina il progetto

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Passaggi successivi