La maggior parte dei servizi di inferenza usa solo una parte di una GPU, e una scheda intera è spesso più di quanto serva a un notebook, a un job di batch scoring o a un piccolo modello. Condividere una scheda tra più carichi di lavoro sembra semplice, ma Kubernetes non lo fa per impostazione predefinita, e i diversi modi per farlo fanno promesse molto diverse. Questo articolo spiega quelle promesse, che cosa una slice condivisa su Kube-DC garantisce e che cosa no, e che cosa abbiamo imparato eseguendo un vero LLM su di essa.

Kubernetes assegna GPU intere per impostazione predefinita

Il modello standard di device plugin di Kubernetes comunica le GPU allo scheduler come numeri interi. Una richiesta di nvidia.com/gpu: 1 significa l'intera scheda, e tutti gli altri pod attendono. Lo scheduler non ha alcuna nozione di quota di memoria, quindi condividere una scheda richiede meccanismi aggiuntivi, e ci sono tre approcci comuni.

Approccio Limite di memoria Isolamento Funziona su una V100?
MIG (partizionamento hardware) Applicato in hardware Isolamento di memoria e dei guasti a livello hardware No: richiede Ampere o successive (A100, H100, A30, H200), e la V100 è una scheda più vecchia, della generazione Volta
Time-slicing Nessuno: le repliche condividono la memoria della scheda Nessun isolamento di memoria né dei guasti tra le repliche, secondo la documentazione NVIDIA Sì
Software slicing (HAMi) Applicato in software: le allocazioni oltre la slice vengono rifiutate Isolamento software tramite intercettazione delle API CUDA; non è isolamento hardware e il calcolo viene limitato secondo il criterio best-effort Sì

HAMi, un progetto della Cloud Native Computing Foundation, funziona caricando in ogni container una libreria che intercetta le chiamate CUDA. Il container vede solo la propria slice di memoria, un'allocazione che supererebbe la slice restituisce un errore di memoria esaurita e i lanci dei kernel vengono limitati verso la quota di calcolo richiesta. La documentazione di HAMi stessa è accurata sui limiti: le applicazioni che aggirano la libreria CUDA, come Docker-in-Docker o le chiamate dirette al driver, non sono coperte, e l'isolamento è best-effort rispetto a MIG.

Che cosa garantisce una slice condivisa su Kube-DC

I pacchetti GPU di Kube-DC usano il software slicing su schede NVIDIA V100 e la documentazione della piattaforma indica con precisione le garanzie. Una slice è una frazione fissa di un modello di GPU; richiedi il prodotto anziché regolare liberamente memoria e calcolo. Su una V100 da 32 GB, i nostri pacchetti offrono il 25% (8 GiB), il 50% (16 GiB) e il 100% (32 GiB).

  • La slice di memoria è applicata. All'interno del container, nvidia-smi riporta la dimensione della slice, non quella della scheda fisica, e la slice è un limite rigido.
  • La quota di calcolo è cooperativa. La piattaforma orienta ogni carico di lavoro verso la propria quota a regime, ma all'avvio e su alcuni percorsi delle librerie CUDA questa può essere superata brevemente. Non è una prestazione garantita.
  • La quota è un diritto, non una prenotazione. Detenere una quota non riserva una slice fisica. Quando tutte le GPU compatibili sono occupate, un carico di lavoro valido attende nello stato Pending finché non si libera una slice.
  • Le slice sono per i container. La capacità condivisa non può essere collegata a una macchina virtuale.
Una slice condivisa è una garanzia di pianificazione e contabilizzazione con applicazione a runtime. Non è un confine di sicurezza. Un carico di lavoro che non deve condividere il silicio con un altro tenant ha bisogno di una GPU dedicata.

Come si presenta l'uso

Da Kubernetes 1.34 le API Dynamic Resource Allocation (DRA) in resource.k8s.io/v1 sono generalmente disponibili e Kube-DC le usa: un carico di lavoro fa riferimento a un ResourceClaimTemplate che punta alla DeviceClass del tuo prodotto, e la piattaforma convalida la richiesta quando la applichi. La quota del tuo progetto mostra quante slice di ciascun prodotto puoi detenere contemporaneamente:

kubectl get resourcequota -n <project-namespace> -o yaml | grep deviceclass

Una volta in esecuzione il pod, conferma la slice dall'interno del container. Con il prodotto da 8 GiB la memoria totale è di 8192 MiB anche se la scheda ha 32 GB:

nvidia-smi --query-gpu=name,memory.total --format=csv,noheader
# Tesla V100-PCIE-32GB, 8192 MiB

Il manifest completo, da copiare e modificare, si trova nella documentazione di Kube-DC e non lo riproduciamo volutamente qui, perché deve corrispondere esattamente al contratto pubblicato dalla piattaforma. Nel nostro test, due tentativi sono falliti per questo motivo prima che il terzo riuscisse:

  • Una semplice richiesta nvidia.com/gpu su un pod grezzo è stata rifiutata da una admission policy, perché la capacità GPU condivisa viene offerta solo tramite il modello basato sui claim.
  • Un claim template DRA scritto a mano è stato rifiutato da una seconda admission policy, perché etichette, nomi e valori di capacità fissi devono seguire la forma documentata.
  • Il manifest documentato è stato accettato, poi il pod non è riuscito ad avviarsi per un motivo non correlato: la quota di CPU in pool del progetto era quasi interamente utilizzata da un Managed Cluster e da una macchina virtuale. Un pod GPU richiede comunque CPU e memoria dal tuo pacchetto, quindi verifica quel margine prima di distribuire.

Eseguire un LLM su una slice: cosa abbiamo imparato

Nel nostro test end-to-end di agosto 2026 abbiamo eseguito Ollama su una slice da 8 GiB servendo llama3.2:3b, poi vi abbiamo collegato un agente IA, prima da una macchina virtuale nello stesso progetto e poi da un server esterno al data center. I log di Ollama mostravano la scheda come Tesla V100 con compute capability 7.0 e un totale di 8,0 GiB, esattamente la slice. Quattro dettagli ci sono costati tempo, e ognuno vale per chiunque esegua un modello su una slice.

1. Verifica che il tuo software supporti ancora la generazione della GPU

La V100 è una scheda della generazione Volta e il software GPU attuale ha iniziato ad andare oltre. Nel nostro test l'ultima immagine di Ollama ha saltato la GPU, perché la sua build CUDA non includeva la compute capability 7.0. Bloccare la versione ollama/ollama:0.24.0 ha risolto il problema. Ciò coincide con le segnalazioni upstream: una issue di Ollama descrive la v0.30.0 che fallisce su una Tesla V100 con l'errore "device kernel image is invalid", mentre la v0.24.0 e le precedenti funzionavano, e un maintainer ha poi attribuito uno di questi errori a kernel CUDA compressi che richiedono il driver NVIDIA 550 o successivo. Blocca la versione della tua immagine e testa gli aggiornamenti con consapevolezza.

2. Il limite di memoria del pod è separato dalla slice GPU

Il nostro primo caricamento del modello è stato terminato con codice di uscita 137 (OOMKilled). La causa era il limite di memoria del container stesso, pari a 512 MiB, decisamente troppo piccolo per l'overhead lato host di Ollama, e non aveva nulla a che fare con la memoria della GPU. Dimensiona request e limit di RAM del container indipendentemente dalla slice fissa. Abbiamo usato 2 GiB e 4 GiB:

containers:
- name: ollama
  image: ollama/ollama:0.24.0
  env:
  - name: OLLAMA_CONTEXT_LENGTH
    value: "16384"
  resources:
    requests:
      memory: 2Gi
    limits:
      memory: 4Gi

3. La finestra di contesto predefinita può troncare in silenzio il prompt di un agente

L'agente che abbiamo collegato invia un prompt di sistema e definizioni di strumenti per circa 14.700 token. Il log del server Ollama mostrava l'input tagliato al suo limite di 4.096 token, il che produceva risposte confuse e inaffidabili che sembravano un problema di qualità del modello. Aumentare la lunghezza del contesto con la variabile qui sopra ha risolto la causa. Ricorda che un contesto più lungo usa più memoria della tua slice, quindi dimensiona insieme modello e contesto.

4. I modelli vivono nel pod, a meno che tu non dia loro un volume

Con lo storage temporaneo predefinito, ogni riavvio del pod, compreso uno causato dalla modifica di una variabile d'ambiente, cancellava i modelli scaricati. Metti la directory dei modelli su un volume persistente per qualsiasi cosa vada oltre una demo. Tieni presente inoltre che i ruoli tenant su Kube-DC non possono usare kubectl exec, quindi abbiamo scaricato i modelli con Job una tantum che chiamano l'API HTTP di Ollama.

Quando una slice condivisa è lo strumento giusto

La documentazione di Kube-DC indica il caso d'uso adatto: inferenza di modelli, notebook, piccole esecuzioni di addestramento e batch scoring, in cui un job richiede l'accelerazione GPU ma non una scheda intera. È poco adatta quando servono un confine di isolamento rigido, un throughput garantito o un modello più grande della slice, e il lavoro che richiede una scheda intera va su hardware dedicato. Poiché le slice vanno in coda quando la scheda è occupata, è inoltre più adatta a carichi di lavoro che possono attendere la capacità che a servizi critici per la latenza con scadenze rigide.

Come valutare qualsiasi offerta di GPU condivisa

  • Il limite di memoria è applicato o è un semplice suggerimento? Il time-slicing non ne applica nessuno.
  • La quota di calcolo è garantita, cooperativa o illimitata, e che cosa succede in caso di contesa?
  • La quota è una prenotazione, oppure il tuo carico di lavoro può restare in attesa in Pending quando la scheda è occupata?
  • Che modello di GPU è, e il software che prevedi di eseguire ne supporta ancora la generazione?
  • Puoi ottenere una scheda intera o una VM dedicata se la slice non ti basta più, e come si presenta l'isolamento in quel caso?
  • Quali CPU, memoria e storage ottieni insieme alla GPU, e sono condivisi in pool con il resto dei tuoi carichi di lavoro?

Fonti

Letture correlate

Provalo su Kube-DC

I nostri pacchetti GPU aggiungono a un pool Kube-DC una slice di una NVIDIA V100 condivisa: il 25%, il 50% o il 100% della scheda, con la slice di memoria applicata. Insieme ottieni vCPU dedicate, storage NVMe basato su Ceph, un IPv4 pubblico dedicato, object storage compatibile S3 e i tuoi cluster Kubernetes amministrati dal tenant, con supporto 24/7 via email e ticket e un obiettivo di risoluzione di 4 ore. Abbiamo eseguito end-to-end un vero LLM e un agente IA, e ogni passaggio di questo articolo è uno che puoi ripetere.

Scopri Kube-DC Kubernetes