Best practice: job Cloud Run con GPU

Questa pagina fornisce le best practice per ottimizzare il rendimento quando utilizzi un job Cloud Run con GPU per carichi di lavoro di AI come l'addestramento di modelli linguistici di grandi dimensioni (LLM) utilizzando i tuoi framework preferiti, il perfezionamento e l'esecuzione di inferenza batch o offline sugli LLM. Per creare un job Cloud Run in grado di eseguire attività a elevato utilizzo di risorse di calcolo o l'elaborazione batch in tempo reale, devi:
  • Utilizza modelli che vengono caricati rapidamente e richiedono una trasformazione minima in strutture pronte per la GPU e ottimizza il modo in cui vengono caricati.
  • Utilizza configurazioni che consentano l'esecuzione simultanea massima ed efficiente per ridurre il numero di GPU necessarie per gestire una richiesta target al secondo, mantenendo i costi contenuti.

Modi consigliati per caricare modelli di ML di grandi dimensioni su Cloud Run

Google consiglia di archiviare i modelli ML all'interno delle immagini container o di ottimizzare il caricamento da Cloud Storage.

Compromessi tra archiviazione e caricamento dei modelli ML

Ecco un confronto delle opzioni:

Posizione modello Ora di pubblicazione Esperienza di sviluppo Tempo di avvio del container Costo di archiviazione
Immagine container Lenta. L'importazione in Cloud Run di un'immagine contenente un modello di grandi dimensioni richiede più tempo. Le modifiche all'immagine container richiedono un nuovo deployment, che potrebbe essere lento per le immagini di grandi dimensioni. Dipende dalle dimensioni del modello. Per modelli molto grandi, utilizza Cloud Storage per prestazioni più prevedibili ma più lente. Potenzialmente più copie in Artifact Registry.
Cloud Storage, caricato utilizzando il montaggio del volume Cloud Storage FUSE Veloce. Modello scaricato durante l'avvio del container. Non è difficile da configurare e non richiede modifiche all'immagine Docker. Veloce quando utilizzi le ottimizzazioni di rete. Non parallelizza il download. Una copia in Cloud Storage.
Cloud Storage, scaricati contemporaneamente utilizzando il comando Google Cloud CLI gcloud storage cp o l'API Cloud Storage, come mostrato nell'esempio di codice per il download simultaneo di Transfer Manager. Veloce. Modello scaricato durante l'avvio del container. Leggermente più difficile da configurare, perché dovrai installare Google Cloud CLI sull'immagine o aggiornare il codice per utilizzare l'API Cloud Storage. Veloce quando utilizzi le ottimizzazioni di rete. Google Cloud CLI scarica il file del modello in parallelo, rendendolo più veloce del montaggio FUSE. Una copia in Cloud Storage.
Internet Veloce. Modello scaricato durante l'avvio del container. In genere più semplice (molti framework scaricano i modelli da repository centrali). In genere scarsa e imprevedibile:
  • I framework possono applicare trasformazioni del modello durante l'inizializzazione. (Devi farlo in fase di compilazione).
  • L'host del modello e le librerie per il download del modello potrebbero non essere efficienti.
  • Il download da internet comporta un rischio di affidabilità. L'avvio del job potrebbe non riuscire se la destinazione di download non è disponibile e il modello sottostante scaricato potrebbe cambiare, il che riduce la qualità. Ti consigliamo l'hosting nel tuo bucket Cloud Storage.
Dipende dal provider host del modello.

Archiviare i modelli nelle immagini container

Se memorizzi il modello ML nell'immagine container, il caricamento del modello trarrà vantaggio dall'infrastruttura di streaming dei container ottimizzata di Cloud Run. Tuttavia, la creazione di immagini container che includono modelli ML è un processo che richiede molte risorse, soprattutto quando si lavora con modelli di grandi dimensioni. In particolare, il processo di compilazione può diventare un collo di bottiglia per la velocità effettiva di rete. Quando utilizzi Cloud Build, ti consigliamo di utilizzare una macchina di build più potente con prestazioni di calcolo e networking migliorate. Per farlo, crea un'immagine utilizzando un file di configurazione della build con i seguenti passaggi:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'IMAGE', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'IMAGE']
images:
- IMAGE
options:
 machineType: 'E2_HIGHCPU_32'
 diskSizeGb: '500'
 

Puoi creare una copia del modello per immagine se il livello contenente il modello è distinto tra le immagini (hash diverso). Potrebbe esserci un costo aggiuntivo di Artifact Registry perché potrebbe esserci una copia del modello per immagine se il livello del modello è univoco per ogni immagine.

Archivia i modelli in Cloud Storage

Per ottimizzare il caricamento dei modelli ML quando li carichi da Cloud Storage, utilizzando i volumi di montaggio di Cloud Storage o direttamente l'API o la riga di comando di Cloud Storage, devi utilizzare Direct VPC con il valore dell'impostazione di uscita impostato su all-traffic, insieme all'accesso privato Google.

Caricare modelli da internet

Per ottimizzare il caricamento dei modelli ML da internet, instrada tutto il traffico tramite la rete VPC con il valore dell'impostazione di uscita impostato su all-traffic e configura Cloud NAT per raggiungere la rete internet pubblica con una larghezza di banda elevata.

Considerazioni su build, deployment, runtime e progettazione del sistema

Le sezioni seguenti descrivono le considerazioni relative a build, deployment, runtime e progettazione del sistema.

Al momento della build

Il seguente elenco mostra gli aspetti da tenere in considerazione quando pianifichi la build:

  • Scegli una buona immagine di base. Devi iniziare con un'immagine di Deep Learning Containers o del registro di container NVIDIA per il framework ML che stai utilizzando. Queste immagini hanno installato i pacchetti più recenti relativi alle prestazioni. Non è consigliabile creare un'immagine personalizzata.
  • Scegli modelli quantizzati a 4 bit per massimizzare la concorrenza, a meno che tu non possa dimostrare che influiscono sulla qualità dei risultati. La quantizzazione produce modelli più piccoli e più veloci, riducendo la quantità di memoria GPU necessaria per gestire il modello e può aumentare il parallelismo in fase di runtime. Idealmente, i modelli devono essere addestrati alla profondità di bit di destinazione anziché essere quantizzati.
  • Scegli un formato del modello con tempi di caricamento rapidi per ridurre al minimo il tempo di avvio del container, ad esempio GGUF. Questi formati riflettono in modo più accurato il tipo di quantizzazione target e richiedono meno trasformazioni quando vengono caricati sulla GPU. Per motivi di sicurezza, non utilizzare checkpoint in formato pickle.
  • Crea e preriscalda le cache LLM al momento della build. Avvia l'LLM sulla macchina di build durante la creazione dell'immagine Docker. Attiva la memorizzazione nella cache dei prompt e fornisci prompt comuni o di esempio per preparare la cache all'uso reale. Salva gli output generati per caricarli in fase di runtime.
  • Salva il tuo modello di inferenza generato durante la compilazione. Ciò consente di risparmiare tempo significativo rispetto al caricamento di modelli archiviati in modo meno efficiente e all'applicazione di trasformazioni come la quantizzazione all'avvio del container.

Al momento del deployment

Il seguente elenco mostra le considerazioni da tenere presenti quando pianifichi l'implementazione:

  • Imposta un timeout dell'attività di un'ora o meno per le esecuzioni dei job.
  • Se esegui attività parallele in un'esecuzione del job, determina e imposta parallelism su un valore inferiore al valore più basso dei limiti di quota applicabili che hai allocato per il tuo progetto. Per impostazione predefinita, la quota di istanze di job GPU è impostata su 5 per le attività eseguite in parallelo. Per richiedere un aumento della quota, vedi Come aumentare la quota. I task GPU vengono avviati il più rapidamente possibile e raggiungono un massimo che varia a seconda della quota di GPU allocata per il progetto e la regione selezionati. I deployment non riescono se imposti il parallelismo su un valore superiore al limite di quota GPU.

In fase di esecuzione

  • Gestisci attivamente la lunghezza del contesto supportata. Più piccola è la finestra contestuale che supporti, più query puoi supportare in esecuzione in parallelo. I dettagli su come farlo dipendono dal framework.
  • Utilizza le cache LLM generate al momento della compilazione. Fornisci gli stessi flag che hai utilizzato durante la compilazione quando hai generato la cache di prompt e prefisso.
  • Carica dal modello salvato che hai appena scritto. Consulta Compromessi tra archiviazione e caricamento dei modelli per un confronto su come caricare il modello.
  • Se il framework lo supporta, valuta la possibilità di utilizzare una cache di coppie chiave-valore quantizzate. Ciò può ridurre i requisiti di memoria per query e consente di configurare un parallelismo maggiore. Tuttavia, può influire anche sulla qualità.
  • Regola la quantità di memoria GPU da riservare a pesi, attivazioni e cache chiave-valore del modello. Impostalo sul valore più alto possibile senza che si verifichi un errore di esaurimento della memoria.
  • Verifica se il tuo framework offre opzioni per migliorare le prestazioni di avvio del container (ad esempio, utilizzando la parallelizzazione del caricamento del modello).

A livello di progettazione del sistema

  • Aggiungi cache semantiche, se opportuno. In alcuni casi, la memorizzazione nella cache di intere query e risposte può essere un ottimo modo per limitare il costo delle query comuni.
  • Controlla la varianza nei preamboli. Le cache dei prompt sono utili solo quando contengono i prompt in sequenza. Le cache vengono memorizzate nella cache in base al prefisso. Inserimenti o modifiche nella sequenza indicano che non sono memorizzati nella cache o sono presenti solo parzialmente.