Cosa causa il caricamento di copie duplicate di un modello da parte di un runtime di IA locale?

Eva Wong è la Technical Writer e smanettatrice residente di ZimaSpace. Una geek da sempre con una passione per homelab e software open-source, si specializza nel tradurre concetti tecnici complessi in guide accessibili e pratiche. Eva crede che l'auto-ospitare debba essere divertente, non intimidatorio. Attraverso i suoi tutorial, dà potere alla comunità di demistificare le configurazioni hardware, dalla costruzione del loro primo NAS al dominio dei container Docker.

Le copie duplicate del modello compaiono quando processi, repliche, sessioni o contesti dei dispositivi separati non possono condividere una singola allocazione dei pesi caricati.

Un server AI domestico può mostrare circa il doppio della RAM o della VRAM prevista dopo l’aggiunta di un’interfaccia web, di un worker in background, di un servizio vocale, di un indicizzatore di documenti o di un secondo endpoint API. Il file del modello su disco può rimanere unico, mentre diversi oggetti di runtime mantengono pesi indipendenti, tensori convertiti, kernel preconfezionati, cache e contesti dei dispositivi. Alcune duplicazioni sono accidentali; altre sono repliche deliberate create per la concorrenza, l’isolamento o l’esecuzione parallela.

Un singolo file del modello può produrre diversi oggetti di runtime indipendenti

Caricare dallo stesso percorso non implica che due applicazioni facciano riferimento allo stesso modello in memoria. Ogni istanza di runtime può analizzare il checkpoint e allocare i propri tensori.

Le indicazioni di Google Cloud sull’inferenza distinguono tra configurazioni che caricano una copia del modello per processo o per macchina virtuale.

Se la memoria aumenta con incrementi delle dimensioni del modello all’aumentare del numero di worker, la causa principale è la replicazione delle istanze. Aumenti più contenuti indicano più probabilmente cache per worker, allocatori o contesti di esecuzione.

I server web e i worker dei processi spesso avviano processi separati

Un server frontend, un consumer della coda, uno scheduler, un servizio di trascrizione e un worker RAG possono importare ciascuno il caricatore del modello, anche se fanno parte di un’unica configurazione Compose.

L’isolamento dei processi assegna a ogni servizio il proprio spazio di indirizzamento. Le pagine della CPU possono talvolta essere condivise tramite meccanismi del sistema operativo, ma gli oggetti ordinari dei framework e le allocazioni della GPU non diventano automaticamente un unico servizio del modello condiviso.

La duplicazione segue gli ID dei processi e i confini dei servizi. Se l’arresto di un container rilascia circa una copia del modello, quel container non si limitava a inoltrare le richieste a un runtime centrale.

Le repliche del servizio sono copie individuali per progettazione

I sistemi di autoscaling aumentano la produttività avviando più repliche. Una replica è un worker indipendente in grado di gestire le richieste quando gli altri worker sono occupati.

Ray Serve definisce le repliche come copie individuali eseguite in processi actor separati.

Una crescita della memoria che segue i picchi di traffico o gli eventi dell’autoscaler è una replicazione intenzionale, non una perdita di memoria. La causa è il modello di concorrenza scelto, anche se le repliche aggiuntive impiegano tempo per ridursi in seguito.

-15% OFF

Più sessioni di inferenza possono duplicare inizializzatori e pesi preconfezionati

Un’applicazione può creare diverse sessioni all’interno di un unico processo per thread, endpoint, profili o provider di esecuzione differenti.

ONNX Runtime documenta la condivisione di allocatori, inizializzatori e pesi preconfezionati tra le sessioni, poiché sessioni separate aggiungono altrimenti un sovraccarico di memoria.

Se un processo possiede diversi oggetti sessione e la memoria aumenta quando ogni sessione viene inizializzata, lo stato duplicato esiste all’interno dell’applicazione anziché tra i container.

Il fork non garantisce la condivisione dei pesi dell’acceleratore

Un processo padre può caricare un modello prima di creare i worker e sembrare in grado di condividere le pagine della CPU tramite copy-on-write. L’inizializzazione dell’acceleratore e lo stato mutabile del runtime complicano questa ipotesi.

Le indicazioni sul multiprocessing di PyTorch spiegano che i tensori possono usare meccanismi di memoria condivisa tra processi, ma la condivisione richiede una progettazione esplicita e compatibile.

Un worker che sposta il modello sulla GPU, modifica i pesi, crea una cache o esegue l’inizializzazione dopo lo spawn può allocare una nuova copia, anche se le pagine del checkpoint originale sulla CPU erano condivise.

Contesti CUDA separati aggiungono stato del dispositivo per processo

Due processi che utilizzano una GPU operano normalmente tramite contesti CUDA distinti, a meno di usare un’architettura speciale per la condivisione.

NVIDIA osserva che più processi di applicazioni CUDA generalmente creano più contesti con sovraccarico di memoria.

Il sovraccarico dei contesti non equivale da solo a un secondo modello completo, ma può accompagnare la duplicazione di pesi, kernel, aree di lavoro e cache. Di conseguenza, aumenti inferiori alle dimensioni del checkpoint possono comunque derivare dalla duplicazione dei processi.

Due istanze di runtime sulla stessa GPU riservano la memoria in modo indipendente

Un pannello di controllo può avviare un server del modello mentre un servizio di automazione ne avvia un altro, entrambi puntando allo stesso checkpoint e allo stesso dispositivo.

vLLM documenta che l’utilizzo della memoria della GPU è un limite per istanza e fornisce l’esempio di due istanze che dividono la capacità di una GPU.

Se ogni endpoint ha il proprio listener, i propri log, scheduler e la propria cache KV, i due processi sono motori di inferenza indipendenti. Una directory condivisa dei modelli impedisce download duplicati, non allocazioni duplicate durante l’esecuzione.

I ricaricamenti possono lasciare in esecuzione un vecchio processo accanto a quello nuovo

I sistemi di ricaricamento automatico, i supervisori, gli aggiornamenti progressivi, gli arresti non riusciti e i riavvii dei controlli di integrità possono avviare una sostituzione prima che il vecchio worker rilasci il modello.

Questa causa si manifesta come una coppia temporanea o persistente di processi quasi identici con orari di avvio diversi. Le richieste possono essere indirizzate solo al processo più recente, mentre quello precedente continua a occupare RAM o VRAM.

L’articolo di ZimaSpace sul motivo per cui separare lo stato del runtime AI dai file del modello chiarisce il confine: una singola cache del checkpoint può servire molte distribuzioni, ma la topologia del servizio determina comunque quante copie caricate esistono.

Domande frequenti

Un singolo file del modello su disco significa che in RAM esiste una sola copia?

No. Più processi o sessioni possono leggere indipendentemente lo stesso file e allocare i propri tensori, cache e stati di esecuzione.

Ogni copia aggiuntiva è una perdita di memoria?

No. Le repliche, i worker con parallelismo tensoriale, i runtime di fallback e i servizi isolati possono allocare intenzionalmente stato aggiuntivo. Una perdita cresce senza un corrispondente oggetto di runtime attivo.

I container possono condividere automaticamente un modello sulla stessa GPU?

No. I container possono accedere allo stesso dispositivo e agli stessi file, ma hanno bisogno di un processo di serving condiviso o di una progettazione esplicita tra processi per riutilizzare un’unica allocazione del modello caricato.

Hub Tecnologico e AI

Altro da leggere

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.