Definizioni dei termini tecnici usati nel diario e nella cronaca. Ogni termine è linkabile — #nome-termine.
Meccanismo che permette al modello di "guardare" altri token nel testo mentre elabora quello corrente. Per ogni token, calcola quanto ogni altro token è rilevante (punteggio di attenzione) e combina le informazioni in proporzione a quel punteggio. Multi-head attention: il calcolo viene eseguito in parallelo su più "teste", ognuna con parametri propri.
Algoritmo di ottimizzazione usato per aggiornare i parametri del modello durante il training. Combina Adam (stima del gradiente con momenti del primo e secondo ordine) con weight decay disaccoppiato. I parametri vengono aggiornati nella direzione opposta al gradiente, scalata per la stima della varianza.
Formato floating point a 16 bit con 8 bit di esponente (stesso range di float32) e 7 bit di mantissa. Usato come mixed precision nel training via torch.autocast: il forward pass e la loss girano in BF16, i pesi master e i gradienti rimangono in float32. Risultato: ~1.5–2× speedup sul forward pass, ~50% meno memoria per le attivazioni, senza rischio di overflow (a differenza di FP16 che ha solo 5 bit di esponente e richiede GradScaler).
Utile su GPU CUDA con tensor core (es. RTX 4090). Su M2 MPS ignorato — MPS gestisce già mixed precision internamente. Si attiva con --bf16 in train.py.
Byte Pair Encoding — algoritmo per costruire un vocabolario di "pezzi di parola". Parte da caratteri singoli e unisce iterativamente le coppie più frequenti fino a raggiungere il vocabolario target. Il risultato è un set di token che bilancia copertura (parole rare → pezzi comuni) e compattezza (parole comuni → token unici).
Il progetto usa SentencePiece (SPM) come implementazione BPE, vocabolario 16.000 token addestrato su Wikipedia italiana.
Fenomeno per cui un modello neurale, addestrato sequenzialmente su task diversi, "dimentica" ciò che aveva appreso nei task precedenti. Le nuove ottimizzazioni aggiornano gli stessi pesi che codificavano la conoscenza precedente, sovrascrivendola. È il problema centrale del continual learning.
Con LoRA il rischio è ridotto: i pesi del modello base rimangono congelati, e solo i parametri dell'adapter vengono aggiornati. Il forgetting riguarda allora la conoscenza domain-specific accumulata nell'adapter nei task precedenti, non le capacità linguistiche di base. Strategie di mitigazione: replay buffer, EWC, adapter separati per task con merge progressivo.
Paradigma di training in cui un modello impara da un flusso sequenziale di dati o task, aggiornando i propri pesi man mano senza accesso all'intero dataset passato. L'obiettivo è acquisire nuova conoscenza senza perdere quella precedente (catastrophic forgetting) e senza dover ripartire ogni volta dall'inizio (efficienza computazionale).
Si distingue dal fine-tuning classico perché non presuppone un dataset statico e completo: i dati arrivano in ordine, spesso come stream, e ogni aggiornamento deve bilanciare plasticità (imparare il nuovo) e stabilità (mantenere il vecchio). Le strategie principali sono: replay buffer, EWC, architetture progressive (adapter separati per task), e meta-learning.
Sottoinsieme compatto di esempi che approssima statisticamente l'intero dataset. Nel continual learning, un coreset per ogni task passato preserva la diversità delle distribuzioni viste senza dover memorizzare tutti i dati storici. Un buon coreset non seleziona gli esempi più frequenti — seleziona quelli più informativi: esempi che coprono regioni diverse dello spazio degli input, casi limite, rappresentanti di ogni classe.
Selezione pratica: per ogni categoria/classe, prendi i K esempi con la distribuzione di confidenza più ampia (non solo i più confidenti — quelli rischiano di essere tutti uguali). Alternativa: campionamento k-means sui vettori di embedding, con K centroidi per task.
Risultato empirico di Hoffmann et al. (2022) che stima il rapporto ottimale tra numero di parametri e token di training. Formula approssimata: token = 20 × parametri. Per 45.9M parametri → 918M token. Superare questo rapporto (più dati) o stare sotto (più parametri) produce modelli sub-ottimali a parità di compute.
Tecnica in cui un run di training parte dai pesi già appresi da un run precedente (--resume), aggiungendo token al budget totale invece di ricominciare da zero. I token dei run precedenti e di quello corrente si sommano. È più efficiente di ripartire dall'inizializzazione casuale: il modello converge più in fretta perché i pesi sono già in una zona ragionevole dello spazio dei parametri. Run #5 → Run #6 segue questo schema.
Snapshot del modello (pesi + stato ottimizzatore + step corrente) salvato su disco durante il training. Permette di riprendere da dove si era fermati (--resume) e di distribuire il modello senza dover ri-addestrare. Il checkpoint migliore (miglior val loss) viene salvato separatamente da quello corrente.
Architettura transformer che usa solo la parte "decoder" (con attenzione causale — ogni token vede solo i token precedenti, non quelli successivi). È l'architettura di GPT, LLaMA, Mistral e di questo modello. Adatta per generazione di testo e completamento.
Sistema agente che analizza autonomamente la struttura di un dataset (colonne, tipi, valori mancanti, anomalie semantiche) e propone operazioni di pulizia e trasformazione prima che i dati vengano usati per l'analisi o il training. A differenza di un pipeline statico, il data preparation agent usa un LLM per inferire il significato semantico delle colonne — non solo il tipo tecnico — e adatta le trasformazioni al contesto specifico del dataset.
Il ciclo operativo è: analisi struttura → proposta operazioni → approvazione umana (HITL) → esecuzione → salvataggio nel playbook. Le operazioni approvate diventano strategie riutilizzabili: a priori (applicate automaticamente ad ogni nuovo file dello stesso tipo) o condizionali (applicate quando una precondizione sul dato è verificata). Separare la preparazione dall'analisi garantisce che il modello a valle lavori su dati puliti e coerenti, e che le decisioni di pulizia siano tracciate e reversibili.
Tecnica di regolarizzazione per il continual learning (Kirkpatrick et al., 2017). Identifica quali pesi del modello erano più importanti per i task precedenti — usando la matrice di Fisher come approssimazione della curvatura della loss — e li penalizza durante il nuovo fine-tuning: possono cambiare poco, come fossero "elastici". I pesi meno importanti per i task precedenti rimangono liberi di adattarsi al nuovo task.
La penalizzazione EWC si aggiunge alla loss normale: L_totale = L_nuovo + λ · Σ F_i · (θ_i − θ*_i)², dove F_i è l'importanza del peso i (da Fisher), θ*_i il suo valore dopo il task precedente, λ il coefficiente di regolarizzazione. Costo: calcolare la matrice di Fisher richiede un passaggio aggiuntivo sui dati del task precedente. Con LoRA, si applica solo sull'adapter — computazionalmente leggero.
Esempio rappresentativo selezionato da un task o dataset precedente e conservato nel replay buffer. A differenza di un campione casuale, un exemplar è scelto perché è massimamente informativo: copre una regione dello spazio degli input non rappresentata da altri exemplar già selezionati. L'obiettivo è che un piccolo insieme di exemplar sia sufficiente per "ricordare" la distribuzione di un task passato durante il fine-tuning su task nuovi.
Nel contesto del fine-tuning con feedback umano, gli exemplar corretti dall'umano hanno un valore superiore ai pseudo-label ad alta confidenza: sono etichettati in modo affidabile e spesso rappresentano casi difficili (outlier, ambiguità) che il modello da solo non avrebbe classificato correttamente.
Metodo di valutazione PPL su un intero file di testo usando finestre sovrapposte. Il corpus viene scorato con stride < max_seq_len: ogni finestra condivide parte del contesto con la precedente, così ogni token viene valutato con il massimo contesto disponibile. Ogni token è scorato esattamente una volta. La PPL totale aggrega correttamente come exp(Σ NLL / Σ token), non come media delle PPL per finestra (che è biased).
Differisce da estimate_loss() in train.py, che campiona batch casuali dalla split di validazione: quel valore ha varianza e dipende da quanti batch si campionano. L'eval con sliding window è deterministico e comparabile tra checkpoint diversi.
Vettore numerico (d_model = 512 elementi) che rappresenta un token. La tabella di embedding mappa ogni ID token nel vocabolario al suo vettore corrispondente. I vettori vengono appresi durante il training: token semanticamente simili tendono ad avere vettori vicini nello spazio.
Componente di ogni layer transformer che elabora ogni token individualmente, dopo che l'attenzione ha aggregato informazioni dalla sequenza. È una rete neurale fully-connected a due strati: il primo espande la dimensione da d_model a 4×d_model (512→2048 nel nostro modello), applica una funzione di attivazione non lineare (GELU), poi il secondo ricomprime a d_model. A differenza dell'attenzione, che mescola informazioni tra token, il FFN opera su ogni posizione in modo indipendente. L'intuizione comune è che l'attenzione "decide cosa guardare", il FFN "ragiona su quello che ha visto".
Tecnica che simula un batch grande eseguendo più forward/backward consecutivi prima di aggiornare i pesi. Con accum_steps=4 e batch_size=32, il batch effettivo è 128: ogni passo dell'ottimizzatore usa i gradienti di 128 sequenze invece di 32, con la stessa VRAM. La loss di ogni mini-batch va scalata di 1/accum_steps prima del backward — altrimenti i gradienti si sommerebbero N volte e l'aggiornamento sarebbe troppo grande.
Perché serve: batch più grandi producono stime del gradiente più stabili (meno rumore), migliorando la convergenza. Su GPU con VRAM limitata è l'alternativa al ridurre seq_len o d_model.
Formato binario per la distribuzione di modelli LLM, usato da llama.cpp. Contiene pesi, architettura e metadati in un unico file. Supporta vari livelli di quantizzazione (fp16, Q8_0, Q4_K_M…). Il modello Run #4 è distribuito come slm-run4.gguf (fp16) e slm-run4-q8_0.gguf (Q8_0).
Vettore che indica quanto e in quale direzione cambiare ogni parametro per ridurre la loss. Viene calcolato con backpropagation (regola della catena applicata all'intero grafo computazionale). L'ottimizzatore usa il gradiente per aggiornare i pesi.
Un singolo meccanismo di attenzione con le proprie matrici W_Q, W_K, W_V. Il modello usa 8 head in parallelo (multi-head attention): ognuna proietta i token in un sotto-spazio diverso di 64 dimensioni (512÷8) e impara a rilevare un tipo diverso di relazione tra token — accordi grammaticali, riferimenti pronominali, strutture sintattiche. I risultati vengono concatenati e riproiettati con una matrice W_O. La specializzazione di ogni head emerge dal training, non viene programmata.
Proprietà di un'operazione che, applicata più volte, produce sempre lo stesso risultato dell'applicazione singola. Nel contesto dei pipeline di data preparation, ogni trasformazione dovrebbe essere idempotente: eseguire pd.to_datetime(df['Data']) su una colonna già convertita non deve generare errori né alterare i dati.
L'idempotenza si implementa tramite precondizioni: prima di applicare una trasformazione, il sistema verifica se la condizione che la giustifica è ancora vera. Se la colonna è già in datetime, la trasformazione viene saltata. Questo rende i playbook rieseguibili senza effetti collaterali — proprietà essenziale quando lo stesso playbook viene applicato a file diversi dello stesso tipo nel corso del tempo.
I numeri che definiscono la struttura del modello e il processo di training, scelti prima dell'addestramento e mai modificati dalla backpropagation. Si distinguono dai parametri, che vengono appresi. Per questo modello: d_model=512 (dimensione embedding), n_heads=8 (teste di attenzione), n_layers=12 (layer transformer), seq_len=512 (finestra di contesto), vocab_size=16000, learning rate massimo 3×10⁻⁴. La scelta degli iperparametri bilancia capacità del modello, costo computazionale e hardware disponibile.
Misura di quanto il modello sbaglia le sue previsioni. In language modeling, è la cross-entropy tra la distribuzione prevista e il token corretto. Training loss: calcolata sui dati di training (tende a scendere). Val loss: calcolata su dati non visti — misura la generalizzazione, quella che conta.
Unità funzionale completa del transformer, composta da multi-head attention e feed-forward network, ognuna preceduta da una layer norm e seguita da una connessione residuale. Prende in ingresso una sequenza di vettori e produce una sequenza trasformata della stessa forma. Il modello impila 12 layer in sequenza: i layer bassi tendono a catturare pattern locali (morfologia, strutture di frase brevi), i layer alti relazioni più astratte e a lungo raggio. Questa specializzazione emerge dal training.
Tecnica di fine-tuning efficiente (Hu et al., 2021). Invece di aggiornare tutti i parametri del modello (costoso, rischio di forgetting), aggiunge due matrici a basso rango A ∈ ℝ^(d×r) e B ∈ ℝ^(r×k) a ogni layer scelto. Durante il fine-tuning solo A e B vengono aggiornate; i pesi originali W rimangono congelati. L'output è W·x + B·A·x, con r ≪ min(d,k). Parametri tipici: r=8–64, alpha=16–128. Risultato: adapter da 1–50 MB per task di specializzazione, contro 4–40 GB per il modello base.
LoRA nel continual learning: il congelamento dei pesi base è un vantaggio strutturale — le capacità linguistiche generali non vengono mai toccate. Il catastrophic forgetting riguarda solo l'adapter, che è piccolo. Questo rende possibile mantenere adapter separati per task diversi e combinarli (LoRA merging). In un loop sequenziale, ogni ciclo di fine-tuning aggiorna lo stesso adapter usando un replay buffer per bilanciare la conoscenza dei task precedenti con quella del task nuovo.
QLoRA: variante che carica il modello base in quantizzazione a 4-bit (NF4) e addestra l'adapter in float16. Riduce il requisito di VRAM di ~4×, rendendo il fine-tuning su 7–13B modelli fattibile su GPU consumer.
Backend GPU per PyTorch su Mac Apple Silicon (M1/M2/M3). Usa il chip Neural Engine e GPU integrata del SoC. Circa 10–15× più lento di un RTX 4090 per il training — ma disponibile localmente, a costo zero, senza latenza di rete.
Strategia di campionamento che seleziona il minimo insieme di token la cui probabilità cumulata supera una soglia p (tipicamente 0.9). A differenza di top-k (che tiene un numero fisso di candidati), top-p si adatta alla situazione: quando la distribuzione è concentrata (il modello è sicuro) tiene pochi token; quando è piatta (incerto) ne include di più. Il vantaggio è che non viene mai campionata la "coda lunga" di token improbabili.
Con p = 0.9 e distribuzione [0.4, 0.3, 0.2, 0.05, 0.05, ...]: il nucleo è {A, B, C} che insieme coprono 0.9. D e seguenti vengono esclusi dal campionamento.
numpy int16Tipo di dato usato per salvare i token in cache. int16 copre valori −32.768 a +32.767 — sufficiente per un vocabolario di 16.000 token (ID 0–15.999). Occupa 2 byte per token contro gli 8 di torch.long (int64). Il cast a long avviene solo nel batch, riducendo il picco di RAM da 12 GB a 3 GB per corpus da 8 GB.
Esponenziale della val loss: PPL = e^(val_loss). Misura intuitiva di quanto il modello è "sorpreso" dal testo. Un modello con PPL 36 assegna in media a ogni token una probabilità equivalente a scegliere tra 36 opzioni equiprobabili. Lower is better. Run #4: PPL ~36, Run #3: PPL ~59.
Come quality scorer: si usa la perplexity del checkpoint Run #3 per valutare se un documento è "italiano enciclopedico". Alta PPL = testo insolito rispetto a Wikipedia → potenziale rumore.
Etichetta generata automaticamente dal modello stesso su dati non etichettati, usata come se fosse ground truth per il training. Il modello assegna una classe a un input con una certa confidenza; se la confidenza supera una soglia (es. 70–90%), l'etichetta viene accettata come pseudo-label e inserita nel dataset di training.
Il rischio principale è l'error propagation: se il modello sbaglia con alta confidenza, l'errore viene rinforzato nei cicli successivi. La qualità dei pseudo-label dipende dalla capacità del modello base e dalla soglia scelta. Una soglia alta (95%+) produce pochi esempi ma affidabili; una soglia bassa (60%) produce molti esempi ma rumorosi. In un loop con replay buffer, i pseudo-label ad alta confidenza alimentano l'apprendimento automatico; i casi sotto soglia vengono accantonati per revisione umana (HITL) e, una volta corretti, diventano exemplar di qualità superiore.
Registro persistente delle strategie di trasformazione apprese e approvate da un data preparation agent. Ogni entry descrive un'operazione (es. conversione di tipo, rimozione di colonne ridondanti, filtraggio di righe nulle), la sua precondizione, la motivazione e lo stato di approvazione. Il playbook è il meccanismo di memoria del sistema: permette di rieseguire in autonomia le stesse trasformazioni su nuovi file dello stesso tipo, senza ripetere l'analisi.
Le strategie nel playbook si dividono in due classi. A priori: applicate automaticamente a ogni nuovo file, senza condizioni — sono state giudicate invarianti del dataset (es. la colonna Data_Operazione contiene sempre tipi misti in questo formato). Condizionali: applicate solo quando una precondizione è verificata sul dato corrente (es. "se una colonna di tipo object ha nome che contiene 'data', convertila in datetime"). Le strategie condizionali generalizzano a dataset non ancora visti.
La struttura minima di un'entry: { id, tipo, colonna_target, codice, precondizione, motivazione, approvato_da, approvato_il }. L'idempotenza è garantita dalla precondizione: se la trasformazione è già stata applicata, la precondizione è falsa e l'operazione viene saltata.
Meccanismo di rilevamento del catastrophic forgetting durante il fine-tuning. Prima del training SFT, si calcola la perplexity del modello su un campione fisso del corpus originale (il "probe") come baseline. Dopo ogni checkpoint, la PPL viene ricalcolata sullo stesso campione. Se il rapporto PPL_attuale / PPL_baseline supera una soglia (default 1.15, cioè +15%), viene emesso un avviso: il modello sta perdendo fluenza sul linguaggio generale mentre impara il task specifico.
Il probe non ferma il training — segnala. In Phase 09 (SFT intent recognition): baseline 27.54, picco a epoch 4 di ×1.156 (31.8 PPL, avviso emesso), poi recovery a ×1.120 a epoch 5. Il forgetting era lieve e temporaneo — tipico con dataset piccoli e learning rate conservativo.
L'insieme completo dei numeri che compongono il modello — tutto ciò che viene appreso durante il training tramite backpropagation. Ogni matrice (embedding, W_Q, W_K, W_V, W_O, FFN W1, FFN W2, layer norm) è fatta di numeri float: la loro somma totale è il "numero di parametri" del modello. Per questo modello: 45.997.056. All'inizio del training sono valori casuali. Dopo milioni di step, codificano tutta la conoscenza acquisita — distribuita su ogni singolo numero, non localizzata in nessun posto specifico. Il file best.pt è un dizionario di matrici con i valori appresi.
Il percorso completo dal corpus grezzo al training. Step 1: il tokenizer converte il testo in interi (token ID) e li salva in un file .pt — da questo momento il testo originale non serve più. Step 2: l'embedding lookup trasforma ogni intero in un vettore float — unico punto di contatto tra il mondo degli interi e quello vettoriale. Step 3: i layer transformer elaborano la sequenza di vettori via attenzione e FFN, senza mai riferirsi al testo. Step 4: l'output è una distribuzione di probabilità sul token successivo, confrontata con il token reale dal .pt via cross-entropy loss.
Variante dell'architettura transformer dove la LayerNormalization viene applicata prima dell'attenzione e del feed-forward (invece che dopo). Stabilizza il training, in particolare nelle architetture profonde. Usata in LLaMA, GPT-NeoX e in questo modello.
Memoria di esempi passati usata nel continual learning per contrastare il catastrophic forgetting. Ad ogni ciclo di fine-tuning, il batch di training include sia esempi del task corrente sia esempi campionati dal buffer. Il modello "rivede" periodicamente la conoscenza passata, impedendo ai nuovi gradienti di sovrascriverla completamente.
Dimensione e selezione: il buffer non può contenere tutti i dati passati (altrimenti il fine-tuning sarebbe costoso quanto ripartire da zero). Si mantiene un sottoinsieme — gli exemplar — selezionati per massimizzare la copertura della distribuzione passata con il minimo numero di esempi. Strategie di selezione: casualità uniforme (semplice, rischio squilibrio), campionamento bilanciato per classe (preserva proporzioni), reservoir sampling (garantisce rappresentatività statistica senza accesso all'intero storico), coreset selection (massimizza la diversità).
Mixing ratio: la proporzione tra esempi nuovi e esempi da buffer in ogni batch. Tipicamente 70% nuovo / 30% buffer. Con un ratio troppo alto verso il buffer, il modello non converge sui nuovi pattern; troppo basso, il forgetting riprende. Il valore ottimale dipende dal grado di differenza tra task successivi.
Warm-up period: nei primi N task/shard il buffer è troppo piccolo per essere utile. Il fine-tuning automatico conviene iniziarlo solo dopo che il buffer ha raggiunto una dimensione minima (es. ≥ 100 exemplar, ≥ 3 task distinti). Prima di allora si accumula solo conoscenza esplicita senza aggiornare i pesi.
Meccanismo che penalizza i token già presenti nel contesto corrente durante la generazione. Se un token ha logit positivo, viene diviso per il valore della penalità (abbassato); se negativo, viene moltiplicato (abbassato ulteriormente). Con penalty = 1.3, un token già generato diventa ~30% meno probabile al passo successivo. Con penalty = 1.0 l'effetto è nullo.
Risolve il problema dei loop di ripetizione — fenomeno frequente nei modelli senza questa correzione, visibile nel benchmark Run #7 dove "Foggia" veniva ripetuto 20+ volte nella generazione sul prompt Puglia.
Codifica di posizione che ruota i vettori di query e key nell'attenzione in modo che il loro prodotto scalare dipenda dalla distanza relativa tra i token (non dalla posizione assoluta). Nessun parametro aggiuntivo. Generalizza meglio a sequenze lunghe rispetto al PE sinusoidale. Standard in LLaMA, Mistral, Gemma. Introdotto in Run #4: val loss 3.59 vs 4.08 di Run #3.
Fase di addestramento successiva al pre-training, su coppie prompt/completamento curate. Il modello impara a seguire istruzioni invece di completare testo arbitrario. La loss viene calcolata solo sulla parte "risposta" (masked loss): i token del prompt ricevono target=-100, ignorato da F.cross_entropy. Il gradiente si propaga solo sulle risposte, non sulle domande.
SFT vs LoRA: SFT è una strategia di addestramento (formato dati + obiettivo); LoRA è un metodo di ottimizzazione (quali parametri aggiornare). Sono ortogonali e si combinano. Full SFT aggiorna tutti i parametri — rischio catastrophic forgetting con dataset piccoli. SFT+LoRA aggiorna solo ~393k parametri (adapter) su 45.9M frozen — forgetting quasi nullo.
Run Phase 09 (intent recognition): 140 coppie, 5 epoche, lr=2e-5. Train loss: 2.77 → 0.38. Checkpoint: checkpoints/sft_intent_v1.pt. Il base model generava narrativa libera; dopo SFT produce JSON strutturato con intent e parametri estratti.
Parametro che controlla la "nitidezza" della distribuzione di probabilità prima del campionamento. I logit vengono divisi per la temperatura T prima del softmax: T < 1 concentra la distribuzione (output più prevedibili e coerenti), T > 1 la appiattisce (output più creativi e variabili). Con T = 0 si ottiene il greedy decoding (sempre il token più probabile). Il valore T = 0.8 è il default usato in questo progetto.
Array multidimensionale di numeri, struttura dati fondamentale di PyTorch. Il corpus tokenizzato è un tensor 1D di ID interi. I batch di training sono tensor 2D (batch_size × seq_len). I pesi del modello sono tensori 2D e 3D. Le operazioni sui tensori vengono eseguite in parallelo su GPU/MPS.
Unità atomica di testo che il modello elabora. Può essere un carattere (tokenizer char-level), una parte di parola (BPE) o una parola intera. Il vocabolario BPE del progetto ha 16.000 token: la parola "addestramento" potrebbe diventare ["addestr", "amento"], "il" rimane ["il"].
Numero totale di token consumati durante il training, calcolato come batch_size × seq_len × steps. Determina quanto testo il modello "vede" complessivamente — non quanti dati hai su disco, ma quanti ne passano realmente attraverso i pesi durante gli aggiornamenti.
Per Run #5: 8 × 512 × 56.000 = 229M token (25% del target Chinchilla). Per Run #6: aggiunge 32 × 512 × 56.000 = 918M token partendo dal checkpoint di Run #5. Budget cumulativo finale: ~1.15B token ≈ 1.25× Chinchilla.
Porzione del corpus tenuta separata dal training per misurare la generalizzazione. Tipicamente il 10% finale del corpus. Il modello non vede mai questi dati durante il training — la loss su questi dati è l'indicatore più onesto della qualità.
Tecnica che condivide i pesi tra la tabella di embedding (input) e la testa di proiezione finale (output). Invece di due matrici separate da vocab_size × d_model, si usa la stessa matrice per entrambe. Riduce i parametri del modello di ~16M e spesso migliora la qualità — il modello usa la stessa rappresentazione per capire e produrre un token.