Ingegneria

Come un LLM genera il testo, parola per parola

Jithin Kumar Palepu · 7 luglio 2026 · 12 min di lettura

Chiedi a un modello “Cos'è la gravità?” e ti risponde una parola alla volta, da sinistra a destra, come se stesse pensando ad alta voce. Non sta pensando ad alta voce. Sotto il cofano, ogni singolo token che vedi comparire ha percorso la stessa catena di montaggio: tokenizza, fai l'embedding, attraversa lo stack del transformer, proietta sul vocabolario, campiona un token, e poi ricomincia da capo per quello dopo. Qui percorriamo quella catena dall'inizio alla fine, e il fatto che ribalta tutto quello che credevi di sapere sulla velocità di un LLM.

Ho organizzato tutto in nove fasi numerate, che uso come spina dorsale: poi spendo la maggior parte delle parole sulla cosa che decide quanto è veloce e quanto costa tutto questo: la realtà dei sistemi.

Cosa imparerai

  • Le nove fasi che ogni token attraversa, dal tokenizer all'output in streaming
  • Perché l'inferenza si divide in due fasi con colli di bottiglia opposti
  • Cosa contiene davvero la KV cache, e perché è il principale limite di memoria
  • Come si differenziano greedy, top-k, top-p e temperature
  • Da dove nascono le allucinazioni, e come un RAG privato le tiene a bada
  • Perché FlashAttention, quantizzazione e speculative decoding colpiscono ciascuno un punto debole preciso

Tutta la pipeline in un respiro

Il modello non fa niente di misterioso. Fa queste nove cose, in ordine, e le ultime si ripetono una volta per ogni token in uscita.

  1. Input. Il tuo prompt di testo grezzo.
  2. Tokenizer. Spezza il testo in token e mappa ciascuno su un ID intero.
  3. Embedding. Trasforma ogni ID in un vettore denso.
  4. Blocco transformer (× N layer). Self-attention più una rete feed-forward, impilate decine di volte.
  5. Linear + softmax (LM head). Proietta il vettore finale in una probabilità su tutto il vocabolario.
  6. Campionamento. Sceglie il token successivo da quella distribuzione.
  7. Speculative decoding. Un trucco di velocità opzionale che indovina più token in avanti e li verifica in blocco.
  8. Detokenizer. Riporta gli ID dei token scelti a testo.
  9. Streaming. Ti mostra i token man mano che arrivano.

Le fasi 4-8 girano una volta per ogni token del prompt, per “scaldare i motori”, e poi di nuovo, un token alla volta, per ogni parola della risposta. È tutta lì la storia, quindi diamogli un nome adesso: il riscaldamento si chiama prefill, la generazione a un token per volta si chiama decode. Tieni a mente queste due parole.

Prima che il modello pensi: tokenizzazione ed embedding

Un modello non sa leggere i caratteri. Il tokenizer taglia il tuo prompt in pezzi di sotto-parola e cerca un intero per ciascuno. Nota che una parola comune come “gravità” può spezzarsi in grav e ità. È normale, i tokenizer sono addestrati a spezzare le parole rare in frammenti frequenti.

"Cos'è la gravità?"
  -> token:      ["Cos", "'è", "la", "grav", "ità", "?"]
  -> ID token:   [3018, 704, 512, 26110, 879, 30]

Ogni ID viene poi usato per pescare una riga in una matrice di embedding, producendo un vettore denso. In un modello di classe GPT-4 quel vettore ha d_model = 4096 dimensioni. Così un prompt di sei token diventa una griglia di numeri 6 × 4096, e da qui in poi è tutta matematica di matrici su quella griglia. La tokenizzazione decide anche, in silenzio, la tua bolletta: paghi a token, e un tokenizer che frammenta di più il testo significa più token per le stesse parole.

Dentro il transformer: attenzione, KV cache e FFN

Questo è il motore, ed è impilato in profondità. Un modello di classe GPT-4 gira sull'ordine di 96 layer identici, e ogni layer fa le stesse due cose: mescola informazione tra i token con la self-attention, poi trasforma ogni token per conto suo con una rete feed-forward. (L'idea nasce dal celebre paper Attention Is All You Need (Vaswani et al., 2017).)

La self-attention proietta ogni token in tre vettori: una Query, una Key e un Value. Per decidere quanto il token i debba tenere conto del token j, il modello fa il prodotto scalare tra la query di i e la key di j, lo scala, e passa un softmax così che i pesi sommino a uno. Quei pesi poi fondono insieme i vettori value:

attention(Q, K, V) = softmax( (Q @ K^T) / sqrt(d_k) ) @ V

Dopo l'attenzione, una connessione residua riaggiunge l'input e un LayerNorm tiene stabili i numeri. Poi la rete feed-forward espande ogni vettore-token a una dimensione nascosta più larga, applica una non linearità come ReLU o SwiGLU, e lo riproietta giù. È lì che vive gran parte della conoscenza grezza del modello. (Nei modelli più grandi questa FFN è sparsa, e per ogni token si accendono solo pochi sotto-esperti, il trucco dietro il Mixture of Experts.) Somma, normalizza di nuovo, passa al layer successivo.

La KV cache è l'oggetto più importante dell'inferenza di un LLM, e quasi nessuno, fuori dal settore, ne ha mai sentito parlare.

Ecco la parte che governa tutto il resto. Quando il modello genera il token numero 500, la sua attenzione ha bisogno delle key e dei value di tutti i 499 token che lo precedono. Ricalcolarli da zero a ogni passo sarebbe folle, quindi il modello li conserva. Quel magazzino è la KV cache: i vettori key e value per ogni token, a ogni layer, tenuti nella memoria della GPU così non vengono mai calcolati due volte.

Il trucco è nell'aritmetica. La KV cache cresce linearmente con la lunghezza della sequenza. Ogni nuovo token aggiunge un'altra fetta di key e value, a ognuno dei 96 layer, per ogni testa di attenzione. Una conversazione lunga o un documento grande non costano solo più calcolo, si mangiano gigabyte di memoria, e rileggere quella cache a ogni singolo passo di decode è ciò che davvero mette un tetto alla tua velocità.

Dallo stato nascosto alla parola: LM head e campionamento

Dopo l'ultimo layer del transformer, un'ultima proiezione lineare, la LM head, mappa il vettore da 4096 dimensioni dell'ultimo token in un punteggio per ogni parola del vocabolario. I vocabolari ormai sono grandi, sull'ordine di 128K voci, quindi escono 128.000 numeri grezzi chiamati logit. Un softmax li trasforma in una distribuzione di probabilità: questo token 41%, quello 12%, e così via.

Ora il modello deve davvero sceglierne uno. Questo è il campionamento, e la strategia che scegli è la differenza tra un output robotico e uno creativo.

Greedy e temperature

Il decoding greedy prende ogni volta il token con la probabilità più alta. È veloce e deterministico, ma tende a essere piatto e ripetitivo. La temperature rimodella la distribuzione prima del campionamento: una temperature bassa la rende più appuntita verso la scelta migliore, una alta la appiattisce così che anche i token improbabili abbiano una vera possibilità.

Perché conta. La temperature è la manopola principale: vicino a 0 il modello è deterministico e ripetitivo, vicino a 1 è sciolto e creativo.

Top-k e top-p (nucleus)

Top-k tiene solo i k token più probabili e campiona tra quelli. Top-p, detto anche nucleus sampling, è più furbo: tiene l'insieme più piccolo di token le cui probabilità sommano a p (diciamo 0,9), così la rosa di candidati si allarga quando il modello è incerto e si stringe quando è sicuro. Quasi tutti i sistemi in produzione combinano top-p con una temperature moderata.

Perché conta. Entrambi esistono per tagliare la lunga coda di token spazzatura senza uccidere tutta la varietà.

Perché il decode è così lento? Prefill contro decode

Ora possiamo incassare quelle due parole di prima. L'inferenza gira in due fasi dal carattere opposto, e confonderle è il motivo per cui in tanti sbagliano a valutare dove va a finire il tempo.

FaseCosa faCollo di bottiglia
PrefillLegge tutto il prompt in una volta. Tutti i token d'ingresso attraversano lo stack in parallelo, in un grande prodotto di matrici. La GPU è impegnata, la matematica è pesante.Limitata dal calcolo
DecodeScrive un token alla volta. Ogni passo elabora un solo token nuovo ma deve rileggere l'intera KV cache e ogni peso dalla memoria. Quasi nessun calcolo in parallelo, tanto movimento di dati.Limitata dalla memoria

È questo il cuore controintuitivo di tutta la faccenda. Durante il decode la GPU non è a corto di matematica, è a corto di banda di memoria. Passa gran parte di ogni passo ad aspettare che pesi e KV cache in crescita arrivino dalla memoria, poi fa una quantità minuscola di aritmetica su un token, poi aspetta di nuovo. Il tuo costoso acceleratore è per lo più fermo, a tamburellare le dita. Ogni serio intervento di ottimizzazione è un attacco a quella attesa precisa.

Dove nascono le allucinazioni (e come SinergIA le evita)

Rileggi la fase di campionamento. Il modello sceglie il token più plausibile, non quello più vero: pesca dalla sua memoria interna, quella cablata nei pesi durante l'addestramento. Quando non sa qualcosa, non tace, produce comunque una sequenza plausibile. È esattamente da lì che nascono le allucinazioni: non da un bug, ma dal modo in cui il modello genera, per costruzione.

Per dati bancari, di compliance o di rischio, un fatto inventato ma plausibile non è un errore qualunque: è un danno. La risposta non è sperare che il modello “si ricordi bene”. È cambiare la fonte da cui attinge. È l'idea dietro il RAG privato: invece di fidarsi della memoria del modello, ogni risposta è calcolata dalle tue fonti e le cita, riga per riga, tracciabile fino al documento e al dato di origine. Niente scatole nere, niente affermazioni da prendere sulla fiducia.

È il modello che SinergIA porta dentro le istituzioni finanziarie: la conoscenza resta in una knowledge base isolata, con dati trattati in UE e nel rispetto del GDPR, e nessun modello condiviso addestrato sui tuoi contenuti. Gli agenti non improvvisano: consultano i tuoi documenti, preparano una bozza ragionata e mostrano da dove viene ogni pezzo. La decisione resta tua, ma parti da un lavoro che puoi verificare, non da una frase convincente e forse falsa.

I trucchi di velocità: FlashAttention, quantizzazione, speculative decoding

Una volta accettato che il decode è limitato dalla memoria, tutto il manuale di ottimizzazione si legge come una lista di modi per muovere meno dati. Ecco i tre che contano di più, ciascuno puntato a una parte diversa del collo di bottiglia.

FlashAttention

FlashAttention fonde il calcolo dell'attenzione così da non scrivere mai la gigantesca matrice intermedia dei punteggi nella lenta memoria ad alta banda della GPU. Piastrella il lavoro per restare nella veloce memoria on-chip, tagliando drasticamente le letture di memoria a parità di risultato. Vedi il paper originale (Dao et al., 2022).

Perché conta. L'attenzione sprecava in silenzio gran parte del suo tempo a spostare risultati intermedi da e verso la memoria lenta. Questo semplicemente smette di farlo.

Quantizzazione

Conservare i pesi in INT8 o INT4 invece che in float a 16 bit rimpicciolisce il modello di 2-4×. Non è solo questione di stare su una GPU più piccola. Poiché il decode è strozzato dalla lettura dei pesi dalla memoria, dimezzarne la dimensione può quasi dimezzare il tempo d'attesa, spesso con perdita di qualità trascurabile.

Perché conta. Pesi più piccoli significano meno byte da trascinare dalla memoria a ogni passo di decode, e una fase limitata dalla memoria diventa direttamente più veloce.

Speculative decoding

Un piccolo modello “bozza”, veloce, propone diversi token candidati, e il grande modello bersaglio li verifica tutti in un solo passaggio in avanti, accettando quelli su cui è d'accordo e correggendo il primo su cui non lo è. L'output è identico al decode normale, ma ottieni più token per ogni passaggio costoso. L'idea centrale viene da Leviathan et al. (2022).

Perché conta. Invece di un token lento per ogni passaggio costoso, verifichi diverse ipotesi economiche in un solo passaggio.

Nota lo schema. FlashAttention muove meno dati durante l'attenzione, la quantizzazione muove meno byte per peso, e lo speculative decoding tira fuori più token da ogni passaggio affamato di memoria. Nessuno rende più veloce l'aritmetica, perché l'aritmetica non è mai stata il problema. Combattono tutti il muro della memoria.

Detokenizzazione e streaming

Le ultime due fasi sono quelle facili. Ogni token a cui il modello si impegna è un numero, quindi il detokenizer esegue il tokenizer al contrario, riportando ID come 2610, 879, 318 a “La gravità è…”. E poiché la risposta viene comunque costruita un token alla volta, non c'è motivo di farti aspettare il tutto. Lo streaming spinge ogni token sul tuo schermo nell'istante in cui viene scelto, ed è per questo che guardare un modello scrivere sembra guardarlo pensare, anche se ha finito di decidere ogni parola una frazione di secondo prima che tu la vedessi.

Perché questo modello mentale conta

Non ti serve memorizzare nove fasi. Ti serve un'unica idea portante: l'inferenza è in due fasi, e quella lenta, il decode, è limitata dalla memoria. Tutto il resto ne discende. I prompt lunghi ti costano in calcolo di prefill. Le conversazioni lunghe ti costano in memoria della KV cache. Ogni ottimizzazione di latenza che valga la pena conoscere è uno stratagemma per muovere meno dati a ogni passo di decode.

Una volta che la vedi così, le notizie di questo campo smettono di essere una nebbia di trucchi scollegati. Le finestre di contesto più grandi sono in realtà un problema di memoria della KV cache. Un serving più economico è in realtà un problema di byte per peso. E quando un laboratorio annuncia un grande aumento di velocità senza perdita di qualità, sai già a quale muro deve aver trovato il modo di girare intorno.

In sintesi

  • Ogni token in uscita percorre la stessa pipeline in nove fasi, e le fasi 4-8 si ripetono per ogni token.
  • Il prefill legge tutto il prompt in parallelo ed è limitato dal calcolo; il decode scrive un token alla volta ed è limitato dalla memoria.
  • La KV cache conserva key e value passati così non vengono mai ricalcolati, e cresce linearmente con la lunghezza della sequenza.
  • Le allucinazioni nascono dal campionamento: il modello sceglie il token più plausibile, non il più vero. Un RAG privato le tiene a bada ancorando ogni risposta alle tue fonti, con citazione.
  • FlashAttention, quantizzazione e speculative decoding attaccano tutti lo stesso collo di bottiglia di memoria, non la matematica.

Vedi SinergIA sui tuoi dati

Prepara i report di Vigilanza con agenti che citano la fonte, riga per riga. Conoscenza isolata, conforme al GDPR e con dati trattati in UE.