Programma
Immagina di provare a leggere un romanzo in cui ogni parola sulla pagina è mescolata in un ordine casuale. Anche se capisci ogni singola parola, la trama si perde completamente perché l’ordine delle parole determina il significato. Quando gli ingegneri hanno iniziato a progettare i Large Language Models (LLM), hanno incontrato un ostacolo simile. Come insegni a un modello a comprendere la sequenza delle parole quando il suo meccanismo principale elabora tutto simultaneamente?
Qui entra in gioco la codifica posizionale. In questo articolo esploreremo il funzionamento interno della codifica posizionale e come conferisce ai transformer il senso dell’ordine. Vedremo la sua evoluzione dalle formule sinusoidali originali agli embedding rotazionali moderni e come implementarla nel tuo prossimo progetto di machine learning. Se sei alle prime armi con l’architettura sottostante, ti consiglio di iniziare con la nostra guida su come funzionano i transformer.
Che cos’è la codifica posizionale?
La codifica posizionale è una tecnica che consente alle reti neurali di comprendere l’ordine sequenziale dei dati in input. Agisce come un set di coordinate che rappresenta la posizione relativa o assoluta di un token ed è fuso con la rappresentazione standard dei dati.
Prima che il testo entri in una rete neurale, le parole vengono convertite in forma numerica continua chiamata embedding. Tuttavia, gli embedding standard catturano solo il significato semantico: non dicono nulla sulla posizione di una parola in un dato testo. Puoi imparare esattamente come funziona questo processo seguendo il nostro corso Introduction to Embeddings with the OpenAI API.
Una codifica posizionale è un ulteriore strato matematico aggiunto direttamente a questi embedding di token. Combinando la rappresentazione semantica con un timbro posizionale, il modello transformer può distinguere tra parole identiche che compaiono in diverse parti di una frase.
Il problema dell’invarianza per permutazione
I dati sequenziali dipendono fortemente dall’ordine. In linguaggio naturale, la frase "the dog bit the man" ha un significato completamente diverso da "the man bit the dog".

Storicamente, le Recurrent Neural Networks (RNN) e le Long Short-Term Memory (LSTM) gestivano questo aspetto in modo intrinseco. Elaboravano i token in sequenza, il che significa che la rete ingeriva matematicamente la seconda parola solo dopo aver terminato la prima. Allo stesso modo, le Convolutional Neural Networks (CNN) elaborano i dati utilizzando finestre scorrevoli locali che catturano la disposizione spaziale di pixel o parole adiacenti.
I transformer abbandonano completamente l’elaborazione sequenziale. Elaborano tutti i token in parallelo. Il motore centrale di un transformer è il meccanismo di self-attention, che calcola i punteggi di relazione a coppie tra ogni singolo token nella sequenza esattamente nello stesso momento. Matematicamente, la self-attention è invariante per permutazione. Se mescoli la sequenza in input, il meccanismo di self-attention produrrà gli stessi identici punteggi di attenzione per le coppie di parole.
Senza un meccanismo per preservare l’ordine, il modello subisce una perdita totale di informazioni sequenziali. Il significato semantico collassa in un sacco di parole non ordinato. La codifica posizionale risolve il problema dell’invarianza per permutazione alterando forzatamente i vettori di input affinché il meccanismo di self-attention registri in modo diverso i token alla posizione 1 rispetto ai token alla posizione 10.
Come funziona la codifica posizionale?
La codifica posizionale opera modificando matematicamente i vettori dei token in input prima che raggiungano i layer di self-attention. Questo garantisce che il modello calcoli le relazioni basandosi sia sul significato che sulla posizione.
Costruiamo un po’ di intuizione su cosa significhi. Immagina gli embedding standard dei token come badge con il nome a una conferenza. Il badge ti dice chi è la persona, ma dove si trova alla conferenza non cambia chi è o le sue relazioni con gli altri. La codifica posizionale è come aggiungere un numero di posto a quel badge. Quando li combini, sai sia chi è la persona sia dove è seduta. Questo aggiunge contesto alle possibili interazioni che questa persona potrebbe avere alla conferenza.
In un transformer, questa combinazione viene in genere ottenuta tramite una semplice addizione elemento per elemento. Il modello prende il vettore di embedding semantico di una parola e aggiunge un vettore di codifica posizionale della stessa identica dimensione. Il vettore risultante contiene una modulazione sottile che i layer successivi imparano a interpretare come coordinate spaziali.
Esempio di calcolo
Vediamo un esempio semplificato. Immagina di avere uno spazio di embedding molto piccolo con dimensione 4. Vogliamo elaborare la parola "DataCamp" in posizione 0 nella nostra sequenza.
- Embedding semantico: La rete neurale recupera l’embedding per "DataCamp", che potrebbe essere [0.51, -0.22, 0.88, 0.14].
- Codifica posizionale: La formula posizionale genera un vettore di coordinate per la posizione 0. Per questo esempio, supponiamo che calcoli [0.00, 1.00, 0.00, 1.00].
- Combinazione: Sommiamo i due vettori elemento per elemento.
- Input finale: La forward pass riceve [0.51, 0.78, 0.88, 1.14].
Anche se lo stesso identico token "DataCamp" compare più avanti in posizione 5, il vettore di codifica posizionale sarà diverso. Di conseguenza, il vettore di input finale apparirà completamente diverso al meccanismo di self-attention.

Codifica posizionale sinusoidale
L’articolo originale "Attention Is All You Need" ha introdotto un metodo brillante per generare vettori posizionali utilizzando la trigonometria di base. Questo approccio non richiede pesi di machine learning e si basa interamente su funzioni matematiche fisse.
Fondamenti matematici
La codifica posizionale sinusoidale utilizza funzioni seno e coseno a frequenze diverse per codificare le informazioni di posizione. La formula originale stabilisce che, data una posizione (pos) e un indice di dimensione specifico (i) all’interno del vettore di embedding, la codifica si calcola come segue:
-
Per le dimensioni pari (
2i):PE(pos, 2i) = sin(pos / 10000^(2i/dmodel)) -
Per le dimensioni dispari (
2i+1):PE(pos, 2i+1) = cos(pos / 10000^(2i/dmodel))
In questa formula, dmodel è la dimensione totale del vettore di embedding. Man mano che ti muovi lungo le dimensioni del vettore dall’indice 0 fino a dmodel, la lunghezza d’onda delle funzioni sinusoidali aumenta geometricamente.
Vantaggi e proprietà
Questa progressione geometrica delle frequenze offre diversi vantaggi distinti.
- Gli output di seno e coseno sono rigorosamente limitati tra -1 e 1. Questa natura limitata assicura che le codifiche posizionali non sovrastino numericamente gli embedding semantici.
- Le funzioni sono periodiche. Grazie alle formule di addizione trigonometriche, una trasformazione lineare può rappresentare facilmente la codifica posizionale di una posizione futura (
pos + k) come funzione della posizione attuale (pos). Questa proprietà consente naturalmente al modello di apprendere la codifica della posizione relativa. - La codifica sinusoidale utilizza parametri fissi. Non richiede pesi apprendibili, riducendo notevolmente l’overhead di memoria. Poiché opera su una funzione matematica continua, il modello possiede una capacità teorica di estrapolazione, il che significa che può mappare coordinate posizionali per sequenze più lunghe di quelle viste durante l’addestramento.
Visualizzazione
Per comprendere la codifica sinusoidale, può essere utile visualizzarla come una heatmap.

L’asse x della visualizzazione rappresenta la dimensione dell’embedding, mentre l’asse y indica la posizione del token.
Le dimensioni inferiori a sinistra oscillano rapidamente tra valori negativi e positivi, il che consente di distinguere posizioni di token vicine. Con l’aumentare dell’indice di dimensione, la lunghezza d’onda si allunga e la codifica cambia più gradualmente. Queste dimensioni catturano differenze posizionali su distanze maggiori.
Per le 50 posizioni mostrate qui, molte dimensioni più alte appaiono come strisce verticali quasi uniformi. Ciò accade perché le loro lunghezze d’onda sono così lunghe che i valori del seno rimangono vicini a 0 e quelli del coseno vicini a 1 all’interno di questa breve sequenza, non 0 e 1 rispettivamente. Quindi le strisce alternate riflettono dimensioni adiacenti seno–coseno, non una semplice codifica binaria. Su una sequenza più lunga, anche queste dimensioni inizierebbero a variare in modo evidente.
La conclusione è che le diverse frequenze forniscono al modello informazioni posizionali su più scale: le dimensioni che cambiano rapidamente catturano differenze fini tra token vicini, mentre quelle che cambiano lentamente tracciano la posizione più ampia all’interno di sequenze più lunghe.
Codifica posizionale appresa
Sebbene le formule matematiche fisse siano eleganti, le architetture moderne di deep learning spesso si affidano ai dati per apprendere rappresentazioni ottimali. Gli embedding posizionali appresi spostano completamente sul training l’onere della disposizione.
Concetto e implementazione
Invece di codificare rigidamente i valori posizionali con funzioni seno e coseno, gli embedding posizionali appresi trattano le coordinate di posizione come normali parametri apprendibili.
Il modello inizializza una matrice di embedding completamente vuota in cui ogni riga corrisponde a una posizione specifica della sequenza. Durante il normale ciclo di training con backpropagation, la rete aggiorna questi pesi posizionali insieme agli embedding semantici dei token per minimizzare la loss function complessiva.
Vantaggi comparativi
Il principale vantaggio degli embedding posizionali appresi è l’estrema flessibilità. Hanno piena libertà di apprendere le rappresentazioni posizionali esatte che funzionano meglio per uno specifico dataset. Architetture come BERT e GPT-2 hanno reso popolare questo approccio grazie all’elevata adattabilità e alle ottime prestazioni sui task a valle.
Limitazioni e sfide
La limitazione più significativa degli embedding posizionali appresi è un confine rigido sulla lunghezza della sequenza. Se un modello è addestrato con un massimo di 2.048 vettori di posizione appresi, fisicamente non può elaborare un documento di 2.049 token.
Questa restrizione limita severamente l’estrapolazione in lunghezza e spesso richiede un costoso riaddestramento per estendere la finestra di contesto.
Codifica posizionale relativa
Con l’evolversi dei modelli per gestire documenti più lunghi, gli ingegneri si sono resi conto che la posizione assoluta di una parola spesso conta meno della sua distanza relativa da altre parole.
Passaggio concettuale alle posizioni relative
Considera la frase "the rapid advancement of AI." La relazione grammaticale tra "advancement" e "AI" rimane identica sia che la frase appaia all’inizio di un documento sia alla fine. La codifica posizionale relativa abbandona le coordinate della griglia assoluta. Invece, si concentra interamente sugli scarti di distanza tra i token che interagiscono.
Implementazione nei meccanismi di attenzione
Per implementare le codifiche relative, gli ingegneri modificano direttamente il calcolo dei punteggi di attenzione piuttosto che alterare gli embedding di input all’inizio della rete.
Nel calcolo del punteggio di attenzione tra una matrice "query" e una matrice "key", l’operazione include un termine di bias aggiuntivo appreso che rappresenta la distanza relativa. Questa modifica garantisce l’invarianza rispetto allo spostamento nel testo. Per approfondire il funzionamento di queste matrici, leggi la nostra guida sul meccanismo di attenzione negli LLM.
Compromessi pratici
Questo approccio offre una comprensione contestuale molto accurata ma introduce un notevole overhead computazionale. Calcolare matrici di distanza relative uniche per ogni singola testa di attenzione aumenta drasticamente il consumo di memoria. Complica anche i meccanismi di caching interni utilizzati per velocizzare la generazione di testo.
Informazioni posizionali assolute vs relative
La scelta tra codifica assoluta e relativa dipende dallo specifico task.
- La codifica assoluta funziona benissimo quando il layout spaziale è rigido e si dà priorità all’esecuzione rapida.
- La codifica relativa è di gran lunga superiore per l’elaborazione di linguaggio naturale di lunga durata, dove la struttura grammaticale dipende interamente dalle distanze di contesto locale piuttosto che dalle coordinate assolute del documento.
Rotary Position Embedding (RoPE)
Nella continua ricerca di perfezionare le architetture transformer, i ricercatori hanno introdotto i Rotary Position Embedding (RoPE). Combinano le migliori proprietà delle codifiche posizionali assolute e relative e sono rapidamente diventati uno standard del settore.
Approccio innovativo
RoPE unifica posizionamento assoluto e distanze relative usando trasformazioni rotazionali. Invece di aggiungere un vettore agli embedding o pesanti bias ai punteggi di attenzione, RoPE mappa il vettore di embedding su un piano complesso e lo ruota di un angolo specifico. L’ampiezza di questo angolo è determinata esclusivamente dalla posizione assoluta del token nella sequenza.

Intuizioni matematiche
In uno spazio 2D, la rotazione si applica utilizzando una matrice di rotazione 2D standard. Per dimensioni superiori, RoPE raggruppa semplicemente le dimensioni dell’embedding in coppie e applica rotazioni 2D uniche a ciascun blocco in base all’indice di posizione assoluta.
Grazie alle proprietà geometriche delle matrici di rotazione, il prodotto scalare di un vettore query ruotato e di un vettore key ruotato finisce per dipendere solo dall’angolo relativo tra di loro. Così, RoPE utilizza una mappatura della posizione assoluta per codificare naturalmente la distanza relativa tra i token.
RoPE vs codifica sinusoidale
Come mostra il grafico sopra, la codifica sinusoidale cambia la magnitudine e la direzione del vettore originale. RoPE invece preserva l’informazione di magnitudine e ha bisogno solo dell’angolo tra due posizioni diverse per comprenderne la distanza relativa.
Attention With Linear Biases (ALiBi)
Mentre RoPE si basa su una matematica rotazionale complessa, un’altra tecnica chiamata Attention with Linear Biases (ALiBi) adotta un approccio completamente diverso.
Semplicità ed efficienza
ALiBi scarta completamente l’idea di aggiungere informazioni posizionali agli embedding iniziali dei token. Gli embedding delle parole entrano nel transformer del tutto intatti.
Invece, ALiBi interviene all’ultimissimo passaggio del calcolo dell’attenzione. Subito prima che i logit di attenzione passino attraverso la funzione softmax, ALiBi sottrae una penalità statica proporzionale alla distanza tra i due token. Più due parole sono lontane, maggiore è la penalità sottratta dal loro punteggio di attenzione.
Prestazioni
Questo metodo è molto semplice da implementare e molto efficiente. Il suo vantaggio principale è l’estrema efficacia nei task di estrapolazione della lunghezza. Un modello addestrato con ALiBi su sequenze di 1.024 token può facilmente generare testo coerente su sequenze di lunghezza doppia senza andare in crisi.
Per chi vuole esplorare altre tecniche avanzate utilizzate per la generazione di testo veloce e i task di inferenza, consulta la nostra guida sulla decodifica speculativa.
Quando usare quale codifica posizionale
Parti da ciò che stai costruendo e poi scegli il metodo adatto — a volte è uno solo, a volte sono più di uno.
- Vuoi una baseline semplice e senza parametri: Sinusoidale (formule fisse, niente da addestrare).
- La lunghezza della sequenza è fissa e vuoi le massime prestazioni su uno specifico dataset: Appresa.
- Devi gestire sequenze più lunghe di quelle su cui ti sei addestrato: RoPE è la scelta più forte tra le tecniche che possono estrapolare.
- La grammatica dipende dalla distanza tra i token, non dalla loro posizione assoluta: Relativa o RoPE.
- Stai costruendo un LLM moderno per uso generale: RoPE.
- L’estrapolazione della lunghezza è la tua priorità assoluta e vuoi l’implementazione più semplice: ALiBi.
- Vuoi i benefici delle posizioni relative senza l’overhead di memoria e caching: RoPE (le codifiche relative danno il beneficio ma sono più costose).
Implementazione pratica e considerazioni architetturali
Colmare il divario tra teoria e pratica richiede di capire come integrare le codifiche posizionali in codebase reali e gestire i limiti architetturali.
Implementare la codifica posizionale nei transformer
Per aggiungere codifiche posizionali a un transformer in framework come PyTorch, gli sviluppatori creano tipicamente un modulo dedicato. Questo modulo genera la matrice di codifica una volta e la registra come buffer in modo che non si aggiorni accidentalmente durante la backpropagation.
Di seguito trovi un’implementazione pratica standard di una forward pass che incorpora codifiche sinusoidali. Le codifiche sono calcolate una volta dalle formule seno e coseno e non cambiano mai durante l’addestramento, motivo per cui sono archiviate in un buffer invece che come parametri apprendibili (e perché non aggiungono nulla al costo di training).
import torch
import torch.nn as nn
import math
class PositionalEncoding(nn.Module):
def __init__(self, d_model: int, max_len: int = 5000):
super().__init__()
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
# Calculate the division term for frequencies
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
# Apply sine to even indices and cosine to odd indices
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
# Register as a buffer
self.register_buffer('pe', pe)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# Add positional encoding directly to the input embeddings
seq_len = x.size(1)
x = x + self.pe[:, :seq_len, :]
return x
In __init__, il modulo pre-calcola la tabella di codifica fino a max_len posizioni: position è una colonna di indici (0, 1, 2, …) e div_term sono le frequenze, che equivalgono a 1 / 10000^(2i/d_model), quindi le dimensioni più basse hanno onde veloci e quelle più alte onde lente.
Applicare sin alle dimensioni pari (0::2) e cos alle dispari (1::2) riempie la tabella. Poi forward fa l’unico lavoro a runtime: taglia la tabella alla lunghezza di sequenza dell’input e la aggiunge agli embedding dei token elemento per elemento. Nota che il modulo assume una forma batch-first [batch, seq_len, d_model], motivo per cui forward affetta sulla dimensione 1.
Bias di posizione e fenomeno lost-in-the-middle
Una conseguenza indesiderata della mappatura di sequenze lunghe è il bias di posizione. Questo si manifesta spesso come fenomeno "lost-in-the-middle". Quando elaborano documenti enormi, i modelli linguistici tendono a ricordare molto meglio i fatti dell’inizio o della fine di un prompt rispetto a quelli nel mezzo. Può sembrare familiare, dato che la memoria umana funziona in modo simile (almeno per me; non dirmi che sono l’unico a ricordare meglio l’inizio e la fine dei libri rispetto al resto!).
La teoria è che ciò accada perché il meccanismo di attenzione viene sopraffatto dal contesto irrilevante e si ancora naturalmente ai primi token (che impostano l’istruzione) e agli ultimi token (che sono i più recenti in memoria). Per mitigare questo bias, gli sviluppatori ricorrono a strategie di chunking avanzate e a sistemi di recupero semantico.
Codifica posizionale per domini specializzati
I transformer non sono più limitati esclusivamente al testo. Il concetto di codifica posizionale si adatta rapidamente per gestire diversi tipi di dati in più domini.
Per i vision transformer, le imagini sono suddivise in griglie di patch. Una semplice codifica sequenziale 1D non riesce a catturare la prossimità spaziale in uno spazio 2D. Pertanto, i modelli di visione usano spesso codifiche posizionali apprese 2D che tengono conto sia delle coordinate X che Y della patch dell’immagine.
Esistono adattamenti simili per i modelli di serie temporali continue, in cui codifiche specializzate tracciano distanze temporali, stagionalità e timestamp.
Ulteriori ricerche sulla codifica posizionale
Con l’accelerazione della corsa verso finestre di contesto più ampie, il perfezionamento del modo in cui i modelli comprendono la posizione rimane un’area di ricerca nel machine learning estremamente attiva e critica.
Estrapolazione della lunghezza ed estensione del contesto
Gli utenti di oggi richiedono finestre di contesto enormi per elaborare intere codebase o serie di romanzi in una volta. Poiché addestrare modelli da zero su lunghezze di sequenza massicce è troppo costoso, i ricercatori si affidano a tecniche di estensione del contesto.
Metodi come l’interpolazione posizionale comprimono matematicamente le coordinate posizionali di una sequenza molto più lunga entro i limiti della lunghezza di training originale. Metodi adattivi come YaRN regolano dinamicamente la frequenza rotazionale dei parametri RoPE per estendere senza soluzione di continuità la comprensione della distanza da parte del modello.
Transformer senza codifica posizionale esplicita
Sorprendentemente, alcune ricerche suggeriscono che la codifica posizionale esplicita potrebbe non essere sempre strettamente necessaria. Nei modelli linguistici causali decoder-only, il mascheramento causale standard (un meccanismo che costringe i token a guardare solo all’indietro) trapela intrinsecamente informazioni sull’ordine temporale.
Ciò significa che potrebbe essere possibile apprendere implicitamente regole posizionali esclusivamente dal causal mask tramite una sintonizzazione strategica della temperatura e aggiustamenti architetturali.
Sfide e direzioni future
L’ultima frontiera evidenzia un persistente trade-off tra adattamento stretto (ottimizzare le prestazioni per una specifica lunghezza di sequenza) ed estrapolazione perfetta (consentire al modello di generalizzare all’infinito).
Le aree di ricerca emergenti sono fortemente focalizzate sulla codifica multimodale. Creare rappresentazioni posizionali universali che fondano coordinate video 3D con flussi di testo e audio è uno degli obiettivi per la prossima generazione di modelli di intelligenza artificiale.
Conclusione
La codifica posizionale colma il divario tra elaborazione parallela e comprensione sequenziale e ci consente di creare modelli che possono elaborare grandi quantità di dati in ordine. Abbiamo esplorato come gli embedding appresi e relativi offrano estrema flessibilità e come innovazioni moderne come RoPE e ALiBi ottimizzino sia l’eleganza matematica sia l’efficienza computazionale.
Man mano che le finestre di contesto si estendono da qualche migliaio di token a milioni, il semplice atto matematico di dire a una rete neurale esattamente dove si trovano le cose rimarrà al cuore della progettazione dei modelli.
Se vuoi andare più a fondo e fare pratica, ti consiglio di iscriverti al nostro skill track Developing Large Language Models.
Domande frequenti sulla codifica posizionale
Che cos’è la codifica posizionale nel machine learning?
La codifica posizionale è una tecnica matematica utilizzata per fornire alle reti neurali informazioni sull’ordine dei dati in una sequenza.
Perché i modelli transformer hanno bisogno della codifica posizionale?
A differenza delle vecchie Recurrent Neural Network che elaborano i dati passo dopo passo, i transformer elaborano tutti i dati simultaneamente usando un meccanismo di self-attention. Poiché la self-attention è naturalmente invariante per permutazione, tratta l’input come un sacco di parole non ordinato. La codifica posizionale lo risolve iniettando coordinate sequenziali direttamente nei dati prima che il modello li elabori.
Qual è la differenza tra codifica posizionale assoluta e relativa?
La codifica posizionale assoluta assegna a un token una coordinata fissa in base al suo esatto indice in una sequenza. La codifica posizionale relativa ignora la posizione esatta sulla griglia e invece calcola la distanza tra due token che interagiscono, concentrandosi esclusivamente sul loro scarto contestuale.
Che cos’è il Rotary Position Embedding (RoPE)?
RoPE è un metodo di codifica ampiamente utilizzato che mappa gli embedding dei token su un piano complesso e li ruota di un angolo determinato dalla loro posizione assoluta. Quando il modello calcola i punteggi di attenzione, la relazione tra due vettori ruotati dipende interamente dalla loro distanza relativa.
Cosa sono gli embedding posizionali appresi?
Invece di utilizzare formule matematiche fisse come seno e coseno, gli embedding posizionali appresi trattano le coordinate spaziali come pesi addestrabili. Il modello inizializza una matrice di posizioni vuota e aggiorna queste coordinate durante il training per apprendere rappresentazioni spaziali ottimali per uno specifico dataset.
Sono una data scientist con esperienza in analisi spaziale, machine learning e pipeline dei dati. Ho lavorato con GCP, Hadoop, Hive, Snowflake, Airflow e altri processi di data science/engineering.


