Best practice: job Cloud Run con GPU

Questa pagina fornisce le best practice per ottimizzare le prestazioni quando utilizzi un job Cloud Run con GPU per i workload AI, ad esempio l'addestramento di modelli linguistici di grandi dimensioni (LLM) utilizzando i framework che preferisci, il perfezionamento e l'esecuzione dell'inferenza batch o offline sugli LLM. Per creare un job Cloud Run in grado di eseguire attività con uso intensivo di calcolo o elaborazione batch in tempo reale, devi:
  • Utilizzare modelli che si caricano rapidamente e richiedono una trasformazione minima in strutture pronte per la GPU e ottimizzare la modalità di caricamento.
  • Utilizzare configurazioni che consentano l'esecuzione simultanea massima ed efficiente per ridurre il numero di GPU necessarie per gestire una richiesta di destinazione al secondo, mantenendo bassi i costi.

Modalità consigliate per caricare modelli ML di grandi dimensioni su Cloud Run

Google consiglia di scaricare i modelli ML da Cloud Storage e di accedervi tramite Google Cloud CLI. In alternativa, puoi archiviare i modelli all'interno delle immagini container, ma questo metodo è più adatto ai modelli più piccoli, inferiori a 10 GB.

Compromessi per l'archiviazione e il caricamento dei modelli ML

Ecco un confronto tra le opzioni:

Posizione modello Tempo di deployment Esperienza di sviluppo Tempo di avvio del container Costo di archiviazione
Cloud Storage, scaricato contemporaneamente utilizzando il comando Google Cloud CLI gcloud storage cp o l'API Storage di Cloud Storage, come mostrato nell'esempio di codice per il download simultaneo del transfer manager. Il più veloce. Modello scaricato durante l'avvio del container. Assicurati che all'istanza Cloud Run sia allocata RAM sufficiente per archiviare i file del modello. Leggermente più difficile da configurare, perché dovrai installare Google Cloud CLI sull'immagine o aggiornare il codice per utilizzare l' API Cloud Storage. Per ulteriori informazioni su come recuperare le credenziali dal server di metadati, consulta la sezione Introduzione all'identità del servizio. 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.
Cloud Storage, caricato utilizzando il montaggio del volume Cloud Storage FUSE Più veloce. Modello scaricato durante l'avvio del container. Non è difficile da configurare, non richiede modifiche all'immagine Docker. Veloce quando utilizzi le ottimizzazioni di rete. Non parallelizza il download. Una copia in Cloud Storage.
Immagine container Veloce. L'importazione di un'immagine contenente un modello di grandi dimensioni in Cloud Run richiederà più tempo. Dovrai creare una nuova immagine ogni volta che vuoi utilizzare un modello diverso. 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 i modelli di dimensioni molto grandi, utilizza Cloud Storage per prestazioni più prevedibili, ma più lente. Potenzialmente più copie in Artifact Registry.
Internet Lento. Modello scaricato durante l'avvio del container. In genere più semplice (molti framework scaricano i modelli da repository centrali). In genere scadente e imprevedibile:
  • I framework possono applicare trasformazioni del modello durante l'inizializzazione. (Dovresti farlo in fase di compilazione).
  • L'host del modello e le librerie per il download del modello potrebbero non essere efficienti.
  • Esiste un rischio di affidabilità associato al download da internet. Il job potrebbe non avviarsi se la destinazione di download non è disponibile e il modello sottostante scaricato potrebbe cambiare, il che riduce la qualità. Ti consigliamo di eseguire l'hosting nel tuo bucket Cloud Storage.
Dipende dal provider host del modello.

Archiviare i modelli in Cloud Storage

Per ottimizzare il caricamento dei modelli ML quando li carichi da Cloud Storage, utilizzando i montaggi dei volumi Cloud Storage o direttamente l'API Storage 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.

A un costo aggiuntivo, l'utilizzo di Rapid Cache può ridurre la latenza di caricamento dei modelli memorizzando in modo efficiente i dati sugli SSD per letture più veloci.

Per ridurre i tempi di lettura dei modelli, prova le seguenti opzioni di montaggio per abilitare le funzionalità di Cloud Storage FUSE:

  • cache-dir: abilita la funzionalità di memorizzazione nella cache dei file con un montaggio del volume in memoria da utilizzare come directory sottostante per rendere persistenti i file. Imposta il valore dell'opzione di montaggio cache-dir sul nome del volume in memoria nel formato cr-volume:{volume name}. Ad esempio, se hai un volume in memoria denominato in-memory-1 che vuoi utilizzare come directory della cache, specifica cr-volume:in-memory-1. Quando questo valore è impostato, puoi anche impostare altri file-cache flag disponibili per la configurazione della cache.
  • enable-buffered-read: imposta il campo enable-buffered-read su true per il prefetching asincrono di parti di un oggetto Cloud Storage in un buffer in memoria. In questo modo, le letture successive vengono gestite dal buffer anziché richiedere chiamate di rete. Quando configuri questo campo, puoi anche impostare il read-global-max-blocks campo per configurare il numero massimo di blocchi disponibili per le letture con buffer in tutti gli handle dei file.

Quando vengono utilizzati sia cache-dir sia enable-buffered-read, cache-dir ha la precedenza. Tieni presente che l'abilitazione di una di queste funzionalità modificherà la contabilità delle risorse del processo Cloud Storage FUSE, che verrà conteggiata in base ai limiti di memoria dei container. Valuta la possibilità di aumentare il limite di memoria dei container seguendo le istruzioni su come configurare i limiti di memoria.

Archiviare i modelli nelle immagini container

Se archivi 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 della rete. Quando utilizzi Cloud Build, ti consigliamo di utilizzare una macchina di build più potente con prestazioni di calcolo e di rete maggiori. 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 costo perché potrebbe esserci una copia del modello per immagine se il livello del modello è univoco in ogni immagine.

Caricare i modelli da internet

Per ottimizzare il caricamento dei modelli ML da internet, instrada tutto il traffico attraverso 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.

In fase di compilazione

L'elenco seguente mostra le considerazioni da tenere presenti quando pianifichi la build:

  • Scegli una buona immagine di base. Dovresti iniziare con un'immagine da Deep Learning Containers o dal registro 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 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 di 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 di destinazione e richiedono meno trasformazioni quando vengono caricati sulla GPU. Per motivi di sicurezza, non utilizzare checkpoint in formato pickle.
  • Crea e riscalda le cache LLM in fase di compilazione. Avvia l'LLM sulla macchina di build durante la creazione dell'immagine Docker. Abilita la memorizzazione nella cache dei prompt e fornisci prompt comuni o di esempio per riscaldare la cache per l'utilizzo nel mondo reale. Salva gli output generati per caricarli in fase di runtime.
  • Salva il modello di inferenza che generi durante il tempo di compilazione. In questo modo si risparmia molto tempo 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

L'elenco seguente mostra le considerazioni da tenere presenti quando pianifichi il deployment:

  • Imposta un timeout dell'attività di un'ora o inferiore per le esecuzioni dei job.
  • Se esegui attività parallele nell'esecuzione di un job, determina e imposta il parallelismo su un valore inferiore alla quota di GPU senza ridondanza a livello di zona allocata per il tuo progetto. Per richiedere un aumento della quota, consulta la sezione Come aumentare la quota. Le attività GPU vengono avviate il più rapidamente possibile e raggiungono un massimo che varia a seconda della quota di GPU allocata per il progetto e della regione selezionata. I deployment non riescono se imposti il parallelismo su un valore superiore al limite della quota di GPU.

In fase di runtime

  • Gestisci attivamente la finestra contestuale supportata. Più piccola è la finestra contestuale supportata, più query puoi supportare in esecuzione in parallelo. I dettagli su come farlo dipendono dal framework.
  • Utilizza le cache LLM generate in fase di compilazione. Fornisci gli stessi flag utilizzati in tempo di compilazione quando hai generato la cache di prompt e prefisso.
  • Carica dal modello salvato che hai appena scritto. Per un confronto su come caricare il modello, consulta la sezione Compromessi per l'archiviazione e il caricamento dei modelli.
  • Valuta la possibilità di utilizzare una cache coppia chiave-valore quantizzata se il tuo framework la supporta. In questo modo è possibile ridurre i requisiti di memoria per query e configurare un parallelismo maggiore. Tuttavia, può anche influire sulla qualità.
  • Ottimizza la quantità di memoria GPU da riservare per i pesi dei modelli, le attivazioni e le cache coppia chiave-valore. Impostala il più alta possibile senza ricevere un errore di memoria insufficiente.
  • Verifica se il tuo framework ha 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 dove appropriato. 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 di prompt sono utili solo se contengono i prompt in sequenza. Le cache sono effettivamente memorizzate nella cache dei prefissi. Gli inserimenti o le modifiche nella sequenza indicano che non sono memorizzati nella cache o sono presenti solo parzialmente.