TLDR
- I Transformer superano i colli di bottiglia sequenziali delle RNN elaborando tutti i token simultaneamente in parallelo.
- Il Positional Encoding sinusoidale reintroduce l'informazione di ordine sequenziale all'interno degli embedding vettoriali.
- Il meccanismo di Scaled Dot-Product Attention calcola la rilevanza tra matrici di Query (Q), Key (K) e Value (V).
- Le tre architetture fondamentali (Encoder-only, Decoder-only, Encoder-Decoder) coprono comprensione, generazione e traduzione.
La Rivoluzione dei Transformer
Prima del 2017, l'elaborazione del linguaggio naturale (NLP) e delle sequenze temporali era dominata dalle Reti Neurali Ricorrenti (RNN) e dalle loro evoluzioni con cancelli (LSTM e GRU).
Tuttavia, queste architetture presentavano due limiti strutturali insormontabili:
- Collo di Bottiglia Sequenziale: L'elaborazione del token $t$ richiedeva obbligatoriamente il completamento dello stato nascosto al tempo $t-1$. Questo impediva la parallelizzazione massiva sull'hardware GPU.
- Perdita di Memoria a Lungo Raggio: Nonostante le celle di memoria delle LSTM, l'informazione compressa lungo centinaia di passaggi temporali tendeva a sbiadire (Vanishing Gradient), rendendo impossibile collegare concetti distanti nel testo.
Nel celebre articolo scientifico "Attention Is All You Need" (Vaswani et al.), i ricercatori di Google introdussero i Transformer: un'architettura che elimina completamente la ricorrenza, elaborando l'intera sequenza di token in parallelo tramite il meccanismo di Auto-Attenzione (Self-Attention).
Il Workflow End-to-End di un Transformer
L'elaborazione di un testo all'interno di un Transformer segue una pipeline rigorosa in 7 fasi:
[ Testo Grezzo ]
│
▼
[ 1. Tokenizzazione ] ──────────► Suddivisione in subword token (es. BPE)
│
▼
[ 2. Embedding Layer ] ─────────► Vettori densi nello spazio R^d
│
▼
[ 3. Positional Encoding ] ─────► Somma di frequenze sinusoidali PE(pos)
│
▼
[ 4. Multi-Head Attention ] ────► Calcolo parallelo di Q, K, V
│
▼
[ 5. Add & Norm (Residui) ] ────► Skip connection: x + Attention(x)
│
▼
[ 6. Feed-Forward Network ] ────► Trasformazione non lineare densa
│
▼
[ 7. Linear & Softmax Output ] ─► Distribuzione di probabilità sui token
Positional Encoding (Codifica Posizionale)
Poiché l'operazione di attenzione elabora tutti i token contemporaneamente, l'architettura è intrinsecamente invariante rispetto all'ordine delle parole (tratterebbe la frase "il cane morde l'uomo" esattamente come "l'uomo morde il cane").
Per reintrodurre l'ordine sequenziale, viene sommato all'embedding di ciascun token un vettore posizionale generato tramite funzioni sinusoidali a frequenze scalari:
$$PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right)$$
$$PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right)$$
Dove $pos$ è la posizione temporale del token nella frase e $i$ è l'indice della dimensione lungo lo spazio di embedding $d_{\text{model}}$.
La Formulazione Matematica della Scaled Dot-Product Attention
Il cuore computazionale del Transformer è l'operazione di attenzione scalata. A partire dalla matrice di rappresentazione dei token $X \in \mathbb{R}^{T \times d_{\text{model}}}$, il modello calcola tre proiezioni lineari mediante matrici di peso addestrabili $W_Q, W_K, W_V$:
- Query ($Q = X W_Q \in \mathbb{R}^{T \times d_k}$): Rappresenta ciò che ogni token sta cercando;
- Key ($K = X W_K \in \mathbb{R}^{T \times d_k}$): Rappresenta le etichette informative usate per valutare la rilevanza;
- Value ($V = X W_V \in \mathbb{R}^{T \times d_v}$): Rappresenta il contenuto informativo effettivo da aggregare.
$$\mathbf{\text{Attention}(Q, K, V) = \text{softmax}\left( \frac{Q K^T}{\sqrt{d_k}} \right) V}$$
Analisi dei Componenti della Formula
- $Q K^T$: Prodotto scalare che calcola la matrice quadrata di affinità grezza ($T \times T$) tra ogni coppia di token della frase;
- Divisione per $\sqrt{d_k}$: Essenziale per evitare che per grandi dimensioni $d_k$ il prodotto scalare cresca eccessivamente, spingendo la softmax verso zone con gradienti piatti;
- $\text{softmax}(\dots)$: Converte i punteggi di affinità in coefficienti di peso probabilistici sommati a $1$;
- Moltiplicazione per $V$: Calcola la combinazione lineare dei valori pesata per l'attenzione reciproca.
Multi-Head Attention (Attenzione Multi-Testa)
Anziché calcolare una singola attenzione globale, il modello proietta $Q, K, V$ in $h$ sottospazi differenti in parallelo (heads). Questo consente di catturare simultaneamente diverse relazioni semantiche, sintattiche e grammaticali a distanze differenti:
$$\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h) W^O$$
$$\text{head}_i = \text{Attention}(Q W_i^Q, K W_i^K, V W_i^V)$$
Le Tre Famiglie di Architetture Transformer
Dall'architettura originaria sono derivate tre varianti specializzate per compiti differenti:
1. Encoder-only (es. BERT, RoBERTa)
- Workflow: Input $\to$ Encoder Blocks $\to$ Rappresentazione Bidirezionale $\to$ Predizione.
- Caratteristiche: Ogni token ha visibilità completa su tutti i token a destra e sinistra.
- Ideale per: Classificazione testi, Named Entity Recognition (NER), Sentiment Analysis, ricerca semantica vettoriale.
2. Decoder-only (es. GPT-4, LLaMA, Mistral, Claude)
- Workflow: Input $\to$ Masked Causal Attention $\to$ Decoder Blocks $\to$ Next-Token Prediction.
- Caratteristiche: I token possono prestare attenzione esclusivamente ai token precedenti (mascheramento causale triangolare inferiore).
- Ideale per: Generazione di codice, Large Language Model conversazionali, ragionamento autoregressivo.
3. Encoder-Decoder (es. T5, BART)
- Workflow: Input $\to$ Encoder Bidirezionale $\to$ Cross-Attention $\to$ Decoder Autoregressivo $\to$ Sequenza Target.
- Ideale per: Traduzione automatica multilingue, riassunti astrattivi, compiti sequence-to-sequence generici.
Implementazione Minimale di Self-Attention in PyTorch
import torch
import torch.nn as nn
import math
class ScaledDotProductAttention(nn.Module):
def __init__(self, d_k):
super().__init__()
self.scale = 1.0 / math.sqrt(d_k)
def forward(self, Q, K, V, mask=None):
# Q, K, V: [batch_size, num_heads, seq_len, d_k]
scores = torch.matmul(Q, K.transpose(-2, -1)) * self.scale
if mask is not None:
# Applicazione maschera causale (-inf) per bloccare token futuri
scores = scores.masked_fill(mask == 0, -1e9)
attn_weights = torch.softmax(scores, dim=-1)
output = torch.matmul(attn_weights, V)
return output, attn_weights
# Verifica numerica
batch_size, seq_len, d_k = 2, 4, 64
Q = torch.randn(batch_size, 1, seq_len, d_k)
K = torch.randn(batch_size, 1, seq_len, d_k)
V = torch.randn(batch_size, 1, seq_len, d_k)
attention_layer = ScaledDotProductAttention(d_k)
out, weights = attention_layer(Q, K, V)
print(f"Dimensioni Output Attenzione: {out.shape}")
print(f"Dimensioni Matrice dei Pesi: {weights.shape}")
print(f"Somma pesi prima riga: {weights[0, 0, 0].sum().item():.4f}")
Conclusioni
I Transformer hanno ridefinito le frontiere dell'intelligenza artificiale moderna. Tuttavia, l'addestramento e l'adattamento di modelli con decine di miliardi di parametri pongono sfide di memoria formidabili.
Nel prossimo articolo esploreremo le tecniche di Parameter-Efficient Fine-Tuning (PEFT), dimostrando matematicamente come adattare modelli da 70 miliardi di parametri con LoRA, QLoRA e fino a soli 13 parametri con TinyLoRA.
FAQ
Perché le reti ricorrenti (RNN e LSTM) sono state soppiantate dai Transformer?
Le RNN elaborano il testo sequenzialmente, token dopo token, impedendo la parallelizzazione su GPU e soffrendo della perdita di memoria a lungo termine per sequenze estese (Vanishing Gradient). I Transformer elaborano tutti i token simultaneamente in parallelo tramite l'attenzione.
Cosa rappresentano Query (Q), Key (K) e Value (V) nell'attenzione?
Query (Q) rappresenta ciò che un token sta cercando nel contesto; Key (K) rappresenta l'etichetta o il profilo identificativo di ciascun token; Value (V) è il contenuto informativo effettivo che viene pesato e sommato in base all'affinità calcolata tra Query e Key.
Perché nella formula dell'attenzione si divide per la radice quadrata di d_k?
Perché per dimensioni vettoriali elevate, il prodotto scalare Q*K^T assume valori numerici molto grandi, spingendo la funzione Softmax in regioni asintotiche con gradienti infinitesimali (piatti). Il fattore di scala 1/sqrt(d_k) mantiene la varianza a 1, preservando gradienti stabili.
Qual è la differenza fondamentale tra BERT (Encoder-only) e GPT (Decoder-only)?
BERT usa l'attenzione bidirezionale completa (ogni parola può guardare sia a sinistra che a destra) ed è ideale per la comprensione e classificazione del testo. GPT usa l'attenzione causale mascherata (ogni parola può guardare solo a quelle precedenti) ed è progettato per la generazione autoregressiva del token successivo.
A cosa servono le connessioni residue (Residual Connections) e la Layer Normalization?
Le connessioni residue (skip connections: x + Sublayer(x)) consentono ai gradienti di propagarsi direttamente attraverso decine o centinaia di strati profondi senza degradarsi, mentre la Layer Normalization stabilizza la distribuzione statistica delle attivazioni.