Ollama – parte 5

Dialogo con Gemini.

Quali sono i limiti di usare Ollama senza CUDA?

Eseguire Ollama senza accelerazione CUDA (o senza un backend GPU accelerato come ROCm/Metal) sposta l’intero carico di calcolo sui thread della CPU e sulla RAM di sistema tramite il runtime llama.cpp.

I limiti tecnici e pratici principali si articolano su più fronti:

1. Crollo del Prompt Processing (Time-to-First-Token) L’inferenza di un LLM si divide in due fasi distinte:

  • Prompt Evaluation (Prefill): Quando invii una richiesta con un lungo contesto (es. un documento, codice o una chat articolata), il sistema elabora tutti i token di input contemporaneamente. Questa fase richiede calcolo matriciale massiccio e altamente parallelo: Internals Decoded+ 1
    • Su GPU con CUDA, una scheda elabora centinaia o migliaia di token al secondo in fase di prefill.
    • Su CPU, il prefill scende a 10–40 token al secondo. Inserire un testo lungo (es. 4.000–8.000 token) si traduce in un’attesa di diversi minuti solo prima di vedere apparire la prima parola.

2. Bassa velocità di generazione (Token per secondo) La fase di generazione dei singoli token successivi è limitata dalla larghezza di banda della memoria (Memory Bandwidth):

  • Una RTX 3060 sposta dati a ~360 GB/s; una RAM DDR5 dual-channel consumer si ferma a ~60–80 GB/s, mentre una DDR4 a ~35–45 GB/s.
  • Di conseguenza, la generazione su CPU è mediamente da 4 a 10 volte più lenta rispetto all’uso di CUDA:
    • Modello 8B (Q4): 45–60 t/s su GPU vs 8–14 t/s su CPU desktop.
    • Modello 14B (Q4): 25–35 t/s su GPU vs 4–7 t/s su CPU.
    • Modello 70B (Q4): 15–20 t/s su cluster GPU vs 1.5–3 t/s su CPU.

3. Mancanza di ottimizzazioni kernel avanzate (FlashAttention) Senza GPU NVIDIA e CUDA non è possibile sfruttare FlashAttention, una tecnica che riduce la complessità di memoria e accelera l’attenzione su contesti ampi. Senza FlashAttention, all’aumentare della lunghezza del contesto (8k, 16k, 32k) la memoria richiesta per la cache KV cresce linearmente e rallenta l’intero processo.

4. Saturazione completa delle risorse di sistema Durante l’inferenza, llama.cpp impegna tutti i core fisici della CPU al 100% con istruzioni vettoriali intensive (AVX2/AVX-512). Questo porta a:

  • Blocco o rallentamento percettibile di altri processi in esecuzione sullo stesso host (container Docker, database, server web).
  • Picchi termici costanti della CPU con ventole al massimo regime e consumi prolungati fino al TDP massimo.
  • Impossibilità pratica di gestire richieste concorrenti (OLLAMA_NUM_PARALLEL > 1) senza degradare i tempi di risposta.

Riepilogo: Quando è accettabile e quando no

ScenarioSenza CUDA (Solo CPU)Con CUDA (GPU Dedicata)
Chat interattiva e AssistantLenta, poco naturale sui modelli mediIstantanea e fluida
RAG / Analisi di documenti lunghiPessima (prefill lentissimo sui documenti)Ottima (prefill rapido del contesto)
Coding / Autocompletamento (IDE)Inutilizzabile (latenza troppo alta)Funzionale in tempo reale
Elaborazioni batch non presidiateAccettabile (può girare di notte)Molto più rapida
Modelli MoE / 70B a basso costoUnica via economica per 128GB+ RAMRichiede GPU costose (es. 2x 3090)