1.2 Arquitectura Transformer i LLM Fundacionals¶
El paper que ho va canviar tot
"Attention Is All You Need" — Vaswani et al., Google Brain, 2017.
🏗️ L'Arquitectura Transformer¶
Paral·lelisme Total
Tots els tokens es processen simultàniament. Aprofita al màxim les GPUs modernes.
Self-Attention
Cada token pot "mirar" directament qualsevol altre token. Capta dependències globals.
Positional Encoding
Informació de posició explícita per cada token, ja que no hi ha recurrència.
🔬 Self-Attention: La Intuïció¶
La pregunta clau: "Quan proceso la paraula X, quines altres paraules del context necessito mirar?"
import numpy as np
import math
def scaled_dot_product_attention(Q, K, V):
"""
Q (Query) — "Què estic buscant?" [seq_len, d_k]
K (Key) — "Quin contingut ofereixo?" [seq_len, d_k]
V (Value) — "Quina informació dono?" [seq_len, d_v]
"""
d_k = Q.shape[-1]
# Similitud entre cada parell de tokens
scores = np.matmul(Q, K.T) / math.sqrt(d_k) # [seq, seq]
# Convertir a distribució de probabilitat
exp_s = np.exp(scores - scores.max(axis=-1, keepdims=True))
attention = exp_s / exp_s.sum(axis=-1, keepdims=True) # [seq, seq]
# Suma ponderada de valors
return np.matmul(attention, V), attention # [seq, d_v]
Exemple Visual: "El gat seu al coixí"¶
El gat seu al coixí
El [0.50, 0.30, 0.05, 0.05, 0.10] → "El" posa atenció en "gat"
gat [0.10, 0.60, 0.15, 0.05, 0.10] → "gat" auto-atenció alta
seu [0.05, 0.40, 0.30, 0.10, 0.15] → "seu" mira "gat" (qui seu?)
al [0.10, 0.05, 0.10, 0.60, 0.15] → preposició: auto-atenció
coixí [0.05, 0.10, 0.15, 0.20, 0.50] → objecte: auto-atenció
Multi-Head Attention: en lloc d'un sol mecanisme, el Transformer en té 8 o 16 en paral·lel. Cada cap aprèn aspectes diferents: sintaxi, semàntica, co-referència, temporalitat...
🧬 Genealogia dels LLM Moderns¶
graph TD
A["Transformer (2017, Google)"] --> B["BERT (2018, Google)<br/>Encoder-only"]
A --> C["GPT-1 (2018, OpenAI)<br/>Decoder-only"]
C --> F["GPT-2 (2019)"] --> G["GPT-3 175B (2020)"]
G --> H["InstructGPT + RLHF"] --> I["ChatGPT (Nov 2022)"]
I --> J["GPT-4 (2023)"] --> K["GPT-4o (2024)"]
K --> K2["o1 / o3 (2024-2025)<br/>Raonament extès"]
K2 --> K3["GPT-4.5 / o4-mini (2025)"]
A --> O["LLaMA 1 (2023, Meta)"] --> P["LLaMA 2"] --> Q["LLaMA 3.1 (2024)"]
Q --> Q2["LLaMA 3.3 / 4 (2025)"]
A --> R["Claude 1 (2023)"] --> S["Claude 2 / 2.1"]
S --> S2["Claude 3: Haiku · Sonnet · Opus (2024)"]
S2 --> T["Claude 3.5 Sonnet / Haiku (2024)"]
T --> T2["Claude 4: Sonnet 4.6 · Opus 4.6 (2025)"]
T2 --> T3["Claude Haiku 4.5 (2025)"]
A --> U["Mistral 7B (2023)"] --> V["Mixtral 8x7B (MoE)"]
V --> V2["Mistral Large / Codestral (2024-2025)"]
🔀 Encoder-only, Decoder-only i Encoder-Decoder¶
El diagrama anterior menciona aquests termes. Aquí els expliquem.
El Transformer original tenia dues meitats: un encoder (llegeix i entén) i un decoder (genera la sortida). Els models moderns n'han triat una o les dues, depenent de la tasca:
Encoder-only (models de comprensió)¶
L'encoder processa tota la seqüència en ambdues direccions (cada token "veu" els tokens anteriors i posteriors). Ideal per entendre el significat global d'un text.
Text: "El [MASK] menja el peix"
←←←← tots els tokens es veuen entre ells ←←←←
→→→→ en ambdues direccions simultàniament →→→→
Sortida: representació vectorial de cada token (no genera text)
Usat per: classificació de text, anàlisi de sentiment, detecció d'entitats, cerca semàntica (embeddings).
Exemples: BERT, RoBERTa, DistilBERT.
Decoder-only (models generatius)¶
El decoder processa els tokens d'esquerra a dreta (autoregressive): cada token només "veu" els anteriors, mai els futurs. Perfecte per generar text de forma natural.
Entrada: "El gat"
↓
Token 3: "El gat" → prediu "menja" (veu token 1, 2)
Token 4: "El gat menja" → prediu "el" (veu token 1, 2, 3)
Token 5: "El gat menja el" → prediu "peix"
...
Cada pas genera un nou token, i s'afegeix a l'entrada per generar el següent. Per això aquests models són bons escrivint, però no "veuen" el que ve després.
Usat per: generació de text, xat, escriptura de codi, agents.
Exemples: GPT-4, Claude, Llama, Mistral, Gemini.
Encoder-Decoder (models de transformació)¶
Combinen les dues meitats: l'encoder llegeix i entén el text d'entrada, i el decoder en genera un de nou. Útil quan la sortida és una transformació de l'entrada.
Entrada (encoder): "The cat eats fish" ← entén la frase sencera
↓
Sortida (decoder): "El gat menja el peix" ← genera token a token
Usat per: traducció automàtica, resum de textos, resposta a preguntes amb context.
Exemples: T5, BART, mT5.
Resum visual¶
| Encoder-only | Decoder-only | Encoder-Decoder | |
|---|---|---|---|
| Direcció de l'atenció | Bidireccional | Esquerra → dreta | Bidirec. + Esq.→dreta |
| Genera text? | No | Sí | Sí |
| Millor per a... | Entendre / classificar | Generar / xatejar | Traduir / resumir |
| Exemples | BERT, RoBERTa | GPT, Claude, Llama | T5, BART |
| Usat en agents? | Com a eina d'embedding | Sí (el LLM central) | Ocasionalment |
Per què els agents usen decoder-only?
Els agents necessiten generar text (raonament, respostes, crides a eines). Els models decoder-only com GPT-4 o Claude ho fan de forma natural. Els models encoder-only com BERT s'usen com a eines auxiliars (p.ex., per convertir documents en vectors per al sistema RAG).
🔄 Les Tres Fases d'Entrenament¶
Fase 1: Pre-training¶
# Objectiu: predir el token següent (Causal LM)
# "El gat menja el" → [peix, menjar, gos, gat...]
# Dataset: CommonCrawl + Wikipedia + llibres + GitHub ≈ bilions de tokens
# Cost GPT-3: ~4.6M$ | GPT-4 estimat: ~100M$
for batch in dataset: # ~300 bilions de tokens (GPT-3)
logits = model(batch.input_tokens)
loss = cross_entropy(logits, batch.next_tokens)
loss.backward()
optimizer.step()
Fase 2: Supervised Fine-Tuning (SFT)¶
# Dataset: ~13,000 parells (instrucció, resposta ideal) escrits per humans
dataset_sft = [
{"instruccio": "Escriu un poema sobre la tardor",
"resposta": "Les fulles cauen lentament, silencioses..."},
# ...
]
# El model aprèn a SEGUIR INSTRUCCIONS
Fase 3: RLHF¶
1. Model genera 3-4 respostes per cada pregunta
2. Humans les ordenen per qualitat: A > B > C
3. Reward Model aprèn a predir preferències humanes
4. PPO optimitza el model per maximitzar el reward
→ Resultat: respostes útils, segures i honestes
📊 Propietaris vs Open-Source¶
| Criteri | Propietari (GPT-4o, Claude) | Open-Source (Llama, Mistral) |
|---|---|---|
| Rendiment | Superior en tasques complexes | Competitiu a 70B+ paràmetres |
| Cost | Per token: $0.002–$0.06/1K | Infraestructura pròpia / Ollama gratuït |
| Privacitat | Dades surten al núvol | Execució local, dades privades |
| Customització | Fine-tuning limitat via API | Fine-tuning complet amb les teves dades |
| En aquest curs | gpt-4o-mini (pràctiques), gpt-4o (final) | Llama 3.1 via Ollama (opció alternativa) |
Usar Llama 3.1 localment (Ollama)¶
# Instal·lar Ollama — https://ollama.ai
curl -fsSL https://ollama.ai/install.sh | sh
# Descarregar Llama 3.1 8B (~5 GB)
ollama pull llama3.1:8b
ollama serve # Servidor local: http://localhost:11434
# LangChain amb Ollama — mateixa interfície que OpenAI!
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b", temperature=0)
print(llm.invoke("Explica en 2 frases qué és un LLM.").content)
✅ Activitats¶
Exercici 1.2.1 — Cost d'un LLM
Usa la calculadora de preus d'OpenAI per estimar el cost de: 1. Processar 1,000 pàgines PDF (~500 tokens/pàgina) amb gpt-4o-mini 2. Generar 10,000 respostes curtes (~200 tokens) amb gpt-4o 3. Comparar amb el cost de Llama 3.1 local (considera ~0.20€/hora de CPU)
Exercici 1.2.2 — Tokenització
Usa el Tokenizer d'OpenAI: 1. Quants tokens té la frase "El gat seu al coixí" en català vs anglès? 2. Per qué el català sol consumir més tokens per paraula que l'anglès? 3. Quin impacte té això en el cost d'una aplicació multilingüe?
📚 Referències¶
- Vaswani et al. (2017) — Attention Is All You Need. arXiv:1706.03762
- Ouyang et al. (2022) — Training language models to follow instructions with human feedback. arXiv:2203.02155
- Jay Alammar — The Illustrated GPT-2. jalammar.github.io