Contribuisci a migliorare questa pagina
Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Per contribuire a questa guida per l'utente, scegli il GitHub link Modifica questa pagina su che si trova nel riquadro destro di ogni pagina.
Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Accelera il caricamento dei modelli su Amazon EKS
Quando distribuisci modelli linguistici di grandi dimensioni (LLM) su Amazon EKS, il tempo di caricamento dei modelli influisce direttamente sulla rapidità con cui i Pods possono iniziare a fornire richieste di inferenza. Ciò è particolarmente vero durante gli eventi di scalabilità, quando nuovi pod o nodi devono caricare il modello prima di gestire il traffico. L'avvio del modello prevede due fasi che puoi migliorare con l'ottimizzazione e la memorizzazione nella cache degli artefatti:
-
Caricamento dei pesi: streaming dei file di peso del modello da Amazon S3 nella memoria della GPU utilizzando Model Streamer. Run:ai
-
torch.compile — Compilazione del grafico di calcolo del modello in kernel fused ottimizzati. CUDA/Triton Questa compilazione viene eseguita al primo avvio e può influire in modo significativo sull'ora di avvio a seconda delle dimensioni del modello.
Questo argomento mostra come ottimizzare le prestazioni di Run:ai Model Streamer e il caching di torch.compile per ridurre entrambe le fasi del processo di caricamento del modello. Per la procedura completa di distribuzione di vLLM su Amazon EKS per l'inferenza, consulta. Modelli Load & Serve su Amazon EKS
Ottimizza il percorso di rete S3 in EKS Auto Mode
Se utilizzi la modalità EKS Auto con nodi GPU in sottoreti private, ti consigliamo di utilizzare un endpoint Gateway VPC per S3 per ottimizzare il percorso di rete tra i tuoi nodi e S3. Con l'endpoint Gateway VPC, il traffico verso S3 rimane sulla AWS rete e bypassa completamente il NAT Gateway, quindi non vi è alcun limite di larghezza di banda condiviso e nessun costo di elaborazione dei dati NAT per GB. Senza l'endpoint Gateway VPC, quando il traffico attraversa un NAT Gateway, il NAT Gateway diventa un collo di bottiglia condiviso durante la scalabilità, quando più nodi eseguono il modello contemporaneamente.
La modalità automatica EKS colloca comunemente i nodi in sottoreti private, quindi il traffico verso S3 fluisce attraverso un gateway NAT per impostazione predefinita. Un gateway NAT fornisce fino a 100 Gbps di larghezza di banda e 55.000 connessioni simultanee per destinazione. Tuttavia, tale larghezza di banda è condivisa tra tutti i nodi della sottorete privata. Durante un evento di scalabilità, diversi nodi che scaricano contemporaneamente il modello completo si contendono la stessa larghezza di banda del NAT Gateway, il che può rallentare il caricamento dei pesi del modello su tutti.
Run:ai Ottimizzazione delle prestazioni di Model Streamer
I motori di inferenza come vLLM e SGlang utilizzano Run:ai Model Streamer come meccanismo alternativo per caricare i pesi durante l'avvio dell'inferenza.
Per impostazione predefinita, Run:ai Model Streamer utilizza impostazioni di concorrenza conservative quando scarica i file di peso del modello da S3. L'aumento della concorrenza di download e della dimensione dei blocchi riduce il tempo di caricamento dei pesi del modello scaricando più dati in parallelo.
Calcola la concorrenza ottimale
Calcola il valore di concorrenza ottimale nel modo seguente:
concurrency = ceil(total_model_size_gb / chunk_size_gb)
Sostituisci il concurrency valore che usi in base alle dimensioni del modello e alla dimensione del blocco. Per alcuni esempi, consultate la tabella seguente. Ad esempio, con un modello da 67 GB e una dimensione del blocco da 4 GB:ceil(67 / 4) = 17.
| Dimensione del modello | Dimensione del blocco | Concurrency (Simultaneità) |
|---|---|---|
|
10 GB |
4 GB |
3 |
|
67 GB |
4 GB |
17 |
|
140 GB |
4 GB |
35 |
Applica la configurazione
Aggiungi i seguenti argomenti e variabili di ambiente alle specifiche del contenitore di inferenza:
-
--tensor-parallel-size— Il grado tensoriale parallelo (TP) è in genere il numero minimo di GPU richiesto per adattare il modello alla memoria della GPU in base alle dimensioni del modello. Ad esempio, un modello da 67 GB su un tipo dip5.48xlargeistanza richiede almeno 2 GPU, quindi impostalo su.2 -
concurrencyanddistributed(in--model-loader-extra-config): impostatoconcurrencysul valore calcolato per il modello. Impostatodistributedsutruesolo quando si utilizza il parallelismo tensoriale (TP > 1). Se abilitato, ogni rango tensore-parallelo trasmette il proprio frammento di peso direttamente da Amazon S3, invece di caricare tutti i pesi al rango 0 e trasmetterlo agli altri ranghi. Ciò migliora notevolmente le prestazioni di caricamento per le distribuzioni con più GPU. Lascialo deimpostato (ofalse) per TP=1, dove non fornisce alcun vantaggio. Questa opzione richiede l'architettura vLLM V1. È incompatibile con--enforce-eager, che impone il percorso V0; utilizzandoli entrambi insieme si genererà un errore o si tornerà automaticamente al caricamento non distribuito. -
RUNAI_STREAMER_CHUNK_BYTESIZE— Dimensione del blocco da 4 GB. Questo valore mostra costantemente le migliori prestazioni tra i benchmark. Blocchi più grandi riducono il numero di richieste S3 e migliorano il throughput su istanze con larghezza di banda elevata. -
RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS— Per-request timeout in millisecondi. Consente un nuovo tentativo più rapido sulle risposte S3 lente. -
RUNAI_STREAMER_S3_LOW_SPEED_LIMIT— Velocità minima di trasferimento in byte al secondo prima che una richiesta venga considerata lenta e ritentata.
containers: - name: vllm-inference image: vllm/vllm-openai:v0.21.0 command: - python3 - -m - vllm.entrypoints.openai.api_server args: # ... your existing args ... - --model=s3://<MODEL_PATH> - --tensor-parallel-size=2- --load-format=runai_streamer - --model-loader-extra-config={"concurrency":17,"distributed":true} env: - name: RUNAI_STREAMER_CHUNK_BYTESIZE value:"4294967296"- name: RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS value:"3000"- name: RUNAI_STREAMER_S3_LOW_SPEED_LIMIT value:"1048576"
Ottimizza torch.compile cold start
La torch.compile fase del processo di elaborazione delle inferenze traccia il grafico di calcolo di un modello (la sequenza di operazioni matematiche) e lo compila in kernel fused ottimizzati. CUDA/Triton Non compila i pesi del modello, ma solo le operazioni che li trasformano.
I motori di inferenza utilizzano torch.compile perché fornisce automaticamente significativi miglioramenti del throughput, senza ingegneria del kernel personalizzata per architettura del modello:
-
Fusione del kernel: diverse piccole operazioni (aggiunta residua, layernorm, attivazione) vengono fuse in un unico kernel, riducendo i roundtrip della memoria della GPU.
-
Meno avvii del kernel: un trasformatore passa da circa 15-30 kernel CUDA separati a circa 10 kernel fusi, risparmiando il sovraccarico della CPU per avvio.
-
Python rimosso dall'hot path: l'intero forward pass diventa un piano di esecuzione C++, eliminando il sovraccarico dell'interprete Python tra le operazioni.
-
Migliore compatibilità con CUDA Graph: i grafici statici compilati vengono acquisiti e riprodotti con un sovraccarico della CPU quasi nullo.
-
Ottimizzazione automatica: funziona per qualsiasi architettura di modello. La produttività migliora del 5-30% rispetto alla modalità eager.
La tabella seguente mostra i motori di inferenza più comuni che utilizzano torch.compile.
Il problema dell'avvio a freddo di torch.compile
Il compromesso di torch.compile è che la prima inferenza Pod deve essere compilata prima di poter soddisfare le richieste. Questa compilazione può richiedere fino a diversi minuti a seconda delle dimensioni del modello. Gli artefatti compilati sono piccoli (~15 MB per un modello da 60 GB) ma aumentano notevolmente il tempo di avvio a freddo. Poiché gli artefatti sono piccoli e deterministici per una determinata configurazione, è possibile memorizzarli nella cache e riutilizzarli per eliminare la penalizzazione dovuta all'avvio a freddo al successivo avvio del Pod e del nodo.
Gli artefatti sono costituiti da:
-
File sorgente del kernel Triton generati
-
Binari del kernel compilati ()
.cubin -
Struttura grafica che sequenzia le chiamate al kernel
Il compromesso --enforce-eager
Per impostazione predefinita, vLLM abilita l'acquisizione di grafici CUDA. torch.compile Il --enforce-eager flag disattiva entrambi ed esegue il modello in modalità eager, in cui ogni operazione viene eseguita immediatamente tramite l'interprete Python. Poiché la modalità eager salta sia la compilazione che l'acquisizione di grafici, alcune guide rapide, inclusa la distribuzione di base in, vengono utilizzate per avviare i Pod più velocemente. Modelli Load & Serve su Amazon EKS --enforce-eager
--enforce-eagerè una scelta valida per il debug, le implementazioni con limiti di memoria o le architetture di modelli che non vengono compilate in modo corretto, ed è possibile utilizzarla in produzione per questi motivi. Sebbene possa mitigare i problemi legati all'avvio a torch.compile freddo, consigliamo altri approcci, come quelli descritti nelle sezioni successive di questa pagina, per mantenere le prestazioni di runtime in produzione.
Comprendi il compromesso tra tempo di avvio e prestazioni in fase di esecuzione prima dell'implementazione in produzione. --enforce-eager
| Aspetto | Con (modalità eager) --enforce-eager |
Predefinito (torch.compile + grafici CUDA) |
|---|---|---|
|
Ora di avvio |
Veloce: nessuna fase di compilazione o acquisizione di grafici |
Avvio lento a freddo (problema risolto con Memorizza gli artefatti torch.compile sullo stesso nodo ePre-warm torch.compile cache sui nuovi nodi) |
|
Steady-state produttività |
Linea di base |
~5-30% in più rispetto alla fusione del kernel |
|
Per-token latenza (piccoli lotti) |
Maggiore sovraccarico di avvio della CPU |
Molto più basso: il kernel di riproduzione dei grafici CUDA viene avviato come un'unica unità |
|
Memoria GPU |
Più basso e più prevedibile |
Più alto: l'acquisizione del grafico prealloca i pool di buffer |
|
Debuggabilità |
Pulisci le tracce dello stack per operazione |
Gli errori emergono all'interno dei kernel generati |
Memorizza gli artefatti torch.compile sullo stesso nodo
Questa tecnica si applica quando si utilizza un motore di inferenza che supportatorch.compile, ad esempio vLLM (abilitato per impostazione predefinita) o SGlang (abilitato tramite). --enable-torch-compile Funziona solo quando torch.compile è attivo, cioè quando non è impostato. --enforce-eager
Importante
Questo miglioramento non ha effetto se torch.compile è disabilitato. In vLLM, il --enforce-eager flag si disattiva torch.compile completamente, quindi nessun artefatto viene compilato o memorizzato nella cache. Se hai seguito la distribuzione di base Modelli Load & Serve su Amazon EKS con--enforce-eager, vLLM crea la directory della cache ma non vi scrive mai. Rimuovi --enforce-eager prima di applicare questa tecnica.
Quando un motore di inferenza compila il grafico di calcolo del modello al primo avvio, puoi memorizzare nella cache i kernel ottimizzati risultanti nella memoria locale del nodo. I pod successivi sullo stesso nodo riutilizzano gli artefatti memorizzati nella cache e saltano completamente la fase di compilazione, il che può ridurre significativamente i tempi di avvio.
Aggiungi variabili di ambiente alla cache
Aggiungete le seguenti variabili di ambiente alle specifiche del contenitore di inferenza per indirizzare torch.compile e Triton cache a un percorso host persistente. Ti consigliamo di utilizzare lo store di istanze NVMe locale del nodo e non il volume principale di Amazon Elastic Block Store (Amazon EBS) per. hostPath Per esempi, consulta la sezione seguente.
containers: - name: vllm-inference env: # torch.compile cache - name: XDG_CACHE_HOME value:"/compile-cache"- name: TORCHINDUCTOR_CACHE_DIR value:"/compile-cache/inductor"- name: TRITON_CACHE_DIR value:"/compile-cache/triton"volumeMounts: - name: compile-cache mountPath: /compile-cache volumes: - name: compile-cache hostPath: path:/mnt/k8s-disks/0/compile-cachetype: DirectoryOrCreate
Imposta il percorso della cache per l'archivio di istanze NVMe
Gli artefatti compilati e i pesi trasmessi in streaming traggono vantaggio dall'archiviazione locale veloce. Nelle istanze GPU con storage di istanze NVMe (come le P-family istanze G-family and), l'instant store ne fornisce circa 30 GB/s, rispetto a circa 1 del volume Amazon EBS principale. GB/s Indirizza la cache al punto di montaggio hostPath NVMe per ottimizzare il throughput.
Importante
Il hostPath volume utilizza. type: DirectoryOrCreate Se lo indirizzi verso un percorso non supportato dall'Instance Store NVMe, Kubernetes crea invece silenziosamente la directory sul volume principale di Amazon EBS. La cache funziona ancora, ma si perdono i vantaggi prestazionali di NVMe senza errori o avvisi.
Il punto di montaggio NVMe e il modo in cui viene abilitato differiscono tra la modalità automatica EKS e i nodi autogestiti:
| Calcolo | Punto di montaggio NVMe | Come abilitare l'archivio di istanze NVMe |
|---|---|---|
|
Modalità automatica di EKS |
|
Abilitato dinamicamente in base allo storage temporaneo richiesto. EKS Auto Mode formatta e monta l'archivio di istanze NVMe come array RAID 0 quando l'istanza ha più unità NVMe solo quando la |
|
Self-managed Karpenter |
|
Ambientato |
Per EKS Auto Mode, imposta il valore su nelle specifiche del contenitore: hostPath /mnt/.ephemeral/compile-cache
volumes: - name: compile-cache hostPath: path: /mnt/.ephemeral/compile-cache type: DirectoryOrCreate
Per Karpenter autogestito, imposta il hostPath to /mnt/k8s-disks/0/compile-cache nelle specifiche del contenitore:
volumes: - name: compile-cache hostPath: path: /mnt/k8s-disks/0/compile-cache type: DirectoryOrCreate
Risultati di esempio
-
Il primo Pod su un nodo esegue torch.compile e scrive i kernel compilati sull'host.
/compile-cache -
I Pod successivi sullo stesso nodo montano la cache esistente e saltano completamente la compilazione, il che riduce l'avvio a freddo di torch.compile da ~50—80 s a ~4—6 s.
La tabella seguente mostra il miglioramento della memorizzazione nella cache dello stesso nodo per modelli di dimensioni diverse:
| Dimensione del modello | first Pod torch.compile (senza cache) | Pods torch.compile successivi (stesso nodo) |
|---|---|---|
|
60 GB |
~ 53 secondi |
~6 secondi |
|
140 GB |
~ anni '60 |
~6 secondi |
|
640 GB |
~anni '80 |
~6 secondi |
Pre-warm torch.compile cache sui nuovi nodi
Questa tecnica si applica quando si esegue l'inferenza multinodo con GPU omogenee, parallelismo tensoriale, modelli e versioni tra nodi. PyTorch La tecnica Memorizza gli artefatti torch.compile sullo stesso nodo si concentra sul caso di un singolo nodo, ma i nuovi nodi aggiunti durante gli eventi di scalabilità iniziano con una cache torch.compile vuota. Per ridurre ulteriormente i tempi di avvio a freddo sui nodi appena inizializzati, puoi implementare un meccanismo di caching che memorizza gli artefatti torch.compile compilati in S3 e li prescarica in nuovi nodi quando si uniscono al cluster.
L'approccio generale è:
-
Dopo che il primo Pod ha compilato il modello sul primo nodo, carica gli artefatti torch.compile (~15 MB) in un bucket S3.
-
Quando nuovi nodi si uniscono al cluster, scarica gli artefatti memorizzati nella cache nella memoria locale del nodo prima che i Pod di inferenza siano programmati.
Ad esempio, puoi implementare uno DaemonSet che viene eseguito su nodi GPU che impacchetta e carica la cache torch.compile su S3. Può anche sincronizzare la cache con l'archiviazione dei nodi locali prima che i pod di inferenza vengano pianificati su nuovi nodi.
Considerazioni sulla memorizzazione nella cache tra nodi
Quando si memorizzano nella cache gli artefatti torch.compile tra i nodi, i kernel compilati sono validi solo quando questi parametri corrispondono tra il nodo che ha generato la cache e il nodo che la consuma. Il meccanismo di caching deve tenere conto di tutti questi fattori. Una mancata corrispondenza su qualsiasi parametro produce una cache non valida che impone la ricompilazione o causa errori di runtime. Lo strumento di caching deve distinguere gli artefatti in base a questi parametri, ad esempio incorporandoli nella chiave oggetto S3 o nella struttura della directory della cache.
| Parametro | Perché è importante |
|---|---|
|
Tipo GPU |
I kernel compilati sono GPU-architecture-specific (ad esempio, sm_90 per H100 e sm_89 per L4). |
|
Parallelismo tensoriale (TP) |
Gradi TP diversi producono partizioni grafiche di calcolo diverse. |
|
Modello |
L'architettura e la dimensione di ogni modello vengono compilate in kernel diversi. |
|
PyTorch versione |
Gli interni dei compilatori torch.compile e Triton possono introdurre modifiche sostanziali tra le versioni. |
Risultati di esempio
Nei test direzionali con preriscaldamento della cache tra nodi (Qwen3-6-35B-A3B, 67 GB, 2 GPU con TP=2 su p5.48xlarge), il primo Pod su nodi appena scalati ha raggiunto lo stesso tempo di avvio dei Pod successivi su un nodo già caldo:
| Scenario | Primo Pod | Secondo pod |
|---|---|---|
|
Senza memorizzazione nella cache tra nodi (nuovo nodo) |
65s |
Anni 16 |
|
Con memorizzazione nella cache tra nodi (nuovo nodo) |
16s |
16 anni |
Esempio di implementazione
L'esempio seguente combina l'ottimizzazione delle prestazioni di Run:ai Model Streamer e una cache torch.compile in un unico manifest di vLLM Deployment. Sostituisci i valori segnaposto con la tua configurazione:
-
serviceAccountName— Account di servizio con un ruolo IAM che consente ad Amazon S3 di accedere in lettura al bucket del modello. -
nodeSelector(karpenter.sh/nodepool) — Il nome del pool di nodi della GPU (ad esempio,).gpu-nodepool-g6e-12xlarge -
--model— Percorso Amazon S3 rispetto ai pesi del modello. -
--model-loader-extra-config— Impostatoconcurrencyin base alle dimensioni del modello:.ceil(total_model_size_gb / chunk_size_gb)Ad esempio, un modello da 67 GB con una dimensione del blocco da 4 GB fornisceceil(67 / 4) = 17. -
--tensor-parallel-size— Impostare il grado tensoriale parallelo (TP) sul numero minimo di GPU necessarie per adattare il modello alla memoria. -
hostPathpath— Mount point dell'archivio di istanze NVMe per nodi autogestiti con Karpenter. In modalità EKS Auto, usa invece./mnt/.ephemeral/compile-cachePer informazioni dettagliate, vedi Memorizza gli artefatti torch.compile sullo stesso nodo.
apiVersion: apps/v1 kind: Deployment metadata: name: vllm-inference namespace: default spec: replicas: 1 selector: matchLabels: app: vllm-inference template: metadata: labels: app: vllm-inference spec: serviceAccountName: <SERVICE_ACCOUNT_NAME> nodeSelector: karpenter.sh/nodepool: <GPU_NODEPOOL> tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: vllm image: vllm/vllm-openai:v0.21.0 command: - python3 - -m - vllm.entrypoints.openai.api_server args: - --model=s3://<BUCKET_NAME>/<MODEL_PATH> - --load-format=runai_streamer - --model-loader-extra-config={"concurrency":17,"distributed":true} - --tensor-parallel-size=2- --max-model-len=8192 - --host=0.0.0.0 - --port=8000 ports: - containerPort: 8000 name: http env: # Run:ai streamer tuning - name: RUNAI_STREAMER_CHUNK_BYTESIZE value:"4294967296"- name: RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS value:"3000"- name: RUNAI_STREAMER_S3_LOW_SPEED_LIMIT value:"1048576"# torch.compile cache - name: XDG_CACHE_HOME value:"/compile-cache"- name: TORCHINDUCTOR_CACHE_DIR value:"/compile-cache/inductor"- name: TRITON_CACHE_DIR value:"/compile-cache/triton"resources: requests: cpu: "12" memory: 80Gi nvidia.com/gpu: "2" limits: nvidia.com/gpu: "2" volumeMounts: - name: compile-cache mountPath: /compile-cache startupProbe: httpGet: path: /health port: 8000 periodSeconds: 10 failureThreshold: 60 initialDelaySeconds: 30 readinessProbe: httpGet: path: /health port: 8000 periodSeconds: 5 timeoutSeconds: 3 volumes: - name: compile-cache hostPath: path:/mnt/k8s-disks/0/compile-cachetype: DirectoryOrCreate