Transformers & Large Language Models
The Transformer is the neural-network architecture behind every modern large language model: it replaces step-by-step recurrence with attention, letting every token look directly at every other token in parallel. This page takes you from why RNNs hit a wall, through attention math with real numbers, to how models like GPT, Llama, Claude and Gemini are pretrained, aligned, decoded, scaled and served, so you can explain any part of the stack in an interview.
- An LLM is a stack of identical Transformer blocks trained to predict the next token. Everything it "knows" is stored in its weights and everything it "sees" must fit in its context window.
- Attention is
softmax(QKT/√dk)V: each token asks a question (query), compares it with every token's label (key), and takes a weighted average of their content (value). Multi-head attention runs several of these in parallel. - A block = attention (mixes information across tokens) + feed-forward network (processes each token alone), each wrapped with a residual connection and normalization. Position must be injected separately (sinusoidal, learned, RoPE or ALiBi).
- Encoder-only (BERT) understands, decoder-only (GPT, Llama) generates, encoder-decoder (T5) transforms one sequence into another. Almost all chat LLMs today are decoder-only.
- The recipe: pretrain on trillions of tokens, then supervised fine-tune on instructions, then align with human preferences (RLHF or DPO). Reasoning models add reinforcement learning on verifiable tasks and spend more compute at inference time.
- Generation is a loop: logits → temperature → filtering (top-k, top-p, min-p) → sample → append. The KV cache makes that loop fast; its memory cost is what limits long context and batch size.
From RNNs to attention: why Transformers exist
Language is a sequence, and the meaning of a word depends on words that may be far away. In "The animal didn't cross the street because it was too tired", the word it refers to animal, six words earlier. Any model of language needs a way to connect distant positions. The history of NLP architectures is really a history of better ways to make those connections.
The recurrent approach and its problems
A recurrent neural network (RNN) reads one token at a time and keeps a running summary, the hidden state: ht = tanh(Whht-1 + Wxxt + b). LSTMs and GRUs add gates that decide what to keep and what to forget, which helps gradients survive longer. But the design has five structural weaknesses:
- No parallelism Step t cannot start until step t-1 finishes. Training on a 1,000-token sequence needs 1,000 sequential steps, so GPUs sit mostly idle.
- Long information path For token 1 to influence token 500, its signal must pass through 499 hidden-state updates. Each update dilutes it. The path length is O(n).
- Vanishing and exploding gradients Backpropagation through time multiplies many Jacobians together. If their size is below 1 the gradient shrinks exponentially; above 1 it blows up. LSTMs soften this but do not remove it.
- Fixed-size memory The whole history is squeezed into one vector of fixed size, no matter how long the input is.
- Uniform treatment The model has no explicit mechanism to decide which earlier words matter most for the current one.
Seq2seq and the bottleneck
For translation, the classic design used two RNNs: an encoder reads the source sentence and its final hidden state becomes the context vector; a decoder generates the target sentence from that single vector. For a 50-word sentence, everything the decoder needs is forced through one vector. Quality collapsed as sentences got longer. This is the fixed-length context bottleneck.
Attention fixes the bottleneck
The fix (introduced for translation in 2014-2015, often called additive attention) was simple: keep all encoder hidden states, and at every decoder step compute a fresh weighted average of them. When generating "Je", the decoder puts most weight on "I"; when generating "t'aime", it shifts weight to "love". The context is recomputed per output step, so nothing has to be crammed into one vector.
But RNN+attention still had an RNN inside: the encoder was still sequential, tokens inside the source could not attend to each other directly, and training was still slow. The 2017 paper "Attention Is All You Need" asked: what if we delete the recurrence entirely and build the whole model out of attention?
RNN / LSTM
- Sequential: O(n) steps that cannot be parallelised
- Path between two tokens: O(n)
- Cost per layer: O(n · d2)
- Memory: one fixed-size hidden state
- Order is built in (it reads left to right)
Self-attention (Transformer)
- All tokens processed at once: O(1) sequential steps per layer
- Path between any two tokens: O(1), one attention hop
- Cost per layer: O(n2d + nd2); the n2 term dominates when n > d
- Memory: every token keeps its own vector (and in generation, its K and V)
- Order must be added explicitly with positional encoding
An RNN is a game of telephone: a message is whispered from person to person down a long line, and by the time it reaches the end it is distorted, and nobody can start until the previous person finishes. A Transformer is a group video call: everyone hears everyone directly at the same time, and each person decides whose words to focus on. Mapping back: the whisper chain is the hidden state passed step by step (long path, sequential), and the video call is self-attention (direct O(1) paths, fully parallel). The price of the video call is that the number of possible conversations grows with the square of the number of participants, which is exactly attention's O(n2) cost.
The representation story that led here
In parallel, the way words are represented evolved. It is worth knowing because interviewers often ask "why did we need contextual embeddings?"
| Stage | What it gave us | What was missing |
|---|---|---|
| One-hot vectors | A unique ID per word | Huge sparse vectors; every pair of words is orthogonal, so "cat" and "kitten" have similarity 0 |
| Static dense embeddings (Word2Vec, GloVe) | Short dense vectors where geometry means something (king − man + woman ≈ queen) | One vector per word regardless of context: "bank" (river) = "bank" (money) |
| Contextual embeddings from BiLSTMs (ELMo) | Different vectors for the same word in different sentences | Still sequential and slow; limited depth |
| RNN + cross-attention | Alignment between source and target sequences | No attention within a sequence; still recurrent |
| Self-attention + positional encoding (Transformer) | Every token contextualised by every other token, in parallel, with order information | Quadratic cost in sequence length |
If you need a refresher on RNNs, LSTMs, backpropagation or word embeddings, see Deep Learning and NLP Fundamentals.
Tokens, embeddings and token economics
A Transformer never sees characters or words. Text is first split into tokens by a tokenizer, each token is mapped to an integer ID, and each ID is mapped to a learned vector (its embedding). Everything downstream, including context limits and API prices, is measured in tokens.
Think of building text out of LEGO. A word-level vocabulary would need a custom brick for every word ever written, and any new word would be impossible to build. A character-level vocabulary uses only tiny 1x1 bricks, so every sentence needs thousands of them. Subword tokenization is the practical middle: common words get their own big brick ("the", "house"), rare words are assembled from reusable medium bricks ("un" + "believ" + "able"). Mapping back: the brick catalogue is the vocabulary, the number of bricks you use is the token count (what you pay for and what fills the context window), and the fact that any word can still be built is why subword models have almost no out-of-vocabulary problem.
Tokenization recap
| Method | Idea | Used by |
|---|---|---|
| Byte-Pair Encoding (BPE) | Start from characters (or bytes); repeatedly merge the most frequent adjacent pair into a new symbol until the vocabulary reaches the target size | GPT family, Llama 3, many others |
| Byte-level BPE | BPE over raw UTF-8 bytes, so every possible string is representable with a 256-symbol base alphabet; no unknown token ever | GPT-2 onward, tiktoken encodings |
| WordPiece | Like BPE but picks the merge that most increases the likelihood of the training data; continuation pieces are marked with ## | BERT |
| Unigram LM | Start with a big vocabulary and prune pieces that least reduce likelihood; tokenization is probabilistic | T5, many multilingual models (via SentencePiece) |
| SentencePiece | A library that treats the input as a raw stream (spaces become a visible symbol) and trains BPE or Unigram; language-agnostic | T5, Llama 1 and 2, Gemma |
Worked example: three BPE merges
Suppose the training corpus has these words with counts: play x6, played x3, playing x4, say x5. Start with single characters.
- Count adjacent pairs "a y" appears in play (6), played (3), playing (4) and say (5) = 18 times. "p l" and "l a" each appear 13 times. Everything else is lower.
- Merge 1: a + y → ay Words become
p l ay,p l ay e d,p l ay i n g,s ay. - Merge 2: p + l → pl (13 occurrences; ties are broken by a fixed rule). Words become
pl ay, ... - Merge 3: pl + ay → play (13). Now
playis one token, andplayed=play e d. Further merges would createed,in,ing. - Result Frequent words become single tokens; an unseen word like "replaying" is still encodable as pieces such as
re+play+ing.
# Inspect tokenization with two popular libraries
import tiktoken
enc = tiktoken.get_encoding("cl100k_base") # a GPT-4-era BPE vocabulary
ids = enc.encode("Tokenization isn't free!")
print(ids, len(ids))
print([enc.decode([i]) for i in ids]) # see each piece, note leading spaces
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("bert-base-uncased") # WordPiece
print(tok.tokenize("Tokenization isn't free!"))
# e.g. ['token', '##ization', 'isn', "'", 't', 'free', '!']
Tokenization quirks that matter in practice
- Leading spaces are part of tokens. " hello" and "hello" are usually different IDs. This is why prompt formatting and trailing spaces can change outputs.
- Numbers split oddly. "12345" might become "123" + "45". This is one reason LLMs are weak at digit-level arithmetic. Some tokenizers (Llama 3, many newer ones) split numbers into single digits or groups of three to help.
- Letters are invisible. The model sees "strawberry" as maybe two or three tokens, not ten letters, so "how many r's in strawberry?" is genuinely hard without reasoning or tools.
- Languages are not equal. A vocabulary trained mostly on English packs English efficiently (about 4 characters or 0.75 words per token) but may need 2-4x more tokens for Hindi, Tamil, Thai or Korean. Same content, higher cost, less effective context.
- Special tokens.
[CLS],[SEP],[MASK](BERT),<s>,</s>, end-of-sequence (EOS), padding, and chat-template markers that separate system, user and assistant turns. - Vocabulary size trade-off. Typical sizes are 32K-256K. Bigger vocabularies mean fewer tokens per text (cheaper, longer effective context) but a larger embedding matrix and output softmax, and rarer tokens get less training signal.
Embeddings
The embedding layer is a lookup table E of shape vocab_size × d_model. Token ID 4031 simply selects row 4031. The rows start random and are learned by backpropagation like any other weight. In most decoder-only LLMs the final output projection (the "LM head") that turns the last hidden state back into vocabulary logits has the same shape, and many models tie the two matrices to save parameters.
Important distinction: the input embedding is static (one vector per token ID). The vectors that come out of each Transformer layer are contextual: the "bank" vector after layer 12 differs between "river bank" and "bank loan". Those contextual hidden states are what embedding models (for search and RAG) pool into a single sentence vector. See RAG for how they are used in retrieval.
Token economics
Hosted LLMs bill per token, and context windows are counted in tokens, so you should be able to do quick token arithmetic in an interview.
Worked example. A support bot sends a 1,500-token system prompt, 2,000 tokens of retrieved documents and a 100-token question, and gets a 400-token answer. At a hypothetical price of 1 unit per million input tokens and 4 units per million output tokens: input = 3,600 × 1/106 = 0.0036 units; output = 400 × 4/106 = 0.0016 units; total ≈ 0.0052 units per request. At 1 million requests per day, that is about 5,200 units per day, and 69% of it comes from input. The cheapest optimisations are therefore: shorten the system prompt, retrieve fewer but better chunks, and use prompt caching (many providers discount repeated prompt prefixes).
Latency view
Input tokens are processed in parallel (prefill) and are cheap in time; output tokens are generated one by one (decode). A 400-token answer at 50 tokens/s takes 8 seconds no matter how fast prefill is.
Context view
Context window = input + output. A 128K-token model given 126K tokens of input can only answer with 2K tokens.
Quality view
More tokens in context is not always better: irrelevant text dilutes attention and "lost in the middle" effects mean facts buried in the middle of a long prompt are used less reliably.
max_tokens. Mention that non-English traffic can cost 2-4x more tokens.Positional encoding: giving attention a sense of order
Self-attention on its own is permutation-equivariant: shuffle the input tokens and each token's output is the same, just shuffled. The attention score between "dog" and "man" does not care which one came first, so "dog bites man" and "man bites dog" would look identical. Position information must be injected explicitly.
Imagine the pages of a book have been unbound and dropped on the floor. Every page still has its words, but without page numbers you cannot tell the story's order. Positional encoding stamps a page number on each page. The sinusoidal scheme is like a set of clocks with hands spinning at different speeds (seconds, minutes, hours, days): together their positions identify a unique moment. RoPE is like describing each page by an angle on a dial, so that the difference in angles between two pages tells you how far apart they are. Mapping back: pages are tokens, page numbers are position vectors, the clocks are sine/cosine frequencies, and the dial is the rotation RoPE applies to queries and keys.
1. Sinusoidal (original Transformer)
Tiny example (d = 4). Frequencies: pair 0 uses 1/100000 = 1; pair 1 uses 1/100002/4 = 0.01.
| Position | sin(pos·1) | cos(pos·1) | sin(pos·0.01) | cos(pos·0.01) |
|---|---|---|---|---|
| 0 | 0.000 | 1.000 | 0.000 | 1.000 |
| 1 | 0.841 | 0.540 | 0.010 | 1.000 |
| 2 | 0.909 | −0.416 | 0.020 | 1.000 |
The fast pair changes a lot between neighbours (fine position), the slow pair changes gradually (coarse position). Properties: deterministic (no parameters), unique per position, and because sin/cos of (pos + k) is a fixed linear function (a rotation) of sin/cos of pos, the model can learn relative offsets. Using both sin and cos also guarantees that when one is zero the other is not.
import math, torch
def sinusoidal_pe(max_len, d):
pe = torch.zeros(max_len, d)
pos = torch.arange(max_len).unsqueeze(1).float() # (max_len, 1)
div = torch.exp(torch.arange(0, d, 2).float() * (-math.log(10000.0) / d))
pe[:, 0::2] = torch.sin(pos * div) # even dims
pe[:, 1::2] = torch.cos(pos * div) # odd dims
return pe # add to token embeddings
2. Learned absolute positions (BERT, GPT-2)
A second lookup table P of shape max_len × d, trained like the token embeddings. Simple and effective, but the model has literally no vector for position 513 if it was trained with 512, so it cannot extrapolate.
3. RoPE: rotary position embedding (Llama, Mistral, Qwen, Gemma, DeepSeek...)
Instead of adding a vector to the input, RoPE rotates the query and key vectors inside every attention layer. Split each q and k into pairs of dimensions; rotate pair i of the token at position m by the angle m·θi.
Why it became the default: it encodes relative position (what attention actually needs), adds no parameters, works with the KV cache (a cached key never needs updating), and can be stretched to longer contexts with tricks such as position interpolation (squeeze new positions into the trained range), NTK-aware scaling (raise the base so low frequencies stretch more than high ones) and YaRN (a refined per-frequency interpolation plus attention temperature fix), usually followed by a short fine-tune on long documents.
4. ALiBi: attention with linear biases (BLOOM, MPT)
No position vectors at all. Each head adds a penalty proportional to distance directly to the attention score before softmax: score(i, j) = qi·kj/√d − mh·(i − j), with a different fixed slope mh per head (a geometric sequence like 1/2, 1/4, 1/8 ...). Near tokens are favoured, far tokens fade. It extrapolates to longer sequences than seen in training well, but biases the model towards locality.
5. Relative position biases (T5) and NoPE
T5 learns a scalar bias per head for bucketed relative distances and adds it to attention scores. Some research shows decoder-only models can even work with no positional encoding (NoPE), because the causal mask itself leaks order information (token i can see exactly i tokens), but this is not mainstream.
| Scheme | Absolute or relative | Where applied | Parameters | Length extrapolation |
|---|---|---|---|---|
| Sinusoidal | Absolute (relative recoverable) | Added to input embeddings | 0 | Some, in theory; weak in practice |
| Learned absolute | Absolute | Added to input embeddings | max_len × d | None beyond max_len |
| RoPE | Relative (via rotation) | Q and K in every layer | 0 | Moderate; good with interpolation/YaRN plus fine-tuning |
| ALiBi | Relative (distance penalty) | Attention scores in every layer | 0 | Good |
| T5 relative bias | Relative (bucketed) | Attention scores | Small table per head | Good |
Self-attention step by step
Self-attention is the operation that lets each token build a new representation of itself by gathering information from the other tokens in the same sequence. It is best understood as a soft, differentiable lookup table.
You walk into a library with a question written on a card (your query). Every book has a label on its spine (its key) and content inside (its value). You compare your card with every spine and give each book a relevance score. Instead of borrowing only the single best book, you take notes from all of them, spending more time on the more relevant ones. Mapping back: a Python dictionary does an exact match between query and one key; attention does a fuzzy match with every key and returns a blend of values weighted by match strength. The softmax turns relevance scores into a reading-time budget that sums to 100%.
The formula
The five steps
- Project Each token vector is multiplied by three learned matrices to produce its query ("what am I looking for?"), key ("what do I offer?") and value ("what information do I pass on if chosen?").
- Score Dot product of every query with every key:
sij = qi·kj. Large when the two vectors point the same way. - Scale Divide by √dk so scores do not grow with dimension (explained below).
- Mask and softmax Set disallowed positions (future tokens, padding) to −∞, then softmax each row into weights αij that are positive and sum to 1.
- Mix Output for token i is
Σj αij vj, a weighted average of value vectors.
Worked numeric example (3 tokens, dk = 2)
Tokens: "the", "cat", "sat". Assume the projections have already produced these vectors (in a real model they come from X times learned matrices, and dk is 64-128):
| Token | q | k | v |
|---|---|---|---|
| the | [1, 0] | [1, 0] | [2, 0] |
| cat | [0, 1] | [0, 2] | [0, 2] |
| sat | [1, 1] | [1, 1] | [1, 1] |
Step 1-2: raw scores QKT (row = query token, column = key token):
| q \ k | the | cat | sat |
|---|---|---|---|
| the | 1·1+0·0 = 1 | 1·0+0·2 = 0 | 1·1+0·1 = 1 |
| cat | 0 | 2 | 1 |
| sat | 1 | 2 | 2 |
Step 3: scale by √2 ≈ 1.414: the = [0.707, 0, 0.707]; cat = [0, 1.414, 0.707]; sat = [0.707, 1.414, 1.414].
Step 4a: bidirectional (encoder) softmax for the row "the": e0.707 = 2.028, e0 = 1, e0.707 = 2.028, sum 5.056 → weights [0.401, 0.198, 0.401]. Output = 0.401·[2,0] + 0.198·[0,2] + 0.401·[1,1] = [1.203, 0.797]. "the" now carries information from both later tokens.
Step 4b: causal (decoder) softmax. Apply the mask: future positions become −∞.
| Query | Masked scaled scores | Softmax weights | Output = Σ αv |
|---|---|---|---|
| the | [0.707, −∞, −∞] | [1.000, 0, 0] | [2.000, 0.000] |
| cat | [0, 1.414, −∞] | e0=1, e1.414=4.113, sum 5.113 → [0.196, 0.804, 0] | 0.196·[2,0] + 0.804·[0,2] = [0.392, 1.608] |
| sat | [0.707, 1.414, 1.414] | 2.028, 4.113, 4.113, sum 10.254 → [0.198, 0.401, 0.401] | [0.396+0.401, 0.802+0.401] = [0.797, 1.203] |
Read the result: with the causal mask, "the" can only see itself, so its output is just its own value. "cat" leans heavily on itself because its key [0,2] matches its query strongly. "sat" (query [1,1]) matches "cat" and itself equally and "the" less. Every output is a convex combination of value vectors, which is why attention alone is a smoothing, mixing operation and the network also needs the non-linear feed-forward layer.
Why divide by √dk?
If the components of q and k are independent with mean 0 and variance 1, their dot product is a sum of dk terms each with variance 1, so it has variance dk and standard deviation √dk. With dk = 64, raw scores are typically around ±8. Softmax of numbers that spread out is almost one-hot: one weight near 1, the rest near 0, and the gradient of softmax in that saturated region is almost zero, so learning stalls. Dividing by √dk brings the variance back to about 1, keeping softmax in its sensitive range. It is the same maths as temperature: √dk acts as a fixed temperature for attention.
Masks
Causal (look-ahead) mask
Lower-triangular: token i may attend to positions 1..i only. Used in every decoder, in training and inference. It lets a whole sequence train in parallel while each position still predicts only from its past, so the model cannot "cheat" by reading the answer.
Padding mask
Batches contain sequences of different lengths, so short ones are padded. The padding mask sets scores to padded positions to −∞ so real tokens never attend to filler. Used in encoders and decoders.
MLM masking (different idea)
BERT's "masking" replaces input tokens with [MASK] as a training task. It is data corruption, not an attention mask. Interviewers like to check you do not confuse the two.
Causal mask for "I love NLP <eos>" (✓ = attend, ✗ = score set to -inf)
keys → I love NLP <eos>
queries ↓ I ✓ ✗ ✗ ✗
love ✓ ✓ ✗ ✗
NLP ✓ ✓ ✓ ✗
<eos> ✓ ✓ ✓ ✓
Shapes you should be able to recite
For a 10-token sentence in a BERT-base-sized model (d = 768, 12 heads, dk = 64): X is 10 × 768. Per head, Q, K, V are 10 × 64. Scores QKT are 10 × 10. Weights times V give 10 × 64. Concatenating 12 heads gives 10 × 768, then WO (768 × 768) keeps it 10 × 768. The FFN expands to 10 × 3072 and back to 10 × 768. Sequence length never changes inside a block; only the feature dimension expands and contracts. Time is O(n2d) for scores and mixing plus O(nd2) for the Q, K, V and output projections; the n2 term dominates once sequence length exceeds model width. Memory for the score matrix is O(n2) per head unless FlashAttention tiles it down to O(n).
Code: attention from scratch in PyTorch
import math, torch, torch.nn.functional as F
def attention(q, k, v, causal=False, pad_mask=None):
# q, k, v: (batch, heads, seq, d_k)
d_k = q.size(-1)
scores = q @ k.transpose(-2, -1) / math.sqrt(d_k) # (B, H, T, T)
T = scores.size(-1)
if causal:
future = torch.triu(torch.ones(T, T, dtype=torch.bool, device=q.device), 1)
scores = scores.masked_fill(future, float("-inf"))
if pad_mask is not None: # (B, 1, 1, T), True = padding
scores = scores.masked_fill(pad_mask, float("-inf"))
weights = F.softmax(scores, dim=-1) # each row sums to 1
return weights @ v, weights
# Production code uses the fused kernel (FlashAttention under the hood when available):
# out = F.scaled_dot_product_attention(q, k, v, is_causal=True)
What is learned, and what is computed
The attention weights are not parameters. They are computed fresh for every input. The learned parameters are WQ, WK, WV (and WO). Training adjusts those projections so that useful relationships (pronoun to noun, verb to subject) produce high dot products. That is how the same frozen model attends from "it" to "animal" in one sentence and to "street" in another: the weights are fixed, but the input, and therefore Q and K, changes. Nobody tells the model that "animal" is a noun; such structure emerges because it helps predict the next token.
Multi-head attention and cross-attention
One attention operation produces one set of weights per token, so it can express only one "kind" of relationship at a time. Language has many simultaneously: the subject of a verb, what a pronoun refers to, the adjacent word, the matching bracket, the topic of the paragraph. Multi-head attention runs h smaller attentions in parallel, each with its own projections, and combines them.
A film is reviewed by a panel instead of one critic: one critic watches the plot, one the acting, one the cinematography, one the soundtrack. Each writes a short report, and an editor merges the reports into one review. Mapping back: each critic is a head with its own WQ, WK, WV (its own idea of what to look for), the short reports are the lower-dimensional head outputs (d/h each), stapling them together is the concatenation, and the editor is the output projection WO that learns how to blend the perspectives.
Worked example: two heads, one sentence
Two tokens, "animal" = [1, 0] and "it" = [0, 1], model dimension 2, two heads of dimension 1. To keep the numbers readable we skip the √dk scaling (dk = 1 anyway).
| Head 1 (links "it" to "animal") | Head 2 (keeps token identity) | |
|---|---|---|
| WQ, WK, WV | [1,1]T, [1,0]T, [2,0]T | [0,1]T, [0,1]T, [0,3]T |
| q (animal, it) | 1, 1 | 0, 1 |
| k (animal, it) | 1, 0 | 0, 1 |
| v (animal, it) | 2, 0 | 0, 3 |
| Scores | [[1,0],[1,0]] | [[0,0],[0,1]] |
| Softmax weights | [[0.73,0.27],[0.73,0.27]] | [[0.50,0.50],[0.27,0.73]] |
| Output (animal, it) | 1.46, 1.46 | 1.50, 2.19 |
softmax([1, 0]) = [e/(e+1), 1/(e+1)] = [2.718/3.718, 1/3.718] = [0.73, 0.27]. After concatenation, "animal" = [1.46, 1.50] and "it" = [1.46, 2.19]. Head 1 made "it" carry the same animal-flavoured signal as "animal" (coreference); head 2 kept "it" distinguishable. WO then mixes these two views into the final 2-dimensional output. Real models have 12-128 heads, and probing studies find heads specialised for the previous token, syntactic dependencies, coreference and copying (so-called induction heads that find an earlier occurrence of the current token and copy what followed it, a key mechanism behind in-context learning).
import torch, torch.nn as nn, torch.nn.functional as F
class MultiHeadAttention(nn.Module):
def __init__(self, d_model=768, n_heads=12):
super().__init__()
assert d_model % n_heads == 0
self.h, self.d_k = n_heads, d_model // n_heads
self.qkv = nn.Linear(d_model, 3 * d_model, bias=False) # W_Q, W_K, W_V fused
self.out = nn.Linear(d_model, d_model, bias=False) # W_O
def forward(self, x, causal=True):
B, T, D = x.shape
q, k, v = self.qkv(x).split(D, dim=-1)
# (B, T, D) -> (B, h, T, d_k): each head gets its own slice
q, k, v = (t.view(B, T, self.h, self.d_k).transpose(1, 2) for t in (q, k, v))
y = F.scaled_dot_product_attention(q, k, v, is_causal=causal)
y = y.transpose(1, 2).contiguous().view(B, T, D) # concatenate heads
return self.out(y)
Why not one big head?
A single head computes one softmax per query, so it must choose one distribution over positions: it cannot put 90% on the subject and 90% on the previous token at the same time. Several heads can. With the same total width, multi-head costs the same FLOPs, so it is a free increase in expressiveness. More heads is not automatically better: with a fixed dmodel, more heads means smaller dk per head, and research on head pruning shows many heads are redundant and can be removed after training with little loss. Typical choice: dk = 64 or 128, so h = dmodel/64 or /128.
Cross-attention
Cross-attention uses exactly the same formula but takes queries from one sequence and keys and values from another. In an encoder-decoder model, the decoder's queries attend over the encoder's final-layer outputs, so each target token can "look back" at the source.
| Self-attention | Cross-attention | |
|---|---|---|
| Q from | The same sequence X | The decoder (target so far) |
| K, V from | The same sequence X | The encoder output (source), always from the top encoder layer |
| Score matrix shape | n × n | t × s (target length × source length) |
| Masking | Causal in decoders, none (only padding) in encoders | No causal mask (the whole source is known); padding mask on the source |
| Where it appears | Every encoder and decoder layer | Middle sub-layer of each decoder layer in encoder-decoder models; also how many vision-language and diffusion models inject conditioning |
Example: translating "The cat sat" into French, when the decoder is producing "chat", its query matches the key of "cat" strongly (say weight 0.70), "sat" weakly (0.20) and the rest barely, so its context is mostly the encoder's representation of "cat". Because the encoder output does not change during generation, its K and V are computed once and reused at every decoding step.
The Transformer block and the full architecture
A Transformer is a stack of identical blocks. Each block has two sub-layers: multi-head attention (tokens talk to each other) and a position-wise feed-forward network (each token thinks on its own). Each sub-layer is wrapped with a residual connection and a normalization layer. Stack 12 blocks and you have GPT-2 small; stack 96 and you have GPT-3.
Think of an assembly line of identical workstations, each refining a product a little. At every station, first there is a team meeting (attention) where each worker hears what the others have and updates their own notes. Then each worker goes back to their desk and processes those notes privately (the feed-forward network). Nothing is thrown away: each station writes its changes as sticky notes on top of the original document rather than rewriting it (the residual connection), and a quality inspector rescales everything to a standard range before the next station (layer normalization). Mapping back: the document flowing down the line is the residual stream, the sticky notes are sub-layer outputs added to it, and the stack of stations is the stack of layers.
The full diagram (original encoder-decoder Transformer)
Output probabilities
▲
┌──────┴──────┐
│ Softmax │
├─────────────┤
│ Linear │ (d_model → vocab)
└──────▲──────┘
│
ENCODER (× N) DECODER (× N)
┌───────────────────────────────┐ ┌───────────────────────────────────┐
│ ┌───────────────────────┐ │ │ ┌───────────────────────────┐ │
│ │ Add & Norm │◀─┐│ │ │ Add & Norm │◀─┐│
│ └──────────▲────────────┘ ││ │ └────────────▲──────────────┘ ││
│ ┌──────────┴────────────┐ ││ │ ┌────────────┴──────────────┐ ││
│ │ Feed-Forward Network │ ││ │ │ Feed-Forward Network │ ││
│ │ d → 4d → ReLU/GELU → d│ ││ │ └────────────▲──────────────┘ ││
│ └──────────▲────────────┘ ││ │ ├─────────────────┘│
│ ├───────────────┘│ │ ┌────────────┴──────────────┐ │
│ ┌──────────┴────────────┐ │ │ │ Add & Norm │◀─┐│
│ │ Add & Norm │◀─┐│ │ └────────────▲──────────────┘ ││
│ └──────────▲────────────┘ ││ │ ┌────────────┴──────────────┐ ││
│ ┌──────────┴────────────┐ ││ K,V │ │ Multi-Head CROSS-Attn │ ││
│ │ Multi-Head SELF-Attn │ ││ ─────▶│ │ Q: decoder K,V: encoder │ ││
│ │ (bidirectional) │ ││ │ └────────────▲──────────────┘ ││
│ └──────────▲────────────┘ ││ │ ├─────────────────┘│
│ ├───────────────┘│ │ ┌────────────┴──────────────┐ │
│ │ │ │ │ Add & Norm │◀─┐│
└──────────────┼────────────────┘ │ └────────────▲──────────────┘ ││
│ │ ┌────────────┴──────────────┐ ││
│ │ │MASKED Multi-Head SELF-Attn│ ││
│ │ │ (causal: past only) │ ││
│ │ └────────────▲──────────────┘ ││
│ │ ├─────────────────┘│
│ └────────────────┼──────────────────┘
┌───────┴────────┐ ┌───────┴────────┐
│ + Positional │ │ + Positional │
│ encoding │ │ encoding │
├────────────────┤ ├────────────────┤
│ Input embedding│ │Output embedding│
└───────▲────────┘ └───────▲────────┘
│ │
Source tokens ("I love you") Target tokens shifted right ("<bos> Je t'")
Original sizes: N = 6, d_model = 512, heads = 8, d_ff = 2048, post-LN, ReLU, sinusoidal PE.
The modern decoder-only block (Llama-style)
token ids ──▶ Embedding ──▶ x (residual stream, shape T × d)
│
┌─────────────────────┼──────────────────────────┐
│ ├──────────────┐ │
│ RMSNorm │ │
│ │ │ residual │
│ Masked multi-head attention │ │ repeated
│ (RoPE on Q,K; GQA; KV cache) │ │ L times
│ │ │ │ (32, 80,
│ ⊕ ◀────────────┘ │ 126 ...)
│ ├──────────────┐ │
│ RMSNorm │ │
│ │ │ residual │
│ SwiGLU feed-forward │ │
│ W2( SiLU(W1 x) ⊙ W3 x ) │ │
│ │ │ │
│ ⊕ ◀────────────┘ │
└─────────────────────┼──────────────────────────┘
final RMSNorm
│
LM head (d → vocab) ──▶ logits ──▶ sampling ──▶ next token
Residual connections
A useful mental model is the residual stream: a d-dimensional vector per token that flows from the embedding to the output, and every attention and FFN sub-layer reads from it and writes an additive update back into it. Removing residuals makes deep Transformers essentially untrainable.
Layer normalization, Pre-LN vs Post-LN, and RMSNorm
Why LayerNorm rather than BatchNorm: sequences have variable length and padding, batch statistics are noisy for small or variable batches, and at inference you often have batch size 1. LayerNorm normalises each token independently, so it behaves identically in training and inference.
Post-LN (original, BERT)
x = Norm(x + Sublayer(x))- Normalization sits on the residual path
- Gradients near the output are large at initialisation; needs careful learning-rate warm-up
- Can reach slightly better final quality when it trains
- Unstable for very deep stacks
Pre-LN (GPT-2 onward, all modern LLMs)
x = x + Sublayer(Norm(x))- The residual path is a clean identity from input to output
- Much more stable; trains deep models with less warm-up
- Needs a final norm before the LM head
- Residual stream magnitude can grow with depth; variants add extra norms (for example QK-norm)
The feed-forward network (FFN / MLP)
What the FFN does: attention is (apart from the softmax) a weighted average, which is a linear mixing of value vectors. Without a non-linearity between layers, stacking them would collapse to one linear map. The FFN applies the same small MLP to every token independently, adding non-linear feature transformations. Expanding to 4d temporarily gives the network more room to form combinations of features before compressing back. Interpretability work suggests FFN layers act like key-value memories that store much of the model's factual knowledge, and they hold about two-thirds of the parameters.
Parameter counting
| Component | Parameters (ignoring biases and norms) |
|---|---|
| Attention: WQ, WK, WV, WO | 4d2 |
| FFN with 4d hidden (or SwiGLU with 8d/3) | 8d2 |
| One block | ≈ 12d2 |
| Token embedding (+ untied LM head) | |V|·d (×2 if untied) |
Check with GPT-2 small: d = 768, L = 12: 12 × 7682 × 12 ≈ 84.9M in blocks, plus 50,257 × 768 ≈ 38.6M token embeddings (weight tying: the LM head reuses E instead of a second |V|·d matrix), plus 1,024 × 768 ≈ 0.8M position embeddings ≈ 124M. Untied, GPT-2 small would be about 163M. GPT-3: d = 12,288, L = 96: 12 × 12,2882 × 96 ≈ 174B, plus about 0.6B of embeddings ≈ 175B. Memory to hold weights = parameters × bytes per parameter: a 7B model needs about 14 GB in 16-bit, 7 GB in 8-bit, 3.5 GB in 4-bit.
class Block(nn.Module):
"""Pre-norm decoder block with RMSNorm and SwiGLU (Llama-style, simplified)."""
def __init__(self, d=4096, n_heads=32, hidden=11008):
super().__init__()
self.norm1, self.norm2 = nn.RMSNorm(d), nn.RMSNorm(d) # PyTorch 2.4+
self.attn = MultiHeadAttention(d, n_heads) # RoPE omitted for brevity
self.w1 = nn.Linear(d, hidden, bias=False)
self.w3 = nn.Linear(d, hidden, bias=False)
self.w2 = nn.Linear(hidden, d, bias=False)
def forward(self, x):
x = x + self.attn(self.norm1(x), causal=True) # tokens talk
h = self.norm2(x)
x = x + self.w2(F.silu(self.w1(h)) * self.w3(h)) # each token thinks
return x
Other details worth knowing
- Dropout on attention weights and sub-layer outputs was standard in the original model and BERT; very large LLMs trained for about one epoch often use little or none.
- Initialisation is small (for example normal with standard deviation 0.02), and some schemes scale down the output projections of residual branches by 1/√(2L) so the stream does not grow with depth.
- Biases are often removed from linear layers in modern LLMs; it slightly improves stability and costs nothing.
- Why N = 6? The original paper simply found it a good trade-off for its data and compute. Depth is a hyperparameter; deeper models are more expressive but slower and harder to train, and width, depth and data are scaled together (see scaling laws).
Encoder-only, decoder-only and encoder-decoder models
The original Transformer had both an encoder and a decoder. Later models kept only the part they needed. Which part you keep decides what the model sees (both directions or only the past), how it is pretrained, and what it is good at.
An encoder-only model is an editor who reads the whole manuscript, front to back and back to front, before commenting on it: excellent at understanding and judging, but not writing new text. A decoder-only model is an improv storyteller who can only look at what has been said so far and must come up with the next word: natural at generating. An encoder-decoder is a simultaneous interpreter who first listens to the full speech (encoder) and then produces a new speech in another language while glancing back at their notes (decoder with cross-attention). Mapping back: "reading both directions" is bidirectional attention, "only what has been said" is the causal mask, and "glancing at notes" is cross-attention to the encoder output.
| Encoder-only | Decoder-only | Encoder-decoder | |
|---|---|---|---|
| Attention | Bidirectional self-attention | Causal (masked) self-attention | Bidirectional encoder + causal decoder + cross-attention |
| Typical pretraining | Masked language modelling (MLM) | Causal language modelling (next token) | Span corruption / denoising |
| Examples | BERT, RoBERTa, DeBERTa, ELECTRA, ModernBERT; most text-embedding models | GPT series, Llama, Mistral, Qwen, DeepSeek, Claude, Gemini (as publicly described) | Original Transformer, T5, Flan-T5, BART, mBART, Whisper (audio in, text out) |
| Best at | Classification, NER, extractive QA, embeddings, reranking | Open-ended generation, chat, code, reasoning, few-shot learning | Translation, summarisation, speech recognition: input → different output |
| Output | A contextual vector per token (plus a pooled [CLS] vector) | A next-token distribution per position | A generated target sequence |
| Weakness | Cannot generate fluently; fixed-length inputs (often 512) | Sees only left context at each position; generation is sequential | Two stacks to run; less natural for chat and in-context learning |
Why decoder-only won for LLMs
- One objective, every token is a training signal. Next-token prediction on raw text gives a loss at every position, whereas MLM only trains on the ~15% masked tokens.
- Generation is native. The training task (predict the next token) is exactly the inference task.
- Everything is a prompt. Instructions, examples, documents and conversation history are all just the beginning of one sequence; no separate input and output streams. This made in-context learning and chat natural.
- Simple and scalable. One stack, one KV cache, well-understood scaling behaviour; the engineering ecosystem (kernels, serving systems) converged on it.
Encoder-only models remain the workhorse for embeddings, retrieval, reranking and cheap classification: a 100-300M-parameter encoder is far cheaper than an LLM for tagging millions of documents. Encoder-decoders remain strong where input and output are clearly different (speech-to-text, translation).
Using each type with Hugging Face
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
# Encoder-only: fill in a masked word using both sides of context
fill = pipeline("fill-mask", model="bert-base-uncased")
print(fill("Paris is the [MASK] of France.")[0]["token_str"]) # 'capital'
# Encoder-decoder: text-to-text
t5 = pipeline("text2text-generation", model="google/flan-t5-base")
print(t5("Translate English to German: The house is small.")[0]["generated_text"])
# Decoder-only: continue a prompt
name = "gpt2"
tok = AutoTokenizer.from_pretrained(name)
model = AutoModelForCausalLM.from_pretrained(name)
ids = tok("The Transformer architecture", return_tensors="pt")
out = model.generate(**ids, max_new_tokens=30, do_sample=True, temperature=0.8, top_p=0.9)
print(tok.decode(out[0], skip_special_tokens=True))
How a decoder-only model handles "input"
A common confusion: "If GPT has no encoder, where do K and V come from, and how does it read my question?" Answer: the prompt tokens are simply the first part of the sequence. Q, K and V are all computed from that same sequence. During prefill, all prompt tokens are processed in parallel with the causal mask (each prompt token sees earlier prompt tokens); then generated tokens are appended one at a time. Chat "roles" are just special tokens in a chat template that flatten system, user and assistant messages into one token stream.
Pretraining objectives and data
Pretraining teaches a model general language ability from unlabelled text using self-supervised objectives: the labels are hidden pieces of the text itself, so no human annotation is needed and the data can be trillions of tokens.
Pretraining objectives are different kinds of school exercises built from the same textbook. Causal language modelling is "read the sentence so far and guess the next word", like finishing someone's sentence. Masked language modelling is a fill-in-the-blanks worksheet where you can read the text on both sides of each gap. Span corruption is a worksheet where whole phrases are blacked out and replaced with numbered placeholders, and you must write out what each placeholder hid. Mapping back: the textbook is the unlabelled corpus, the blanks are the self-generated labels, and whichever exercise you practise shapes what you become good at (predicting forward makes you a writer, filling blanks makes you a reader).
Causal language modelling (CLM): GPT, Llama and all chat LLMs
Example: for "The cat sat on the mat" the training pairs are (The → cat), (The cat → sat), (The cat sat → on), and so on, all computed in one pass. If the model assigns probability 0.25 to the true token on average, the loss per token is −ln 0.25 = 1.386 and perplexity is 4.
Masked language modelling (MLM): BERT
Pick 15% of tokens. Of those, replace 80% with [MASK], 10% with a random token and leave 10% unchanged (so the model cannot learn that only [MASK] positions matter, since [MASK] never appears at fine-tuning time). Predict the original tokens using context from both sides. BERT also used Next Sentence Prediction (is sentence B the real continuation of A?), which later work (RoBERTa) found unhelpful and dropped, while gaining from more data, longer training, larger batches and dynamic masking. ELECTRA replaced MLM with "replaced token detection" (a small generator swaps some tokens, the main model classifies every token as original or replaced), which learns from all tokens and is more sample-efficient.
Span corruption and denoising: T5, BART
T5 masks contiguous spans (average length 3, about 15% of tokens), replaces each span with a sentinel token, and the decoder must output the missing spans:
Original : Thank you for inviting me to your party last week. Input : Thank you <X> me to your party <Y> week. Target : <X> for inviting <Y> last <Z>
T5 also cast every task as text-to-text ("translate English to German: ...", "summarize: ...", "cola sentence: ..."), so one model, one loss and one decoding procedure handle classification, translation and summarisation. BART corrupts text with several noise types (masking, deletion, span infilling, sentence shuffling, rotation) and trains the decoder to reconstruct the original. Related: prefix LM (bidirectional attention over a prefix, causal over the rest) and fill-in-the-middle (FIM), where code models are trained on documents rearranged as prefix + suffix → middle so they can complete code inside a file.
| Objective | Context used | Tokens that give loss | Good for |
|---|---|---|---|
| CLM (next token) | Left only | All | Generation, in-context learning, chat |
| MLM | Both sides | ~15% | Understanding, embeddings, classification |
| Replaced token detection | Both sides | All (binary) | Efficient encoder pretraining |
| Span corruption | Both sides (encoder), left (decoder) | Masked spans | Seq2seq tasks |
| Fill-in-the-middle | Prefix + suffix | Middle | Code completion inside files |
Pretraining data
Modern LLMs train on roughly 2-36 trillion tokens mixed from filtered web crawls, code repositories, books, scientific papers, encyclopedias, maths, multilingual text and increasingly synthetic data generated by other models. The data pipeline often matters more than architecture tweaks:
- Extraction Pull clean text out of HTML and PDFs; drop boilerplate.
- Language identification and filtering Heuristics (length, symbol ratios, repetition) and quality classifiers trained to recognise "reference-like" text.
- Deduplication Exact and near-duplicate removal (MinHash). Duplicates waste compute and increase memorisation and regurgitation.
- Safety and privacy Remove personal information, toxic content and known benchmark test sets (decontamination).
- Mixing Choose proportions of web, code, maths and languages; often upweight high-quality sources in a final "annealing" phase.
Training mechanics: AdamW optimizer, learning-rate warm-up then cosine or linear decay, bf16 mixed precision, batches of millions of tokens, and parallelism across thousands of GPUs (data parallel with sharded optimizer states such as ZeRO/FSDP, tensor parallel inside layers, pipeline parallel across layers). A frequent later stage, mid-training or continued pretraining, extends context length and adds more code, maths and reasoning data.
[MASK] appears, and fine-tuning, where it does not). "What is teacher forcing and what is its downside?" (training always conditions on the gold prefix, but at inference the model conditions on its own outputs, so early errors can compound; this is called exposure bias).Scaling laws, Chinchilla and emergent abilities
The single most important empirical discovery about LLMs is that their loss improves predictably as you scale parameters, data and compute. That predictability is why organisations were willing to spend enormous sums on training runs: they could forecast the result from small experiments.
Think of a student preparing for an exam with a fixed number of study hours. Brain capacity is model size; the number of textbook pages read is training data; study hours are compute. A huge brain that reads only a pamphlet underperforms, and so does a small brain forced through a whole library it cannot absorb. For a fixed budget of hours there is a best balance between "bigger brain" and "more pages". Mapping back: the Chinchilla result is that balance point, about 20 training tokens per parameter, and the scaling-law curve is the predictable improvement you get as the hour budget grows.
Power laws
Early scaling studies (2020) found that test loss falls as a power law in each of parameters N, data D and compute C when the other factors are not bottlenecks, over many orders of magnitude. Doubling compute gives a roughly constant fractional improvement in loss. A later, widely used form models both together:
Chinchilla: most early LLMs were undertrained
The 2022 Chinchilla study trained over 400 models and concluded that, for compute-optimal training, parameters and tokens should grow in equal proportion: roughly 20 tokens per parameter. GPT-3 (175B parameters, about 300B tokens, under 2 tokens per parameter) and a 280B-parameter model trained on 300B tokens were far from that. A 70B model trained on 1.4T tokens with the same compute outperformed the 280B model across benchmarks, while being 4x cheaper to serve.
| Model size | Compute-optimal tokens (≈20×N) | Approx. training FLOPs (6ND) |
|---|---|---|
| 1B | 20B | 1.2×1020 |
| 7B | 140B | 5.9×1021 |
| 70B | 1.4T | 5.9×1023 |
| 400B | 8T | 1.9×1025 |
Beyond Chinchilla: overtraining for inference
Chinchilla optimises training compute only. But a model that serves billions of requests pays inference cost (about 2N FLOPs per token) forever. So modern open models deliberately train small models far past the Chinchilla point: Llama 3 8B saw about 15T tokens, close to 1,900 tokens per parameter. Loss keeps improving slowly, and the result is a small, cheap model of much higher quality. The practical rule became "train the smallest model that reaches the quality you need, on as much good data as you can get". The emerging constraint is running out of high-quality human text, which drives interest in synthetic data, multi-epoch training and multimodal data.
Emergent abilities and in-context learning
Some capabilities appear to switch on abruptly with scale: multi-digit arithmetic, following few-shot examples, chain-of-thought reasoning, translating low-resource languages. GPT-3 (2020) showed in-context learning: with a handful of examples in the prompt and no weight updates, performance rose sharply (for example on closed-book trivia QA from about 64% zero-shot to 71% with 64 examples), and smaller versions benefited far less. Two caveats every strong candidate mentions:
- Metric artefacts. Some "sudden" jumps come from all-or-nothing metrics like exact match. Measured with smooth metrics (per-token log-likelihood, partial credit), improvement is often gradual and predictable.
- Loss is predictable, abilities less so. Scaling laws forecast next-token loss well, but which downstream task improves at which scale is much harder to predict.
The LLM training pipeline: pretraining, SFT and preference alignment
A raw pretrained model is a brilliant autocomplete, not an assistant. Turning it into a helpful, honest and safe chatbot takes several further stages. This section gives the conceptual picture; the hands-on techniques (LoRA, QLoRA, dataset formats, training scripts) are covered in Fine-Tuning.
Training an LLM is like training a doctor. Pretraining is years of reading every medical book and journal: enormous knowledge, but no bedside manner. Supervised fine-tuning is residency, where the trainee watches senior doctors handle real patients and imitates their answers. Preference alignment is patient and peer feedback: for two ways of explaining a diagnosis, which one was clearer, kinder and more accurate? Over time the doctor learns what people actually prefer. Mapping back: books are the pretraining corpus, residency examples are instruction-response pairs, and the feedback comparing two explanations is the preference data used by RLHF or DPO.
┌────────────────────┐ ┌───────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────┐
│ 1. PRETRAINING │ │ 2. SUPERVISED FINE- │ │ 3. PREFERENCE ALIGNMENT │ │ 4. REASONING RL │
│ trillions of tokens│──▶│ TUNING (SFT) │──▶│ RLHF: reward model+PPO │──▶│ (optional) │
│ next-token loss │ │ 10K-1M+ instruction / │ │ or DPO / other direct │ │ RL on verifiable │
│ → BASE model │ │ chat demonstrations │ │ preference methods │ │ rewards (maths,code)│
│ weeks-months, │ │ → follows instructions│ │ → helpful, harmless, │ │ → long chain-of- │
│ thousands of GPUs │ │ in chat format │ │ preferred style │ │ thought reasoning │
└────────────────────┘ └───────────────────────┘ └──────────────────────────┘ └──────────────────────┘
~99% of compute small small growing share
Stage 2: supervised fine-tuning (instruction tuning)
Train the base model on curated (prompt, ideal response) pairs covering questions, instructions, coding, maths, refusals and multi-turn chats, formatted with the model's chat template. The loss is the same next-token cross-entropy, but usually computed only on the response tokens (prompt tokens are masked out of the loss). Quality beats quantity: a few thousand excellent, diverse examples can dramatically change behaviour. Instruction tuning on many tasks (the FLAN line of work) also improves zero-shot generalisation to unseen tasks.
Stage 3a: RLHF (reinforcement learning from human feedback)
- Collect comparisons For each prompt, sample two or more responses from the SFT model; human labelers rank them.
- Train a reward model Usually the SFT model with a scalar head, trained so the preferred response scores higher:
L = −log σ(r(x, yw) − r(x, yl))(the Bradley-Terry model). - Optimise the policy with RL Generate responses, score them with the reward model, and update the LLM with PPO to increase reward, while a KL penalty keeps it close to the SFT model.
The landmark result: labelers preferred outputs of a 1.3B instruction-following model aligned this way over the raw 175B base model, showing that alignment can matter more than size for usefulness. This recipe is what turned GPT-3 into the first widely used chat assistant in late 2022.
Stage 3b: DPO and other direct preference methods
RLHF with PPO is complex: four models in memory (policy, reference, reward, value), unstable training, many hyperparameters. Direct Preference Optimization (DPO) shows that the optimal policy for the KL-regularised objective can be written in closed form, so you can skip the reward model and RL loop and train directly on preference pairs with a classification-style loss:
| RLHF (PPO) | DPO | |
|---|---|---|
| Reward model | Explicit, trained separately | Implicit in the policy |
| Training loop | Online RL: sample, score, update | Offline supervised loss on fixed pairs |
| Complexity and memory | High (policy, reference, reward, value models) | Low (policy + reference) |
| Stability | Sensitive to hyperparameters | Stable, simple |
| Strength | Can explore new responses online; reusable reward model | Cheap and easy; very popular for open models |
Related methods: RLAIF and Constitutional AI use an AI model, guided by a written set of principles, to produce the preference labels instead of (or in addition to) humans; IPO, KTO, ORPO, SimPO are DPO variants (KTO needs only thumbs-up/thumbs-down labels, ORPO merges SFT and preference steps); rejection sampling fine-tuning samples many responses, keeps the best by a reward model and fine-tunes on them.
Stage 4: reinforcement learning for reasoning
For maths, code and logic, correctness can be checked automatically (unit tests pass, final answer matches). Training with RL against these verifiable rewards teaches models to produce long chains of thought, check themselves and backtrack. GRPO (group relative policy optimization) is a popular PPO variant for this: it samples a group of answers per prompt and uses each answer's reward relative to the group average as its advantage, removing the need for a separate value model. See the reasoning-models section below.
Decoding strategies with worked examples
At each step the model outputs a vector of logits, one raw score per vocabulary token. A decoding strategy turns those logits into the next token; the token is appended and the loop repeats until an end-of-sequence token, a stop sequence or the token limit. The model's weights define a probability distribution; decoding decides how to use it. Temperature and friends are not part of the model and have nothing to do with Q, K or V.
Picture a jazz musician choosing the next note. Greedy decoding always plays the single most expected note: correct but boring, and it can get stuck repeating a riff. Beam search plans a few bars ahead, comparing several candidate phrases before committing. Temperature is how adventurous the musician feels tonight: low temperature plays it safe, high temperature takes risks, and too high sounds like noise. Top-k and top-p are the rule "only choose from notes that fit the key": top-k allows a fixed number of candidate notes, top-p allows however many notes make up most of what would sound right. Mapping back: notes are tokens, "most expected" is the highest logit, and the rules are filters applied to the probability distribution before sampling.
The pipeline, in order
- Logits Forward pass returns logits z for the last position.
- Logit processors Apply repetition, frequency and presence penalties, logit bias, and any grammar or JSON constraint masks (disallowed tokens set to −∞).
- Temperature Divide logits by T.
- Truncation Keep only candidates allowed by top-k, top-p or min-p; renormalise.
- Select Take the argmax (greedy) or sample from the remaining distribution.
- Stop check Stop on EOS, a stop sequence or
max_tokens; otherwise append and repeat.
Greedy and beam search (deterministic)
Greedy picks argmax at every step. Fast and deterministic, but locally optimal choices can lead to a worse overall sequence, and it tends to fall into repetitive loops in open-ended text.
Beam search keeps the B highest-probability partial sequences (the beam) at each step, expands each by every token, and keeps the best B by total log-probability. Worked example with a tiny tree:
| Step 1 options | Step 2 continuations | Sequence probability |
|---|---|---|
| A (0.5) | x (0.4), y (0.3), others | A x = 0.20, A y = 0.15 |
| B (0.4) | z (0.9), w (0.1) | B z = 0.36, B w = 0.04 |
| C (0.1) | ... | ≤ 0.10 |
Greedy picks A (0.5), then x, ending with probability 0.20. Beam search with B = 2 keeps {A, B} after step 1, expands both, and keeps {B z = 0.36, A x = 0.20}: it finds the better sequence B z that greedy missed. Beam search still is not guaranteed to find the global optimum. It is good for tasks with one right answer (translation, summarisation, speech recognition) but in open-ended generation it produces bland, generic and repetitive text, because the highest-probability text is often not the most human-like. Long outputs get lower total probability, so a length penalty (dividing the log-probability by lengthα) is used to avoid favouring short outputs.
Temperature
Worked example with logits [2, 1, 0] for tokens [Paris, Lyon, cheese]:
| T | Scaled logits | exp values | Probabilities |
|---|---|---|---|
| 0.5 | [4, 2, 0] | [54.60, 7.39, 1.00], sum 62.99 | [0.867, 0.117, 0.016] |
| 1.0 | [2, 1, 0] | [7.39, 2.72, 1.00], sum 11.11 | [0.665, 0.245, 0.090] |
| 2.0 | [1, 0.5, 0] | [2.72, 1.65, 1.00], sum 5.37 | [0.506, 0.307, 0.186] |
At T = 2 the absurd option "cheese" is sampled almost one time in five. Typical settings: 0-0.3 for extraction, classification, code and maths; about 0.7 for general assistant chat; 0.9-1.2 for creative writing and brainstorming. Note that even T = 0 is not always perfectly reproducible on hosted APIs because of batching and floating-point non-determinism on GPUs.
Top-k, top-p (nucleus) and min-p
Pure sampling at T = 1 occasionally picks a very unlikely token from the long tail of a 100K-token vocabulary, and one bad token can derail the rest of the text. Truncation methods cut the tail. Example distribution after "I drank a cup of":
| Token | tea | coffee | water | milk | juice | soup | ink |
|---|---|---|---|---|---|---|---|
| Probability | 0.40 | 0.30 | 0.12 | 0.08 | 0.05 | 0.03 | 0.02 |
| Cumulative | 0.40 | 0.70 | 0.82 | 0.90 | 0.95 | 0.98 | 1.00 |
- Top-k (k = 3): keep tea, coffee, water (total 0.82) and renormalise: tea 0.40/0.82 = 0.488, coffee 0.366, water 0.146. Weakness: k is fixed. When the model is very sure (one token at 0.97), k = 3 still lets in two junk tokens; when it is unsure (50 reasonable options), k = 3 cuts valid choices.
- Top-p (p = 0.9): keep the smallest set whose cumulative probability reaches 0.9: tea, coffee, water, milk (0.90). Renormalised: 0.444, 0.333, 0.133, 0.089. The set size adapts: confident distributions give a tiny nucleus, flat distributions a large one. Typical p = 0.9-0.95.
- Min-p (min_p = 0.1): keep tokens whose probability is at least min_p times the top token's probability: threshold 0.1 × 0.40 = 0.04, so tea, coffee, water, milk, juice survive. Min-p scales with the model's confidence and stays coherent at higher temperatures, which makes it popular in open-source inference engines.
- Others: typical sampling (keep tokens whose information content is close to the expected value), and contrastive search (penalise candidates too similar to earlier context).
Repetition, frequency and presence penalties
| Control | Rule | Typical values |
|---|---|---|
| Repetition penalty (multiplicative, Hugging Face style) | For every token already in the context: positive logit divided by ρ, negative logit multiplied by ρ. Example: logit 3.0 with ρ = 1.3 → 2.31; logit −1.0 → −1.3 | 1.0 (off) to 1.3 |
| Frequency penalty (additive, OpenAI style) | logit −= α × count(token so far). Grows with each repeat | 0-2 (0.1-0.8 common) |
| Presence penalty | logit −= β if the token has appeared at all (binary). Encourages new topics | 0-2 |
| No-repeat n-gram | Forbid any n-gram (for example 3 tokens) from appearing twice | n = 3 or 4 |
Penalties that are too strong cause strange word choices, because the model is prevented from reusing necessary words like "the", variable names in code or a person's name.
Length, stop sequences and constrained decoding
max_tokens/max_new_tokensis a hard cap on generated tokens; it controls cost and latency but truncates mid-sentence if hit (check the finish reason).- Stop sequences end generation when a string appears, for example
"\nUser:"in a transcript format or a closing code fence. The stop text is usually not included in the output. - Constrained decoding masks logits of tokens that would violate a grammar or JSON schema, so the output is guaranteed to parse. This is how structured-output modes work (details in LLM APIs).
Code: controlling generation
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
tok = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2").eval()
ids = tok("Once upon a time", return_tensors="pt")
greedy = model.generate(**ids, max_new_tokens=40, do_sample=False)
beam = model.generate(**ids, max_new_tokens=40, num_beams=4, length_penalty=1.0,
no_repeat_ngram_size=3, early_stopping=True)
sample = model.generate(**ids, max_new_tokens=40, do_sample=True,
temperature=0.8, top_p=0.9, top_k=0, repetition_penalty=1.15)
# A minimal top-p sampler, to show the mechanics
import torch
def sample_top_p(logits, p=0.9, temperature=0.8):
probs = torch.softmax(logits / temperature, dim=-1)
sorted_p, idx = torch.sort(probs, descending=True)
cum = sorted_p.cumsum(-1)
sorted_p[cum - sorted_p > p] = 0.0 # drop tokens after the nucleus is complete
sorted_p /= sorted_p.sum()
return idx[torch.multinomial(sorted_p, 1)]
| Use case | Suggested starting point |
|---|---|
| Extraction, classification, JSON | T = 0 (greedy), schema-constrained output, tight max_tokens |
| Code generation | T = 0-0.2, stop sequences, top-p 0.95 if sampling multiple candidates |
| Factual Q&A / assistant | T = 0.3-0.7, top-p 0.9 |
| Creative writing | T = 0.9-1.2, top-p 0.95 or min-p 0.05-0.1, mild presence penalty |
| Translation, summarisation (seq2seq) | Beam search, B = 4-5, length penalty |
| Self-consistency / best-of-N | T = 0.7-1.0 to get diverse candidates, then vote or rank |
Inference, the KV cache and long context
Serving an LLM has two very different phases. Prefill processes the whole prompt in one parallel forward pass; it is compute-bound and determines time-to-first-token. Decode generates one token per forward pass; each step must read all the model weights from GPU memory to do a small amount of maths, so it is memory-bandwidth-bound and determines tokens per second.
Imagine writing a long essay where, before adding each new word, you had to re-read the entire essay from the start and re-derive your notes about every sentence. That is generation without a cache. With a cache, you keep a notebook with a summary card for every sentence already written; to add a word you only write one new card and glance over the existing cards. Mapping back: the cards are the stored key and value vectors of previous tokens, writing one new card is computing K and V for the newest token only, and the notebook growing thicker with every word is the KV cache's memory growing linearly with context length.
The KV cache
In a decoder, the keys and values of past tokens never change (the causal mask means later tokens cannot affect earlier ones). So after computing them once, store them. At each decode step, compute Q, K, V for the new token only, append its K and V to the cache, and attend with a single query row over all cached keys. Per-step attention work drops from recomputing an n × n matrix to an n-length vector, turning generation from roughly quadratic to linear total work in the attention part.
This formula explains most of LLM serving engineering: long contexts and big batches are limited by cache memory, not by weights. Techniques that attack it:
GQA / MQA / MLA
Share or compress keys and values across heads so fewer are stored (next section).
PagedAttention
Store the cache in fixed-size blocks like virtual-memory pages, avoiding fragmentation and allowing sharing of common prefixes; popularised by the vLLM serving engine.
KV cache quantization
Store K and V in 8-bit or 4-bit instead of 16-bit, halving or quartering cache memory with small quality loss.
Prefix / prompt caching
Reuse the cache of a shared system prompt or document across requests; skips prefill for that part and is why providers discount cached input tokens.
Sliding-window and eviction
Keep only recent tokens (plus a few initial "attention sink" tokens) for streaming use; loses distant information.
Offloading
Move cold cache blocks to CPU memory or disk; used for very long contexts at the cost of latency.
Other serving speed-ups
- Continuous (in-flight) batching: add new requests to the batch as soon as others finish, instead of waiting for the whole batch; raises GPU utilisation dramatically.
- Speculative decoding: a small draft model (or extra prediction heads) proposes several tokens; the big model verifies them all in one parallel pass and accepts the longest correct prefix. Output distribution is unchanged; speed-ups of 2-3x are common when the draft agrees often.
- Weight quantization: 8-bit or 4-bit weights (GPTQ, AWQ, GGUF formats) cut memory and, because decode is bandwidth-bound, raise tokens per second almost proportionally. Details in Edge AI.
- Rough throughput rule for decode: tokens/s per sequence ≈ memory bandwidth / bytes of weights read per token. A 7B model in fp16 (14 GB) on a GPU with 2 TB/s bandwidth tops out around 140 tokens/s at batch size 1.
# Hugging Face uses the KV cache automatically (use_cache=True by default).
# Manual loop to make the mechanics visible:
past, ids = None, tok("The KV cache", return_tensors="pt").input_ids
for _ in range(20):
out = model(input_ids=ids if past is None else ids[:, -1:], past_key_values=past, use_cache=True)
past = out.past_key_values # grows by one position per step
next_id = out.logits[:, -1].argmax(-1, keepdim=True)
ids = torch.cat([ids, next_id], dim=-1)
Context windows
The context window is the maximum number of tokens (prompt plus output) the model can attend to in one pass. It grew from 512 (BERT) and 2,048 (GPT-3) to 128K-200K for many current models and 1M or more for some. The model has no memory between calls: chat "memory" is just the application re-sending the conversation (or a summary of it) every time.
Why long context is hard
- Quadratic attention Score computation is O(n2) in time; naive memory is O(n2) too (FlashAttention fixes the memory part, not the time).
- KV cache Grows linearly with n and often dominates GPU memory.
- Position generalisation Models trained on 4K positions do not automatically work at 32K; positions they never saw behave unpredictably.
- Effective use Even when a model accepts 128K tokens, retrieval of facts from the middle is weaker than from the start or end ("lost in the middle"), and multi-fact reasoning across long inputs degrades well before the nominal limit.
- Training data Truly long, coherent documents are rare, so long-context skills need targeted data (books, code repositories, synthetic long tasks).
Long-context techniques
| Technique | Idea |
|---|---|
| RoPE scaling (position interpolation, NTK-aware, YaRN) + long fine-tune | Stretch rotary frequencies so longer positions map into the trained range, then continue training briefly on long sequences |
| Progressive length training | Pretrain mostly at 4-8K, then extend in stages (32K, 128K) during mid-training |
| FlashAttention | Exact attention with linear memory, making long sequences fit |
| Sliding-window / local attention, sparse patterns | Each token attends to a window instead of everything; stacking layers still spreads information further |
| Hybrid layers | Mix a few full-attention layers with many local-attention or state-space (for example Mamba-style) layers to cut cost |
| Ring / context parallelism | Split one long sequence across many GPUs and pass K/V blocks around a ring |
| Attention sinks (streaming) | Keep the first few tokens in cache permanently plus a recent window; allows endless streaming with stable perplexity |
| Retrieval instead of stuffing | Put only relevant chunks into context (see RAG); cheaper and often more accurate than dumping everything |
Efficient attention: FlashAttention, MQA/GQA, sliding window and sparse patterns
Standard attention has two costs: compute that grows as n2, and memory traffic from writing and re-reading the n × n score matrix. It also produces a large KV cache at inference. Different techniques target different costs, and interviewers like candidates who can say exactly which one each technique attacks.
A chef (the GPU's compute units) works at a small countertop (fast on-chip memory, SRAM) next to a big but distant pantry (slow high-bandwidth memory, HBM). Naive attention carries every intermediate bowl back to the pantry and fetches it again for the next step: most of the time is spent walking. FlashAttention prepares the dish in batches that fit on the countertop and only sends the finished plate back, so the walking disappears while the recipe is identical. Grouped-query attention is like several cooks sharing one set of spice jars instead of each keeping their own: less shelf space (KV cache) with almost the same flavour. Mapping back: countertop = SRAM, pantry = HBM, walking = memory I/O, spice jars = key and value heads.
FlashAttention (exact, I/O-aware)
FlashAttention computes exactly the same result as standard attention, but tiles Q, K and V into blocks that fit in on-chip SRAM, computes the scores and softmax for a block, multiplies by V, and accumulates the output using an online softmax (keeping a running maximum and running sum so blocks can be combined correctly). The full n × n matrix is never written to slow memory. In the backward pass it recomputes the scores rather than storing them. Result: memory O(n) instead of O(n2), 2-4x wall-clock speed-ups, and much longer feasible sequences. FLOPs are still O(n2d): it is faster because attention was memory-bound, not because it does less maths. Versions 2 and 3 improved parallelism and use newer GPU features. In PyTorch you get it through F.scaled_dot_product_attention.
Multi-query and grouped-query attention (smaller KV cache)
Multi-head (MHA) Grouped-query (GQA, 2 groups) Multi-query (MQA)
Q: q1 q2 q3 q4 Q: q1 q2 q3 q4 Q: q1 q2 q3 q4
| | | | \ / \ / \ \ / /
K: k1 k2 k3 k4 K: k1 k2 K: k1
V: v1 v2 v3 v4 V: v1 v2 V: v1
KV cache: 4 heads KV cache: 2 heads KV cache: 1 head
- MQA: all query heads share a single K and V head. KV cache shrinks by a factor of h (for example 32x). Some quality loss and training instability.
- GQA: query heads are split into g groups, each group shares one K/V head (for example 32 query heads, 8 KV heads). Near-MHA quality with 4x smaller cache. Default in Llama 2 70B, Llama 3, Mistral, Qwen and many more. Existing MHA checkpoints can be converted by averaging K/V heads and briefly continuing training ("uptraining").
- MLA (multi-head latent attention): used by DeepSeek-V2/V3. Keys and values are compressed into a small shared latent vector per token that is cached; per-head K and V are reconstructed from it. Cache is far smaller than MHA with comparable or better quality.
Sliding-window (local) attention
Each token attends only to the previous w tokens (for example w = 4,096 in Mistral 7B). Cost becomes O(n·w) and the KV cache can be a fixed-size rolling buffer. Information still travels further than w because it hops through layers: after L layers the theoretical receptive field is about L × w. Many models interleave local layers with global (full) layers, for example several sliding-window layers per full-attention layer, to keep long-range ability.
Sparse attention patterns
Sparse transformers restrict which query-key pairs are computed: strided and fixed patterns; Longformer (local window plus a few global tokens such as [CLS] that attend to and are attended by everything); BigBird (local + global + random connections, which keeps theoretical expressiveness). These reach O(n) or O(n log n) cost but are harder to implement efficiently on GPUs, and dense attention with FlashAttention often wins in practice for moderate lengths.
Linear attention and state-space models
Linear-attention methods (kernel approximations like Performer, low-rank like Linformer) rewrite softmax attention so cost grows linearly, usually with some quality loss on retrieval-heavy tasks. State-space and recurrent-style models (Mamba, RWKV, RetNet) process sequences with a fixed-size state, giving O(n) training and O(1) memory per generated token; hybrids that combine them with some attention layers are an active area.
| Technique | Attacks | Exact? | Typical use |
|---|---|---|---|
| FlashAttention | Memory I/O and O(n2) activation memory | Yes | Everywhere, training and prefill |
| MQA / GQA / MLA | KV cache size and decode bandwidth | Architecture change | Almost all modern LLMs |
| Sliding window | O(n2) compute and cache growth | Architecture change | Mistral 7B, Gemma 2/3 (interleaved) |
| Sparse (Longformer, BigBird) | O(n2) compute | Architecture change | Long-document encoders |
| Linear attention / SSMs | O(n2) compute, cache growth | Approximation / different model | Research, hybrid models |
| PagedAttention | Cache fragmentation | Yes (memory manager) | Serving engines |
Mixture of Experts (MoE)
A Mixture-of-Experts layer replaces the single feed-forward network in a block with many parallel FFNs ("experts") plus a small router that sends each token to only a few of them. The model can hold far more parameters (knowledge capacity) while each token uses only a fraction of them (compute cost).
A large hospital has dozens of specialist doctors, but a patient does not see all of them. A triage nurse looks at each patient and sends them to the two most relevant specialists. The hospital's total expertise is huge, yet each patient's visit takes only two doctors' time. If the nurse sent everyone to the cardiologist, that doctor would be overwhelmed while others sat idle, so the hospital tracks and balances workloads. Mapping back: specialists are experts (FFNs), the triage nurse is the router, "two specialists" is top-2 routing, total expertise is total parameters, time per visit is active parameters, and workload balancing is the load-balancing loss.
Worked numbers
- Mixtral 8x7B: 8 experts per layer, top-2 routing. About 47B total parameters (not 56B, because attention and embeddings are shared) but only about 13B active per token. Quality comparable to much larger dense models of its time at the inference FLOPs of a 13B model.
- DeepSeek-V3: about 671B total, about 37B active per token, using many small fine-grained experts plus always-on shared experts.
- Other open MoE families include Qwen MoE variants and Llama 4; several frontier closed models are widely reported to be MoE as well.
Engineering challenges
| Challenge | What happens | Mitigation |
|---|---|---|
| Load imbalance / expert collapse | The router learns to favour a few experts; others get no training signal | Auxiliary load-balancing loss; router noise; bias-based balancing without an auxiliary loss (used by DeepSeek-V3) |
| Capacity overflow | Too many tokens routed to one expert in a batch | Capacity factor; overflow tokens skip the expert via the residual (token dropping) or are rerouted |
| Memory | All experts must be in memory even though few are used per token | Expert parallelism across GPUs, offloading, quantization |
| Communication | Tokens must be sent to whichever GPU hosts their expert (all-to-all) | Topology-aware placement, limiting the number of devices per token |
| Fine-tuning instability | Routers can overfit small datasets | Freeze router, lower learning rate, more regularisation |
Dense model
- Every parameter used for every token
- Compute per token ≈ 2 × total parameters
- Simple to train, fine-tune and serve
- Memory = compute footprint
MoE model
- Only the chosen experts run per token
- Compute per token ≈ 2 × active parameters
- More knowledge per FLOP; training and serving are more complex
- Memory set by total parameters, so it is memory-hungry for local use
Multimodal models: ViT, CLIP and vision-language models
Transformers operate on sequences of vectors, and nothing requires those vectors to come from text. If you can turn an image, an audio clip or a video into a sequence of embeddings, the same architecture applies. This section covers the three ideas behind most multimodal systems.
A Vision Transformer reads a photo the way you would read a comic strip cut into square panels: each panel is a "word", and the order of panels matters. CLIP is like a matching game with a stack of photos and a stack of captions, where you learn to pair each photo with its caption and push apart mismatched pairs; after enough games you can describe any photo by picking the closest caption. A vision-language model is a translator who looks at the comic panels, converts them into words the writer understands, and hands them to a novelist who then writes about them. Mapping back: panels are image patches, the matching game is contrastive training, the translator is the projection layer, and the novelist is the LLM.
Vision Transformer (ViT)
- Patchify Split a 224 × 224 image into 16 × 16 patches: (224/16)2 = 196 patches.
- Embed Flatten each patch (16 × 16 × 3 = 768 values) and project it linearly to d dimensions. This is equivalent to a convolution with kernel 16 and stride 16.
- Add position embeddings and a
[CLS]token Learned 2-D-aware position embeddings; the[CLS]output is used for classification. - Run a standard Transformer encoder Bidirectional self-attention over 197 tokens.
ViTs have weaker built-in assumptions (inductive biases) than CNNs: no locality or translation equivariance baked in. So they need more data or strong augmentation, but they scale better and now dominate large vision models. Higher resolution means more patches and quadratic attention cost, so VLMs often tile large images or pool patch tokens.
CLIP: contrastive image-text pretraining
CLIP trains an image encoder and a text encoder together on hundreds of millions of (image, caption) pairs from the web. In a batch of N pairs, it computes the N × N matrix of cosine similarities between every image embedding and every text embedding and applies a symmetric cross-entropy loss so the N true pairs (the diagonal) score highest.
Payoffs: zero-shot classification (embed "a photo of a {class}" for each class and pick the closest to the image embedding, no task-specific training), text-to-image search, and CLIP-style encoders serve as the "eyes" of many VLMs and as text encoders in diffusion image generators.
Vision-language models (VLMs)
| Design | How images enter the LLM | Examples |
|---|---|---|
| Encoder + projector (late fusion) | A pretrained vision encoder (often CLIP/SigLIP-style ViT) produces patch embeddings; a small MLP or resampler projects them into the LLM's embedding space; they are inserted into the token sequence as "visual tokens" | LLaVA family, many open VLMs (Qwen-VL, InternVL) |
| Cross-attention adapters | The LLM stays mostly frozen; new cross-attention layers let text tokens attend to image features | Flamingo-style models, some Llama vision variants |
| Native / early fusion | Images (and audio) are tokenised and trained jointly with text from the start in one model | Gemini and GPT-4o as publicly described; Chameleon-style research models |
Training usually proceeds in stages: align the projector on image-caption pairs with encoder and LLM frozen, then instruction-tune on visual question-answering and conversation data with more of the model unfrozen. Other modalities follow the same pattern: Whisper is an encoder-decoder Transformer from audio spectrograms to text; video models treat frames or spatio-temporal patches as tokens; diffusion transformers (DiT) replace the U-Net in image and video generators with a Transformer over latent patches.
# Zero-shot image classification with CLIP
from transformers import CLIPModel, CLIPProcessor
from PIL import Image
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
proc = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
labels = ["a photo of a cat", "a photo of a dog", "a photo of a car"]
inputs = proc(text=labels, images=Image.open("pet.jpg"), return_tensors="pt", padding=True)
probs = model(**inputs).logits_per_image.softmax(dim=-1) # similarity / temperature, then softmax
print(dict(zip(labels, probs[0].tolist())))
Major model families: a neutral map
Almost every major LLM is a decoder-only Transformer with the ingredients on this page (RoPE or similar, pre-norm, SwiGLU-style FFN, GQA, often MoE). Differences in behaviour come mostly from training data, scale, post-training (alignment choices and style), specialisation (code, reasoning, multimodality), context length and inference infrastructure. Model versions change every few months, so learn the families and their trade-offs rather than memorising version numbers.
Model families are like car manufacturers that all use internal-combustion or electric drivetrains built on the same physics. The engine concept is shared, but each brand tunes suspension, interior, safety systems and price differently, and some sell you the car while others only rent rides. Mapping back: the shared drivetrain is the Transformer architecture, the tuning is data and post-training, "selling the car" is releasing open weights you can run yourself, and "renting rides" is closed models available only through an API.
Milestones that shaped the field
| Year | Model / event | Why it mattered |
|---|---|---|
| 2017 | The Transformer | Attention-only encoder-decoder for translation |
| 2018 | GPT-1 (117M), BERT (110M / 340M) | Pretrain-then-fine-tune; BERT set records on the GLUE benchmark suite |
| 2019 | GPT-2 (1.5B), T5 (up to 11B), BART | Zero-shot task behaviour from prompts; text-to-text framing |
| 2020 | GPT-3 (175B, 2,048-token context) | Few-shot in-context learning; API-served foundation models |
| 2022 | Chinchilla; instruction-following models with RLHF; ChatGPT | Compute-optimal scaling; alignment makes LLMs usable assistants |
| 2023 | GPT-4, Llama and Llama 2, Mistral 7B, Mixtral, Claude 2, Gemini 1.0 | Multimodality; the open-weights wave; open MoE |
| 2024 | Llama 3, Claude 3 and 3.5, Gemini 1.5 (million-token context), GPT-4o, Qwen2.5, DeepSeek-V3, first reasoning models (o1) | Long context, native multimodality, strong open models, test-time reasoning |
| 2025 onward | DeepSeek-R1, further reasoning and agentic models from all major labs | Open reasoning via RL; compute shifts toward inference |
Families at a glance
| Family | Developer | Weights | Notable traits |
|---|---|---|---|
| GPT (and o-series reasoning models) | OpenAI | Closed (plus some open-weight releases) | Pioneered the decoder-only scaling path, in-context learning and RLHF assistants; broad multimodal API ecosystem; separate reasoning-focused models |
| Claude | Anthropic | Closed | Emphasis on safety research and Constitutional AI; long context (200K class); strong at long documents, coding and instruction following; extended-thinking reasoning modes |
| Gemini (and Gemma) | Google DeepMind | Gemini closed; Gemma open weights | Natively multimodal (text, image, audio, video); very long context (up to millions of tokens in some versions); Gemma is a smaller open sibling |
| Llama | Meta | Open weights under a custom licence | Became the reference open model family; sizes from ~1B to 405B dense, later MoE versions; huge fine-tuning ecosystem |
| Mistral / Mixtral | Mistral AI | Mix of Apache-2.0 open models and commercial models | Strong quality per parameter; sliding-window attention; popularised open MoE with Mixtral 8x7B |
| Qwen | Alibaba | Many open weights (Apache-2.0 for most sizes) | Wide range of sizes, strong multilingual (especially Chinese and English), coding, maths and vision-language variants; dense and MoE |
| DeepSeek | DeepSeek | Open weights (permissive licence) | Efficiency innovations: multi-head latent attention, fine-grained MoE with shared experts, FP8 training, multi-token prediction; R1 showed strong reasoning emerging from RL with verifiable rewards |
| Others | Microsoft (Phi), TII (Falcon), AI2 (OLMo, fully open data and code), and many more | Mostly open | Phi: small models trained on curated and synthetic data; OLMo: open training data, code and checkpoints for research |
Open weights vs closed
Open weights
- Run on your own hardware: data never leaves your environment
- Full control: fine-tune, quantize, inspect logits, constrain decoding
- Predictable cost at high volume; no vendor lock-in; version never changes under you
- You own serving, scaling, safety filtering and updates
- Licences vary: "open weights" is not always "open source" (training data and code may be withheld, usage restrictions may apply)
Closed (API)
- Often the most capable frontier models
- No infrastructure to manage; pay per token; fast to prototype
- Provider handles safety systems, scaling and upgrades
- Data leaves your environment (check retention and compliance terms)
- Less control: limited decoding options, models can be updated or retired
Reasoning models and test-time compute
Classic LLM scaling spent compute at training time. Reasoning models add a second axis: spending more compute at inference time by generating a long internal chain of thought (often hidden or summarised) before the final answer. On maths, coding, science and planning problems, accuracy keeps rising as the model is allowed to "think" longer.
A standard LLM answering a hard maths question is like a student forced to blurt out an answer instantly. A reasoning model is the same student allowed scratch paper and ten minutes: they write intermediate steps, notice a mistake, cross it out, try another route and check the result. The knowledge in their head is the same; the extra time and scratch paper change the outcome. Mapping back: scratch paper is the thinking tokens, ten minutes is the thinking budget (test-time compute), and learning when to double-check is what reinforcement learning on verifiable problems trains.
Why generating more tokens helps
A Transformer does a fixed amount of computation per token (one pass through L layers). A hard problem may need more serial computation than one forward pass can provide. Writing intermediate steps turns the output sequence into working memory: each new token is computed with access to all previous reasoning, so the model effectively gets more layers of computation for harder problems. This is why chain-of-thought prompting ("think step by step") improved large models on multi-step problems even before dedicated reasoning models.
Ways to spend test-time compute
| Method | How it works | Cost |
|---|---|---|
| Chain-of-thought | Generate reasoning steps before the answer (prompted or trained) | More output tokens |
| Self-consistency | Sample several reasoning paths at moderate temperature, take the majority final answer | N times the tokens |
| Best-of-N with a verifier | Generate N candidates; a reward model, unit tests or checker picks the best | N times plus verification |
| Tree / search methods | Explore and prune branches of partial solutions, guided by a value or process reward model | High, variable |
| Trained long reasoning (reasoning models) | RL teaches the model to produce long, self-correcting thoughts within one generation, with a configurable thinking budget | Thousands to tens of thousands of hidden tokens on hard tasks |
How reasoning models are trained
- Start from a strong base or instruct model Reasoning ability rides on pretrained knowledge.
- Optional cold-start SFT A small set of high-quality long chain-of-thought examples to establish readable format.
- RL with verifiable rewards Sample many solutions per problem; reward correct final answers (maths answer checks, code unit tests) and correct format. Algorithms such as PPO or GRPO. Behaviours like re-checking, backtracking ("wait, that is wrong") and trying alternatives emerge because they raise reward.
- Distillation Long reasoning traces from a big reasoning model are used to fine-tune smaller models, which gain much of the ability cheaply.
- General alignment Further preference training so the model stays helpful and safe on ordinary tasks.
Outcome vs process rewards: outcome reward models score only the final answer (simple, scalable, but can reward lucky wrong reasoning); process reward models score each step (denser signal, but step labels are expensive and can be gamed).
Trade-offs
- Latency and cost: the major disadvantage. Hidden reasoning tokens are billed and can take many seconds or minutes.
- Overthinking: simple questions may get needlessly long deliberation; route easy queries to fast models or use a low thinking budget.
- Faithfulness: the visible reasoning is not guaranteed to be the real cause of the answer; explanations can be post-hoc rationalisations.
- Not a knowledge fix: reasoning helps with logic and multi-step problems, not with facts the model never learned; reasoning models can still hallucinate, sometimes elaborately.
- Prompting differs: they usually need less "think step by step" prompting and fewer examples; sampling parameters may be fixed by the provider.
Hallucination and the limitations of LLMs
A hallucination is output that is fluent and confident but not supported by facts or by the provided input: invented citations, wrong dates, non-existent API functions, misquoted documents. Understanding why it happens is what separates a good interview answer from "the model makes things up".
An LLM is like a very well-read improv actor who has been trained never to break character and never to say "I don't know". Asked about an obscure book, they will confidently describe a plausible plot, because keeping the scene flowing is what they were rewarded for. Their performance is usually brilliant on famous topics and dangerously smooth on obscure ones. Mapping back: "never break character" is the next-token objective that always produces a likely continuation, "rewarded for flow" is training and evaluation that reward answering over abstaining, and "obscure topics" are long-tail facts seen rarely in training data.
Why LLMs hallucinate
- The objective is plausibility, not truth Pretraining rewards predicting likely text. A fluent false sentence and a fluent true one look similar to the loss.
- Knowledge gaps and cutoffs Facts after the training cutoff, private company data and rare long-tail facts are missing or weakly stored, but the model still produces an answer-shaped continuation.
- Compression Trillions of tokens are compressed into billions of weights; details blur, similar entities merge (the wrong author for a real book, a real journal with a fake article).
- Incentives in post-training and evaluation Benchmarks and human raters often reward a confident answer over "I'm not sure"; models learn to guess.
- Sycophancy Preference training can teach models to agree with the user's framing, including false premises ("Why did X win the prize in 2019?" when X never did).
- Decoding Sampling can pick a low-probability wrong token, and autoregressive generation then commits to it and builds a consistent story around it (snowballing).
- Context problems Relevant information missing from the prompt, contradictory sources, or facts buried in a long context that the model fails to use.
- Exposure bias Trained on gold prefixes, the model has little practice recovering from its own earlier errors.
Note what is not a cause: residual connections, attention weights or Q/K/V matrices do not "cause" hallucination in themselves; it is a property of what the model learned and how it is used.
Mitigation toolkit
| Layer | Technique |
|---|---|
| Grounding | Retrieval-augmented generation with instructions to answer only from provided context and cite sources (RAG); tool use for calculations, search and databases |
| Prompting | Explicitly allow "I don't know"; ask for quotes from the source before answering; break problems into steps (Prompt Engineering) |
| Decoding | Lower temperature for factual tasks; constrained outputs for structured data |
| Verification | Self-consistency checks, a second model or rule-based checker, citation validation against retrieved documents, unit tests for code |
| Training | Fine-tune to abstain when unsure, preference data that rewards honesty, factuality-focused RL |
| Product | Show sources, confidence indicators and human review for high-stakes outputs |
Other limitations to discuss
Tokenization artefacts
Weak at letter counting, spelling backwards, exact arithmetic on long numbers.
Context limits
Finite window, lost-in-the-middle, cost that grows with prompt length.
No persistent memory
Stateless between calls; memory must be engineered (conversation history, summaries, retrieval).
Stale knowledge
Fixed at the training cutoff unless connected to tools or retrieval.
Reasoning brittleness
Performance can drop when a familiar problem is reworded; the "reversal curse" (knowing "A is B" does not guarantee knowing "B is A").
Bias and toxicity
Reflects biases in web-scale training data; alignment reduces but does not remove them.
Security
Prompt injection (instructions hidden in documents or web pages), jailbreaks, data leakage and training-data regurgitation.
Non-determinism and cost
Outputs vary between runs; large models are expensive and slow; evaluation is hard.
Quick revision
- RNNs are sequential (no parallel training), have O(n) paths between distant tokens and suffer vanishing/exploding gradients; seq2seq RNNs also squeeze the whole input into one context vector.
- Attention removed the bottleneck by letting the decoder take a fresh weighted average of all encoder states at every step; the Transformer (2017) removed recurrence entirely.
- Self-attention gives O(1) path length and full parallelism at the cost of O(n2d + nd2) time and O(n2) score-matrix memory (O(n) with FlashAttention).
- Text becomes subword tokens (BPE, WordPiece, Unigram/SentencePiece); English averages about 4 characters or 0.75 words per token; other languages often need more.
- APIs bill per input and output token; output tokens cost more and are generated sequentially; context window = input + output.
- The embedding table is vocab × d; input embeddings are static, hidden states after each layer are contextual.
- Attention is permutation-equivariant, so position must be injected: sinusoidal (added, fixed), learned absolute (added, trainable), RoPE (rotates Q and K, relative), ALiBi (distance penalty on scores).
- RoPE makes the q·k score depend only on relative distance, adds no parameters and can be extended with interpolation, NTK scaling or YaRN plus fine-tuning.
- Attention(Q,K,V) = softmax(QKT/√dk + mask)V; Q, K, V are linear projections of the same input in self-attention.
- Scaling by √dk keeps dot-product variance near 1 so softmax does not saturate and gradients survive.
- Masked positions get −∞ (not 0) before softmax; causal masks block the future, padding masks block filler tokens.
- Attention weights are computed per input; only WQ, WK, WV, WO are learned.
- Multi-head attention splits d into h heads of size d/h, each learning a different relationship; concatenation plus WO merges them at the same parameter cost as one head.
- Cross-attention takes Q from the decoder and K, V from the final encoder layer; decoder-only models do not use it.
- A block is attention + FFN, each wrapped with a residual connection and normalization; modern LLMs use pre-norm with RMSNorm.
- Residuals give gradients an identity path and let each layer learn an additive update to the residual stream.
- Pre-LN is x + F(Norm(x)) (clean residual path, modern default); Post-LN is Norm(x + F(x)) (needs warmup, unstable when very deep).
- LayerNorm normalises each token over features, so it is independent of batch size and sequence length, unlike BatchNorm.
- The FFN expands d → 4d (or about 8d/3 with SwiGLU), applies a non-linearity and projects back; it holds about two-thirds of parameters and acts per token.
- One block has about 12d2 parameters; GPT-2 small = 124M, GPT-3 = 175B can be derived from this. Tying the embedding table to the LM head saves a second |V|·d matrix.
- Encoder-only (BERT) = bidirectional understanding; decoder-only (GPT, Llama) = causal generation; encoder-decoder (T5, BART, Whisper) = sequence transformation.
- CLM predicts the next token at every position (loss on all tokens); MLM predicts 15% masked tokens with the 80/10/10 rule; T5 uses span corruption with sentinel tokens.
- Perplexity = exp(average cross-entropy per token); lower is better.
- Training compute ≈ 6ND FLOPs; inference ≈ 2N FLOPs per generated token.
- Chinchilla: compute-optimal training uses about 20 tokens per parameter; modern small models are deliberately overtrained for cheaper inference.
- Emergent abilities such as in-context learning appear with scale, but some apparent jumps are artefacts of all-or-nothing metrics.
- The pipeline is pretraining → supervised fine-tuning on instructions → preference alignment (RLHF or DPO) → optional RL for reasoning.
- RLHF trains a reward model on human comparisons and optimises the policy with PPO plus a KL penalty to the SFT model to prevent reward hacking.
- DPO optimises the same objective directly on preference pairs with a classification-style loss, without a reward model or RL loop.
- Greedy and beam search are deterministic; beam search suits translation and summarisation but produces bland open-ended text.
- Temperature divides logits before softmax: below 1 sharpens, above 1 flattens, and the ranking never changes.
- Top-k keeps a fixed number of tokens, top-p keeps the smallest set reaching probability p, min-p keeps tokens above a fraction of the top probability.
- Repetition penalty scales logits of seen tokens; frequency penalty subtracts per occurrence; presence penalty subtracts once.
- Prefill is compute-bound (time to first token); decode is memory-bandwidth-bound (tokens per second).
- The KV cache stores past keys and values; size = 2 × layers × KV heads × head dim × tokens × batch × bytes.
- GQA shares K/V heads among groups of query heads (MQA uses one), shrinking the KV cache several-fold with little quality loss; MLA compresses K/V into a latent.
- FlashAttention is exact attention that tiles computation in on-chip memory: O(n) memory and faster, but the same O(n2d) FLOPs.
- Speculative decoding: a draft model proposes several tokens; the target verifies them in one parallel pass (rejection sampling leaves the output distribution unchanged).
- Sliding-window attention limits each token to recent tokens; stacked layers still spread information further.
- Long context is limited by quadratic attention, KV cache memory, position generalisation and "lost in the middle" effects.
- MoE replaces the FFN with many experts and a router choosing top-k per token: huge total parameters, small active parameters, but all experts must fit in memory.
- ViT turns an image into patch tokens; CLIP aligns image and text embeddings with a contrastive loss; VLMs feed projected visual tokens into an LLM.
- Open weights give control, privacy and fine-tuning; closed APIs give frontier capability with no infrastructure; behaviour differences come mainly from data and post-training.
- Reasoning models spend test-time compute on long chains of thought trained with RL on verifiable rewards; the cost is latency and tokens.
- Hallucination comes from a plausibility objective, knowledge gaps, incentives to guess, sycophancy and decoding; grounding and verification reduce it, temperature 0 does not eliminate it.
- Known limitations: tokenization quirks, stale knowledge, finite context, no persistent memory, bias, prompt injection and non-determinism.
Glossary
- ALiBi
- Attention with Linear Biases: adds a head-specific penalty proportional to token distance to attention scores instead of using position embeddings.
- Alignment
- Post-training that makes a model's behaviour match human intent and values (helpful, honest, harmless), for example via RLHF or DPO.
- Attention
- A mechanism that computes a weighted average of value vectors, with weights from query-key similarity.
- Attention sink
- Initial tokens that receive disproportionate attention; keeping them in the cache stabilises streaming generation.
- Autoregressive
- Generating one token at a time, each conditioned on all previously generated tokens.
- Base model
- A model after pretraining only; it continues text rather than following instructions.
- Beam search
- Deterministic decoding that keeps the B most probable partial sequences at every step.
- BPE (Byte-Pair Encoding)
- Tokenizer training method that repeatedly merges the most frequent adjacent symbol pair into a new token.
- Causal language modelling (CLM)
- Pretraining objective of predicting each next token from the tokens before it.
- Causal mask
- Lower-triangular attention mask that prevents a position from attending to future positions.
- Chain-of-thought
- Intermediate reasoning steps written before the final answer, prompted or trained.
- Chinchilla scaling
- Finding that compute-optimal training uses roughly 20 tokens per parameter, scaling model and data together.
- CLIP
- A model that learns a shared image-text embedding space with a contrastive loss, enabling zero-shot image classification.
- Context window
- Maximum number of tokens (input plus output) a model can attend to in one pass.
- Continuous batching
- Serving technique that adds and removes requests from a running batch at every step to keep the GPU busy.
- Cross-attention
- Attention with queries from one sequence (decoder) and keys/values from another (encoder output).
- Cross-entropy loss
- Negative log-probability assigned to the correct token, averaged over positions.
- Decoder-only
- Transformer with only causally masked self-attention blocks, used by GPT-style LLMs.
- DPO (Direct Preference Optimization)
- Alignment method that trains directly on preferred/rejected response pairs without a separate reward model or RL loop.
- Embedding
- A learned dense vector representing a token (input embedding) or a piece of content (sentence embedding).
- Emergent ability
- A capability that appears only in models above a certain scale, such as in-context learning.
- Encoder-decoder
- Transformer with a bidirectional encoder for the input and a causal decoder with cross-attention for the output (T5, BART).
- Encoder-only
- Transformer with bidirectional self-attention only, used for understanding tasks and embeddings (BERT).
- Exposure bias
- Mismatch between training on gold prefixes (teacher forcing) and generating from the model's own possibly wrong outputs.
- Feed-forward network (FFN)
- The per-token two-layer MLP in each block that expands, applies a non-linearity and projects back.
- FlashAttention
- Exact, I/O-aware attention kernel that tiles work in on-chip memory to avoid materialising the n × n matrix.
- Frequency penalty
- Decoding control that lowers a token's logit in proportion to how often it has already appeared.
- GQA (Grouped-Query Attention)
- Attention variant where groups of query heads share one key/value head to shrink the KV cache.
- Greedy decoding
- Always choosing the highest-probability next token.
- GRPO
- Group Relative Policy Optimization: RL method that scores each sampled answer relative to its group's average reward, used for reasoning training.
- Hallucination
- Fluent output that is not supported by facts or by the provided context.
- In-context learning
- Performing a new task from instructions or examples in the prompt without updating weights.
- Induction head
- An attention-head circuit that finds a previous occurrence of the current token and copies what followed it.
- Instruction tuning
- Supervised fine-tuning on instruction-response pairs so a model follows requests.
- KL penalty
- Term in RLHF that penalises the policy for drifting too far from the reference model.
- KV cache
- Stored keys and values of previous tokens, reused at each decoding step to avoid recomputation.
- Layer normalization
- Normalising each token's features to zero mean and unit variance, then applying learned scale and shift.
- Logits
- Raw, unnormalised scores for every vocabulary token before softmax.
- Lost in the middle
- Tendency of models to use information at the start and end of a long context more reliably than information in the middle.
- Masked language modelling (MLM)
- Pretraining objective of predicting randomly masked tokens using context on both sides.
- Min-p sampling
- Truncation that keeps tokens whose probability is at least a fraction of the most likely token's probability.
- Mixture of Experts (MoE)
- Architecture where a router sends each token to a few of many expert FFNs, decoupling total and active parameters.
- MLA (Multi-head Latent Attention)
- Attention variant that caches a compressed latent per token from which keys and values are reconstructed.
- MQA (Multi-Query Attention)
- Attention variant in which all query heads share a single key and value head.
- Multi-head attention
- Several attention operations in parallel with separate projections, concatenated and projected by WO.
- Open weights
- Model parameters released for download and self-hosting, possibly under licence restrictions and without training data.
- PagedAttention
- Memory manager that stores the KV cache in fixed-size blocks to avoid fragmentation and share prefixes.
- Perplexity
- Exponential of the average per-token cross-entropy; the effective number of choices the model is unsure between.
- Positional encoding
- Any method of giving a Transformer information about token order.
- Pre-LN / Post-LN
- Placement of normalization before the sub-layer inside the residual branch (Pre-LN) or after the residual addition (Post-LN).
- Prefill
- The parallel forward pass over the prompt that fills the KV cache and produces the first token.
- Presence penalty
- Decoding control that lowers a token's logit by a fixed amount once it has appeared at all.
- Prompt caching
- Reusing the computed KV cache of a repeated prompt prefix across requests.
- QK-norm
- Layer- or RMS-normalizing queries and keys before the dot product to stop attention logits from growing with depth.
- Repetition penalty
- Multiplicative decoding control that makes already-seen tokens less likely.
- Residual connection
- Adding a sub-layer's input to its output (x + f(x)), giving gradients an identity path.
- Residual stream
- The per-token vector flowing through the network that every sub-layer reads from and adds to.
- Reward hacking
- A policy exploiting flaws in the reward model to get high scores without genuinely better outputs.
- Reward model
- Model trained on human comparisons to score responses, used as the objective in RLHF.
- RLHF
- Reinforcement Learning from Human Feedback: reward model from human preferences plus RL (typically PPO) to optimise the LLM.
- RMSNorm
- Simplified normalization that rescales by the root-mean-square of features without subtracting the mean.
- RoPE
- Rotary Position Embedding: rotates query and key dimension pairs by position-dependent angles so scores depend on relative distance.
- Scaling laws
- Empirical power-law relationships between loss and model size, data and compute.
- Self-attention
- Attention in which queries, keys and values all come from the same sequence.
- Self-consistency
- Sampling several reasoning paths and choosing the most common final answer.
- Sliding-window attention
- Local attention in which each token attends only to the previous w tokens.
- Span corruption
- T5's objective of replacing spans with sentinel tokens and generating the missing spans.
- Speculative decoding
- A draft model proposes several tokens that the large model verifies in parallel, speeding generation without changing outputs.
- Supervised fine-tuning (SFT)
- Training on curated input-output demonstrations with the standard next-token loss.
- SwiGLU
- Gated FFN variant: W2(SiLU(W1x) ⊙ W3x), used in most modern LLMs.
- Teacher forcing
- Training a sequence model by always feeding the true previous tokens rather than its own predictions.
- Temperature
- Divisor applied to logits before softmax that controls how peaked or flat the sampling distribution is.
- Test-time compute
- Extra computation spent at inference (longer reasoning, sampling, search) to improve answers.
- Token
- The unit of text a model reads and writes, typically a subword piece mapped to an integer ID.
- Top-k sampling
- Sampling only from the k most probable next tokens after renormalising.
- Top-p (nucleus) sampling
- Sampling from the smallest set of tokens whose cumulative probability reaches p.
- Vision Transformer (ViT)
- Transformer encoder applied to sequences of image patches.
- Weight tying
- Sharing the token-embedding matrix with the output LM head (Wout = E), saving |V|·d parameters.
- WordPiece
- BERT's subword tokenizer, which chooses merges by likelihood gain and marks continuations with ##.
Interview questions
Fundamentals
What is a Transformer, in one or two sentences?
A neural-network architecture that processes a sequence of token vectors with stacked blocks of self-attention (which lets every token gather information from every other token) and position-wise feed-forward networks, with residual connections and normalization. It has no recurrence, so all positions are processed in parallel during training, and order is supplied through positional encoding.
What is a large language model?
A Transformer (almost always decoder-only) with billions of parameters trained on trillions of tokens to predict the next token, then usually fine-tuned on instructions and aligned with human preferences. At inference it generates text autoregressively: predict a distribution over the vocabulary, pick a token, append it, repeat. Its knowledge lives in its weights; what it can see at once is limited by its context window.
Why did Transformers replace RNNs and LSTMs?
- Parallelism: RNNs must process tokens one after another; Transformers process all positions at once, which uses GPUs efficiently and made scaling possible.
- Long-range dependencies: any two tokens are connected in one attention step (O(1) path) instead of passing through n hidden-state updates.
- Stable gradients: no repeated multiplication through time; residuals and normalization make deep stacks trainable.
- No fixed-size bottleneck: every token keeps its own representation.
The trade-off is O(n2) cost in sequence length.
What was the context-vector bottleneck in seq2seq RNNs, and how did attention solve it?
The encoder compressed the entire input sentence into its final hidden state, a single fixed-size vector, and the decoder generated everything from it, so information about long inputs was lost. Attention keeps all encoder hidden states and, at every decoder step, computes a new weighted average of them based on relevance to the current decoding state. Each output token gets its own context, focused on the relevant source words.
What are long-range dependencies? Give an example.
Relationships between words far apart in a sequence. In "The dog that chased the cat all around the garden was hungry", the verb "was" agrees with "dog", many words earlier. In "The animal didn't cross the street because it was too tired", "it" refers to "animal". Models must connect such distant positions to understand meaning; RNNs struggle because the signal decays over many steps, while attention links them directly.
What is a token, and why do LLMs use subword tokens instead of words or characters?
A token is the unit a model reads and writes, mapped to an integer ID. Word vocabularies are huge and cannot represent new or misspelled words (out-of-vocabulary problem). Character vocabularies make sequences very long and push more work onto the model. Subwords (BPE, WordPiece, Unigram) keep common words whole and split rare ones into reusable pieces, balancing vocabulary size (32K-256K) against sequence length, and can encode any string (byte-level BPE never needs an unknown token).
How does Byte-Pair Encoding work?
Start with a vocabulary of characters (or bytes) and split the training corpus into them. Count all adjacent symbol pairs, merge the most frequent pair into a new symbol, record the merge, and repeat until the vocabulary reaches the target size. To tokenize new text, apply the learned merges in order. Frequent words end up as single tokens; rare words decompose into subword pieces.
Roughly how many tokens is 1,000 English words, and why does it matter?
About 1,300-1,400 tokens (a token is about 0.75 words or 4 characters in English). It matters because context windows, rate limits and API prices are in tokens. Other languages and code can need considerably more tokens per word, and each model's tokenizer gives different counts, so measure with the model's own tokenizer.
What is an embedding layer?
A learnable lookup table of shape vocabulary size × dmodel. Each token ID selects its row, producing a dense vector. The rows start random and are trained by backpropagation so that tokens used in similar ways get similar vectors. It is equivalent to multiplying a one-hot vector by a weight matrix, but implemented as an index lookup.
What is the difference between static and contextual embeddings?
Static embeddings (Word2Vec, GloVe, or a Transformer's input embedding table) give one vector per word regardless of context, so "bank" has the same vector in "river bank" and "bank account". Contextual embeddings (hidden states from ELMo, BERT, GPT layers) are computed from the whole sentence, so the same word gets different vectors in different contexts, which resolves ambiguity.
Why do we need an encoder (or Transformer layers at all) if we already have good pretrained word embeddings?
Pretrained word embeddings are static: they carry no information about the specific sentence. The Transformer layers update each token's vector using self-attention over its neighbours, producing context-aware representations that capture word sense, syntax, coreference and long-range relations. Feeding static vectors directly to a decoder would lose all of that and performance drops sharply.
What are Query, Key and Value?
Three vectors computed from each token by learned linear projections. The query represents what this token is looking for, the key represents what the token offers to others, and the value is the information it passes on when attended to. Attention scores are query-key dot products; outputs are weighted sums of values.
Write the scaled dot-product attention formula and explain each part.
Attention(Q,K,V) = softmax(QKT / √dk) V. QKT gives an n × n matrix of similarity scores between every query and every key. Dividing by √dk keeps scores in a range where softmax is not saturated. Softmax (row-wise) turns each row into positive weights summing to 1. Multiplying by V produces, for each token, a weighted average of all value vectors. In decoders a mask adds −∞ to future positions before softmax.
What is self-attention, in plain language?
A step in which every token in a sequence looks at every other token in the same sequence, decides how relevant each one is, and builds a new version of itself as a relevance-weighted blend of their information. For "it" in "The animal didn't cross the street because it was too tired", it assigns high weight to "animal", so the new representation of "it" carries the meaning of the animal.
What is the difference between an attention score and an attention weight?
The score is the raw scaled dot product between a query and a key; it can be any real number. The weight is the score after softmax over all keys for that query: positive and summing to 1 across the row. Higher scores give higher weights, but non-linearly (exponentially), and each weight depends on all other scores in the row.
Why is softmax used for attention weights?
It maps arbitrary scores to positive weights summing to 1, so the output is a proper weighted average (a convex combination) of value vectors: its scale stays stable regardless of sequence length, and it is differentiable everywhere. The exponential also emphasises the highest scores, letting attention focus. Alternatives exist (sparsemax, sigmoid attention, linear-attention kernels), but softmax remains the default.
Why do Transformers need positional encoding?
Self-attention treats its input as a set: permuting the tokens just permutes the outputs, so "the dog chased the cat" and "the cat chased the dog" would get the same representations up to order. Positional information (added vectors, rotations of Q and K, or distance biases) is required so the model can use word order.
What is multi-head attention and why use it?
Several attention operations run in parallel, each with its own WQ, WK, WV projecting into a smaller subspace (d/h dimensions). Their outputs are concatenated and projected with WO. Each head can learn a different relationship (previous token, subject-verb, coreference) and attend to different positions at the same time, which one softmax distribution per token cannot do. Total cost equals one full-width head.
What is masked (causal) self-attention and why is it needed?
Attention in which each position can only attend to itself and earlier positions; future scores are set to −∞ before softmax. During training the whole target sequence is available, and without the mask a position could simply read the token it is supposed to predict, so it would learn nothing useful for generation. The mask allows parallel training on all positions while preserving left-to-right prediction, and it matches how the model generates at inference.
Is the causal mask the same as a padding mask?
No. The causal mask blocks attention to future tokens and is a property of autoregressive decoders. The padding mask blocks attention to padding tokens that were added to make sequences in a batch the same length; it is used in both encoders and decoders. Both are implemented by setting scores to −∞, and they are often combined.
What is cross-attention?
Attention where queries come from one sequence and keys and values from another. In encoder-decoder Transformers, decoder tokens (queries) attend over the encoder's output (keys, values), letting each generated token look at the relevant parts of the source, for example the English word being translated. It is also used to condition image and speech models on text or images.
What does the feed-forward network in a Transformer block do?
It is a two-layer MLP applied independently to each token: expand from d to about 4d, apply a non-linearity (ReLU, GELU, or a gated SwiGLU), project back to d. Attention mixes information across tokens; the FFN transforms each token's features non-linearly. It contains most of the parameters and is believed to store much of the model's factual knowledge.
Why is non-linearity needed in a Transformer?
Attention outputs are weighted sums of linear projections, so stacking attention layers alone is close to a composition of linear maps, which collapses to a single linear transformation and cannot model complex functions. The non-linear activation in the FFN gives the network its expressive power to learn feature interactions and abstractions.
What does "Add & Norm" mean?
"Add" is the residual connection: the sub-layer's input is added to its output (x + Sublayer(x)), preserving information and giving gradients a direct path. "Norm" is layer normalization, which rescales each token's features to zero mean and unit variance (plus learned scale and shift) to keep activations well-behaved. In the original design it is applied after each sub-layer; modern LLMs normalise before the sub-layer instead (pre-norm).
Name the three Transformer families and a use case for each.
- Encoder-only (BERT, RoBERTa): classification, named-entity recognition, embeddings for search.
- Decoder-only (GPT, Llama, Claude, Gemini): chat, text and code generation, reasoning.
- Encoder-decoder (T5, BART, Whisper): translation, summarisation, speech-to-text.
Is ChatGPT an encoder model or a decoder model?
Decoder-only. The system prompt, conversation history and your message are flattened into one token sequence, and the model continues it using masked self-attention only. There is no separate encoder or cross-attention; "understanding" the prompt happens in the same stack during prefill.
How is BERT pretrained?
With masked language modelling: 15% of input tokens are selected, of which 80% become [MASK], 10% a random token and 10% stay unchanged, and the model predicts the originals using both left and right context. The original BERT also used next-sentence prediction. BERT-base has 110M parameters (12 layers), BERT-large 340M (24 layers), trained on about 3.3B words of books and Wikipedia with WordPiece tokens.
What is the difference between MLM and CLM?
MLM (masked language modelling) hides some tokens and predicts them from context on both sides; it builds bidirectional understanding but trains on only ~15% of positions and does not directly teach generation. CLM (causal language modelling) predicts each token from the tokens before it; it trains on every position and matches the generation task exactly, which is why generative LLMs use it.
Does pretraining need labelled data?
No. It is self-supervised: the labels are derived from the text itself (the next token, or the masked tokens). That is what allows training on trillions of tokens of raw web text, code and books. Labelled or curated data is used later, in instruction tuning and preference alignment.
What is autoregressive generation?
Producing a sequence one token at a time where each new token is predicted from all previous ones: run the model, get a distribution for the next token, choose one, append it to the input, repeat until an end-of-sequence token, a stop sequence or the length limit. Decoder-only LLMs and the decoder of encoder-decoder models generate this way.
How does a decoder know when to stop generating?
It learns to emit a special end-of-sequence token, because training examples end with it. Generation also stops when the application hits max_tokens or a user-defined stop sequence appears. If none of these happen the model keeps going, which is why length limits are always set.
What is greedy decoding and what is wrong with it?
Always choosing the single most probable next token. It is fast and deterministic but myopic: a high-probability first token can lead to a lower-probability overall sequence, and in open-ended generation it often falls into repetitive loops and dull text.
What does temperature do?
It divides the logits by T before softmax. T below 1 makes the distribution sharper (more deterministic, conservative), T above 1 makes it flatter (more diverse and random), and T close to 0 behaves like greedy decoding. It never changes which token is most likely, only how much probability the alternatives get. It is a decoding setting and does not modify Q, K, V or any weights.
Explain top-k and top-p sampling.
Top-k keeps only the k most probable tokens, renormalises and samples. Top-p (nucleus) keeps the smallest set of tokens whose cumulative probability reaches p (say 0.9), renormalises and samples. Top-p adapts to the model's confidence: when one token dominates the set is tiny, when many are plausible it is large. Top-k uses a fixed count regardless of the shape of the distribution.
What is a context window?
The maximum number of tokens a model can process in a single forward pass, covering prompt plus generated output. Anything beyond it is invisible to the model. In the Word2Vec sense, "context window" means the few words around a target word used for training; in LLMs it means the model's total attention span.
Is the context window the same as memory?
No. The context window is short-term working memory for a single request. LLMs have no memory between API calls; apps simulate memory by re-sending conversation history, summaries or retrieved facts into the context each time. Long-term "memory" features are stored outside the model (databases, vector stores) and injected when relevant.
What is a hallucination?
Generated content that sounds plausible and confident but is false or unsupported by the provided context: fabricated citations, wrong numbers, non-existent functions. It arises because the model is trained to produce likely text, not verified truth, and because it lacks or misremembers some knowledge. It is reduced with grounding (retrieval, tools), verification and careful prompting, not eliminated.
Are the attention weights learned parameters?
No. They are computed on the fly for each input from queries and keys. The learned parameters are the projection matrices WQ, WK, WV, WO (plus FFN, embedding and norm weights). The loss updates those matrices, and better attention patterns emerge indirectly.
How are WQ, WK and WV obtained?
They are ordinary trainable weight matrices, initialised randomly (for example from a normal distribution with standard deviation around 0.02, or Xavier-style schemes) and learned by backpropagation and gradient descent on the training loss, usually next-token prediction. Nobody designs them by hand, and nobody labels words as nouns or verbs; useful projections emerge because they reduce prediction error.
Does a Transformer behave differently in training and inference?
The forward computation is the same, but in training weights are updated by backpropagation and dropout is active; at inference weights are frozen and dropout is off. For decoders, training processes all positions in parallel with teacher forcing, while inference generates one token at a time and uses a KV cache. The causal mask is used in both.
What is the difference between open-weight and closed models?
Open-weight models (Llama, Mistral's open models, Qwen, DeepSeek, Gemma) publish their parameters so you can download, self-host, fine-tune and inspect them, subject to their licence. Closed models (GPT, Claude, Gemini) are accessible only through the provider's API. Open weights give control, privacy and cost predictability; closed models often lead in capability and require no infrastructure.
Going deeper
Why do we divide by √dk in attention? What happens if we remove it?
If query and key components are independent with mean 0 and variance 1, their dot product sums dk such terms, so its variance is dk and its typical magnitude √dk. For dk = 64 raw scores are around ±8; softmax over such values is nearly one-hot, and softmax gradients in that saturated regime are close to zero, so training becomes slow or unstable. Dividing by √dk restores unit variance. Removing it makes attention overly peaked, especially for large head dimensions; the model may partly compensate by learning smaller weights, but training is worse.
Why apply softmax to QKT and then multiply by V, instead of softmax(QKTV)?
The computation has two conceptually separate steps: decide where to look (compare queries with keys and normalise into a distribution over positions), then decide what to take (average the values with those weights). QKTV would mix values before relevance is normalised; the result would not be a weighted average over positions, its scale would be uncontrolled and the interpretation of weights as a distribution would be lost. Also, softmax over QKT normalises over the key dimension, which only makes sense before V is applied.
Walk through the matrix shapes in multi-head attention for a batch.
Input X: (B, T, d). Linear projections give Q, K, V: (B, T, d). Reshape to (B, T, h, d/h) and transpose to (B, h, T, dk). Scores Q KT: (B, h, T, T). Softmax over the last axis. Weights times V: (B, h, T, dk). Transpose and reshape back to (B, T, d) (the concatenation), then WO: (B, T, d). Example: T = 10, d = 768, h = 12 gives 12 score matrices of 10 × 10 and head outputs of 10 × 64.
Why multiple heads instead of one head with a larger dimension?
A single head produces exactly one attention distribution per query, so it must compromise between relationships (it cannot put most weight on the subject and on the previous token simultaneously). h heads produce h independent distributions over different learned subspaces, at the same parameter count and FLOPs as one head of width d. Empirically this works better; beyond a point extra heads become redundant, which is why head dimension is usually kept at 64-128.
How are multi-head projection matrices initialised, and do heads end up learning different things?
Each head has its own slice of WQ, WK, WV, initialised independently at random. Random symmetry breaking is essential: if all heads started identical they would receive identical gradients and stay identical. In practice heads diversify, though some become redundant and can be pruned after training with little loss.
Explain residual connections and what would happen without them.
Each sub-layer computes x + f(x). The gradient flowing back contains an identity term, so it reaches early layers without being repeatedly multiplied by small or large Jacobians, and each layer only has to learn a refinement. Residuals are used around every attention and FFN sub-layer in both encoder and decoder (and around cross-attention in the decoder). Without them, deep Transformers suffer vanishing or exploding gradients, train very slowly or diverge, and lose the easy path for information from the embeddings to the output.
Why LayerNorm and not BatchNorm in Transformers?
BatchNorm normalises each feature across the batch, which is problematic for sequences: lengths vary, padding pollutes statistics, batch statistics are noisy for small batches, and at inference batch size may be 1 so running averages must be used, creating train/test mismatch. LayerNorm normalises across the features of each token individually, so it is independent of batch composition and behaves the same in training and inference.
What is the epsilon in layer normalization for?
It is a small constant (around 10−5 or 10−6) added to the variance inside the square root, so the division never becomes a division by zero or by a tiny number when a token's features are nearly constant. It is a numerical-stability safeguard, not a learned parameter.
Doesn't normalizing each layer's output throw away useful information?
No. LayerNorm keeps the relative pattern of features within a token (the direction of the vector) and only standardises its overall location and scale, and the learned γ and β can re-scale features as needed. The residual stream also carries the un-normalised signal in pre-norm designs. What is removed is mainly scale drift that would destabilise training.
Compare Pre-LN and Post-LN Transformers.
Post-LN (original, BERT) computes Norm(x + Sublayer(x)); the normalization sits on the residual path, which makes gradients at initialisation large near the output and requires careful learning-rate warm-up, and it becomes unstable for very deep stacks. Pre-LN (GPT-2 onward) computes x + Sublayer(Norm(x)); the residual path is a clean identity, training is much more stable and needs less warm-up, and a final norm is added before the output layer. Nearly all modern LLMs use Pre-LN, often with RMSNorm.
What is RMSNorm and why do modern LLMs use it?
RMSNorm divides each token vector by the root-mean-square of its features and multiplies by a learned gain, without subtracting the mean or adding a bias. It is cheaper (fewer reductions and parameters) and performs as well as LayerNorm in practice, so Llama, Mistral, Qwen, Gemma and others adopted it.
What is SwiGLU and why does it use about 8/3 · d hidden units?
SwiGLU is a gated FFN: W2(SiLU(W1x) ⊙ W3x). One branch produces candidate features, the other a gate that scales them element-wise, which empirically gives better quality than a plain ReLU/GELU MLP. It has three matrices instead of two, so to keep the parameter count equal to a 4d classic FFN (2 × 4d2 = 8d2), the hidden size is set to about 8d/3 (3 × d × 8d/3 = 8d2).
Why does the FFN expand to 4d and then contract? What are the "new dimensions"?
The expansion is a linear layer whose outputs are new learned combinations of the existing features; nothing is added to the token and no new tokens are created. Working in a wider space lets the non-linearity carve out many more feature detectors (roughly, each hidden unit can detect a pattern), and the second linear layer combines their activations back into d dimensions to write into the residual stream. Which information survives the contraction is learned by training, not selected by hand.
Where do most parameters of an LLM live? Estimate a block's parameter count.
Attention has 4d2 (Q, K, V, O projections); the FFN has 8d2 (with 4d expansion or equivalent SwiGLU), so a block is about 12d2 and the FFN holds about two-thirds. Add |V| × d for the embeddings (double if the LM head is untied). Norms and biases are negligible. For GPT-2 small (d = 768, 12 layers, 50,257 vocab) this gives about 85M + 39M = 124M; for GPT-3 (d = 12,288, 96 layers) about 175B.
How much GPU memory does it take to run and to fine-tune a 7B model?
Inference: weights take parameters × bytes: about 14 GB in fp16/bf16, 7 GB in 8-bit, about 3.5-4 GB in 4-bit, plus the KV cache (grows with context and batch) and some activation workspace. Full fine-tuning with Adam in mixed precision needs roughly 16 bytes per parameter (weights, gradients, two optimizer moments, master weights), about 112 GB before activations, which is why parameter-efficient methods such as LoRA or QLoRA are used (see Fine-Tuning).
Why sine and cosine for positional encoding, and why use both?
Using sinusoids at geometrically spaced frequencies gives each position a unique multi-scale code (fast waves distinguish neighbours, slow waves distinguish distant positions) without any parameters, and the encoding exists for any position. For a fixed offset k, the (sin, cos) pair at position pos + k is a rotation of the pair at pos, so relative offsets are linear functions the model can learn. Pairing sin with cos guarantees that each pair never vanishes simultaneously and makes that rotation property possible.
What does pe[:, 0::2] and pe[:, 1::2] mean in positional-encoding code?
Python slice notation over the feature dimension: 0::2 selects columns 0, 2, 4, ... (even dimensions), which receive the sine values; 1::2 selects columns 1, 3, 5, ... (odd dimensions), which receive the cosine values. Each even/odd pair shares a frequency.
Positional encodings index tokens, but words split into different numbers of tokens. Is that a problem?
No. Positions refer to token positions, and the model learns during training that a word may span several consecutive tokens; attention easily links subword pieces of the same word. The encoding only needs to tell the model the order and distance between tokens, which it does regardless of how words were split.
Explain RoPE and why it is preferred over learned absolute positions.
RoPE rotates each two-dimensional pair of query and key features by an angle proportional to the token's position, with a different frequency per pair. The dot product of a rotated query at position m and a rotated key at position n depends only on m − n, so attention becomes relative-position aware. Advantages: no parameters, relative positions are what attention needs, cached keys never need updating, and the frequency base can be rescaled to extend context. Learned absolute embeddings have no representation for positions beyond the training maximum.
What is ALiBi and how does it compare with RoPE?
ALiBi adds a fixed negative bias proportional to query-key distance to attention scores, with a different slope per head, and uses no position embeddings. It extrapolates to longer sequences well out of the box and is trivial to implement, but hard-codes a preference for nearby tokens. RoPE is more expressive and has become the standard for large decoders, typically combined with scaling methods for long context.
How does GPT get K and V without an encoder?
In a decoder-only model, Q, K and V are all projections of the same sequence: the prompt followed by already-generated tokens. Each layer applies masked self-attention to that sequence. The prompt plays the role the encoder input would play in a translation model, but it is processed by the same causal stack.
In an encoder-decoder model, which encoder layer provides K and V for cross-attention?
The output of the final (top) encoder layer, which holds the most refined contextual representation of the source. Every decoder layer's cross-attention attends to that same encoder output, each with its own learned K/V projections.
Why is masked self-attention used only in the decoder and not the encoder?
The encoder's job is to understand an input that is fully known in advance, so each token should see both left and right context. The decoder generates the output one token at a time and must not see tokens it has not produced yet; masking also prevents it from reading the gold answer during parallel training. The encoder having seen the entire source does not leak the target, because the source and target are different sequences.
At inference in a translation model, what is computed once and what is repeated?
The encoder runs once on the source sentence, and the keys and values used by cross-attention are computed from its output once and reused. The decoder runs once per generated token: masked self-attention over the tokens generated so far (with a KV cache) plus cross-attention to the fixed encoder output, then the next token is chosen and appended.
What is teacher forcing, and what is exposure bias?
Teacher forcing trains a sequence model by feeding the true previous tokens as input at every position (possible in parallel thanks to the causal mask), rather than the model's own predictions. Exposure bias is the resulting mismatch: at inference the model conditions on its own outputs, which it never practised during training, so an early mistake can lead it into unfamiliar states and errors compound.
What loss is used for next-token prediction, and what is perplexity?
Cross-entropy: the negative log of the probability the model assigned to the actual next token, averaged over positions. Perplexity is exp of that average; it can be read as the number of equally likely options the model is effectively choosing between. A loss of 2.0 nats per token corresponds to perplexity about 7.4. Perplexity is only comparable between models with the same tokenizer.
What is T5's span-corruption objective and text-to-text framing?
T5 replaces random contiguous spans of the input (about 15% of tokens, average span length 3) with sentinel tokens like <X>, <Y>, and the decoder must output each sentinel followed by the missing text. It also frames every task as text in, text out with a task prefix ("summarize:", "translate English to German:"), so a single model, loss and decoding procedure handle classification, translation, QA and summarisation.
Why does the MLM objective use the 80/10/10 replacement rule?
[MASK] never appears when the model is fine-tuned or used, so if every selected token were replaced with [MASK], the model would learn representations useful only at masked positions. Replacing 10% with random tokens and leaving 10% unchanged forces it to build good representations for every token, since any token might be one it must predict.
Explain beam search with its pros and cons.
Keep the B best partial sequences by cumulative log-probability; at each step expand each by all tokens and keep the top B overall; finish when beams produce EOS, using a length penalty to avoid favouring short outputs. Pros: finds higher-probability sequences than greedy, deterministic, good for translation, summarisation and speech recognition. Cons: B times more compute, not guaranteed optimal, and in open-ended generation it yields generic, repetitive text because the most probable text is not the most natural.
Compute the softmax of logits [2, 1, 0] at T = 1 and T = 0.5.
T = 1: exp values 7.389, 2.718, 1.000; sum 11.107; probabilities 0.665, 0.245, 0.090. T = 0.5: logits become [4, 2, 0]; exp values 54.60, 7.39, 1.00; sum 62.99; probabilities 0.867, 0.117, 0.016. Halving temperature concentrates mass on the top token; the ranking is unchanged.
Given probabilities tea 0.40, coffee 0.30, water 0.12, milk 0.08, juice 0.05 ..., which tokens survive top-k = 3, top-p = 0.9 and min-p = 0.1?
Top-k = 3: tea, coffee, water (renormalised 0.488, 0.366, 0.146). Top-p = 0.9: cumulative 0.40, 0.70, 0.82, 0.90, so tea, coffee, water, milk (renormalised 0.444, 0.333, 0.133, 0.089). Min-p = 0.1: threshold 0.1 × 0.40 = 0.04, so tea, coffee, water, milk and juice.
Explain repetition, frequency and presence penalties.
Repetition penalty (multiplicative): for tokens already in the context, divide positive logits by ρ (and multiply negative ones), typically 1.1-1.3. Frequency penalty (additive): subtract α × the number of times the token has appeared, so heavy repetition is penalised more. Presence penalty: subtract a fixed β once a token has appeared at all, nudging the model towards new words and topics. Too much of any makes text unnatural (avoiding necessary words such as names or code identifiers).
Which decoding parameter is most effective at reducing hallucinations?
Among temperature, top-k, top-p and max tokens, lowering temperature (or tightening top-p) helps most, because it reduces the chance of sampling low-probability, often wrong, tokens. But none of them fixes the root causes (missing or misremembered knowledge); the model's most likely answer can still be wrong. Grounding with retrieval or tools, allowing "I don't know", and verification are the real mitigations.
What are stop sequences and max tokens used for?
max_tokens caps how many tokens are generated, bounding cost and latency; if hit, the output is cut off (check the finish reason). Stop sequences end generation as soon as a given string is produced, for example a newline for one-line answers, "\nUser:" in a transcript format, or the end of a code block. Together they give precise control over structured outputs.
What is the KV cache and why does it speed up generation?
During decoding, the keys and values of earlier tokens do not change (causal masking), so they are stored per layer after being computed once. At each new step only the newest token's Q, K, V are computed; its K and V are appended and its single query attends over the cache. This avoids recomputing the whole prefix every step, turning repeated quadratic work into linear work per token. The cost is memory proportional to layers × KV heads × head dim × tokens.
What are prefill and decode, and which is compute-bound?
Prefill processes the prompt tokens in parallel, doing large matrix multiplications; it is compute-bound and determines time to first token. Decode generates one token per step, reading all weights and the KV cache for a small amount of arithmetic; it is memory-bandwidth-bound and determines tokens per second. Optimisations differ: batching and quantization help decode; FlashAttention and chunked prefill help prefill.
What are scaling laws and what did Chinchilla change?
Scaling laws are empirical power-law relationships showing that loss decreases predictably with parameters, data and compute. Chinchilla showed that earlier large models were undertrained: for a fixed compute budget, parameters and tokens should grow together, roughly 20 training tokens per parameter. A 70B model on 1.4T tokens beat a 280B model trained with the same compute on 300B tokens, and was cheaper to serve.
Explain the RLHF process.
- Supervised fine-tuning on human-written demonstrations.
- Collect human rankings of several model responses per prompt and train a reward model to score preferred responses higher (Bradley-Terry loss).
- Optimise the SFT model with an RL algorithm (usually PPO) to maximise reward, with a KL penalty against the SFT model to avoid reward hacking and preserve fluency.
The result is a model whose style and choices match human preferences; it made chat assistants practical.
What is in-context learning, and how does it differ from fine-tuning?
In-context learning is performing a task from instructions and examples placed in the prompt, with no weight updates: the model infers the pattern through attention over the examples. Fine-tuning changes the weights using a training dataset. In-context learning is instant and flexible but consumes context tokens on every call and is limited by window size; fine-tuning bakes behaviour in, saves prompt tokens and can reach higher quality on a narrow task, but costs training effort and must be redone for changes.
Why do models with the same architecture (GPT, Claude, Gemini) behave differently?
Architecture is only one ingredient. Differences come from pretraining data (mix, quality, languages, code share, cutoff), scale, tokenizer, post-training (instruction data, preference data, principles used for alignment, safety policies), specialised training (reasoning RL, coding), context length and system-level features such as tools and safety filters. Newer versions of the same family differ for the same reasons, not only because of more data.
How does a Transformer handle variable-length sequences in a batch?
Sequences are padded to a common length (or packed together with separators) and an attention mask marks padding positions so real tokens never attend to them; the loss also ignores padding. Weights do not depend on sequence length, so any length up to the positional/context limit can be processed. Efficient implementations avoid wasted compute with packing or variable-length kernels.
How is a Vision Transformer different from a CNN?
A ViT splits an image into fixed-size patches, linearly embeds each as a token, adds position embeddings and runs a standard Transformer encoder, so every patch can attend to every other patch from the first layer (global receptive field). A CNN builds features hierarchically with local filters and has built-in locality and translation equivariance. ViTs need more data or augmentation because of weaker inductive biases, but scale better with data and compute.
Advanced
What is the time and memory complexity of self-attention versus an RNN layer, and what does it imply in practice?
Self-attention: O(n2d + nd2) compute (the n2d term is scores and mixing; nd2 is the Q, K, V, O projections) and O(n2) memory for the score matrix per head (O(n) with FlashAttention), with O(1) sequential operations and O(1) path length. RNN: O(n·d2) compute, O(n) sequential steps and O(n) path length. When n < d (typical for short sentences) the projection term can dominate and attention is even cheaper in FLOPs; for long sequences the n2 term dominates. In practice attention wins because its work is parallel matrix multiplication that GPUs do extremely well, while RNN time scales with sequential steps. At inference, decoders are sequential per generated token regardless.
Derive the KV cache size for a model and explain what limits batch size.
Per token per layer you store one key and one value vector per KV head: 2 × nkv × dhead values. Total bytes = 2 × L × nkv × dhead × tokens × batch × bytes per value. Example: 32 layers, 8 KV heads, 128 dims, bf16: 2 × 32 × 8 × 128 × 2 = 131,072 bytes = 128 KB per token; a 32K-token context is 4 GB per sequence. GPU memory minus weights, divided by per-sequence cache, bounds the concurrent batch, which bounds throughput. Hence GQA/MLA, cache quantization, paging and prefix sharing.
How does FlashAttention work, and does it reduce FLOPs?
It splits Q, K, V into blocks sized for on-chip SRAM. For each query block it streams key/value blocks, computes the partial scores, and maintains a running row maximum and running normaliser (online softmax) so partial results can be rescaled and summed exactly. The n × n matrix is never written to high-bandwidth memory, and the backward pass recomputes scores instead of storing them. Memory becomes O(n) and wall-clock time drops because standard attention was memory-bandwidth-bound. FLOPs stay O(n2d) (slightly more due to recomputation), and the result is exact.
Explain MHA, MQA, GQA and MLA and their trade-offs.
MHA: each query head has its own K/V head; best quality, largest KV cache. MQA: all query heads share one K/V head; cache shrinks by h times, faster decode, some quality loss and instability. GQA: query heads grouped, one K/V head per group (for example 32 Q, 8 KV); near-MHA quality with several times smaller cache; the modern default; MHA checkpoints can be converted by averaging heads and briefly retraining. MLA: compress K and V into a low-rank latent per token that is cached and up-projected per head (with a decoupled RoPE component); very small cache with quality comparable to MHA, at the cost of extra projection compute and implementation complexity.
How do you extend a model's context length from 4K to 128K?
- Adjust positional encoding: for RoPE use position interpolation, NTK-aware base scaling or YaRN so new positions map into frequency ranges the model knows.
- Continue training on long sequences (a few billion tokens of long documents, code repositories, synthetic long-range tasks), often in stages (16K, 32K, 128K), mixing in short data to preserve short-context quality.
- Make it computable: FlashAttention, context/sequence parallelism, activation checkpointing.
- Serving: KV cache budgeting, GQA, cache quantization, paging.
- Evaluate beyond needle-in-a-haystack with multi-hop and aggregation tasks over long inputs.
Why do models struggle with "lost in the middle", and how would you mitigate it?
Training data and position encodings bias attention toward recent tokens and toward the beginning (instructions, attention-sink tokens), and relevant facts in the middle compete with many distractors. Long-range retrieval also degrades with distance under RoPE decay. Mitigations: retrieve and include only relevant chunks, put key facts and instructions at the start or end, repeat the question after long documents, rerank so best evidence is near the query, use structured markers, and choose models trained specifically for long-context retrieval.
Explain Mixture of Experts routing and the load-balancing problem.
A router (a linear layer plus softmax) scores all experts for each token at each MoE layer; the top-k experts (often 1-2, or 8 of many fine-grained experts) process the token and their outputs are combined with gate weights. Without intervention, routers collapse onto a few experts that then get better and receive even more tokens. Fixes: an auxiliary loss rewarding uniform expert usage (product of the fraction of tokens and mean gate probability per expert), router noise, capacity limits with token dropping, or bias terms adjusted to balance load without an auxiliary loss. Expert parallelism distributes experts across GPUs with all-to-all communication.
Mixtral 8x7B: why ~47B total and ~13B active parameters rather than 56B and 14B?
Only the FFN is replicated into 8 experts; attention, embeddings and norms are shared. Each 7B-class model has about 5.6B FFN parameters and about 1.6B shared ones, so total ≈ 8 × 5.6B + 1.6B ≈ 46-47B. With top-2 routing each token uses 2 × 5.6B + 1.6B ≈ 13B. Compute per token matches a 13B dense model, but memory must hold all 47B.
Derive or explain the DPO loss and its relation to RLHF.
The KL-regularised RLHF objective max E[r] − βKL(π||πref) has an optimal policy π*(y|x) ∝ πref(y|x) exp(r(x,y)/β). Inverting gives r(x,y) = β log(π*(y|x)/πref(y|x)) + β log Z(x). Substituting into the Bradley-Terry preference model, the partition function Z cancels for a pair of responses to the same prompt, giving L = −log σ(β[log πθ(yw)/πref(yw) − log πθ(yl)/πref(yl)]). So DPO optimises the same objective with the policy acting as its own implicit reward model, trained offline on preference pairs, with no sampling loop or separate reward and value networks. Trade-offs: simpler and stabler, but offline (no exploration) and can over-optimise away from the reference if pairs are noisy.
What is reward hacking in RLHF and how is it controlled?
The policy finds outputs the imperfect reward model scores highly but humans do not actually prefer: excessive length, flattery, confident tone, repeated phrases, or exploiting blind spots. Controls: the KL penalty to the reference model, reward-model ensembles and regular retraining on new policy outputs, length normalisation or penalties, early stopping based on held-out human evaluation, and mixing pretraining loss to preserve capabilities.
How are reasoning models trained, and what is GRPO?
Starting from a strong base model (optionally with a small cold-start SFT on long chain-of-thought examples), they are trained with RL on problems whose answers can be checked automatically: maths with known answers, code with unit tests, plus format rewards. Behaviours like self-verification and backtracking emerge because they raise success. GRPO samples a group of responses per prompt, computes each one's advantage as its reward minus the group mean (divided by the group standard deviation), and applies a clipped policy-gradient update with a KL term. It needs no learned value model, which saves memory. Big reasoning models' traces are then distilled into smaller models.
Why does chain-of-thought improve performance from a computational point of view?
Each forward pass does a fixed, bounded amount of sequential computation (L layers). Problems requiring more serial steps than that cannot be solved in a single token's computation. Generating intermediate tokens writes partial results into the context, which later tokens can read through attention, effectively giving the model a scratchpad and unbounded serial depth proportional to the number of tokens. It also decomposes a hard prediction into a sequence of easier, more in-distribution predictions.
Explain speculative decoding and why it does not change the output distribution.
A cheap draft model proposes k tokens autoregressively. The target model then scores all k positions in one parallel forward pass. Each proposed token is accepted with probability min(1, ptarget/pdraft); at the first rejection, a replacement is sampled from the normalised residual distribution max(0, ptarget − pdraft). This rejection-sampling scheme provably yields exactly the target model's distribution. Speed-up depends on the acceptance rate; since decode is memory-bound, verifying several tokens costs about the same as generating one. Variants use extra prediction heads (Medusa-style) or the model's own early layers as the draft.
What is PagedAttention and continuous batching, and why do serving engines use them?
PagedAttention stores each sequence's KV cache in fixed-size blocks mapped through a block table, like virtual memory pages. It eliminates fragmentation from reserving maximum-length buffers, allows memory sharing between sequences with a common prefix (system prompts, parallel samples), and supports copy-on-write. Continuous batching schedules at the iteration level: finished sequences leave and new ones join the running batch every step instead of waiting for a whole batch to finish. Together they raise GPU utilisation and throughput several-fold.
Why is weight quantization so effective for LLM decode speed?
Decode at small batch sizes is memory-bandwidth-bound: each token requires reading every weight once. Storing weights in 4 bits instead of 16 means reading about 4x fewer bytes, so tokens per second rise nearly proportionally, and the model fits on smaller hardware. Methods like GPTQ and AWQ calibrate quantization to protect sensitive weights, keeping quality loss small at 4-8 bits. Compute-bound prefill benefits less unless low-precision matrix hardware is used.
What are induction heads and how do they relate to in-context learning?
An induction head is a two-layer attention circuit: a "previous-token" head in an earlier layer writes information about each token's predecessor, and a later head uses it to find earlier positions where the current token appeared and attends to the token that followed, copying it forward ([A][B] ... [A] → predict [B]). Interpretability research found these heads form abruptly during training, coinciding with a jump in in-context learning ability, suggesting they are a core mechanism for pattern completion from the prompt.
How would you estimate the training compute and time for a model?
Use C ≈ 6ND FLOPs. For a 7B model on 2T tokens: 8.4 × 1022 FLOPs. A GPU delivering about 1015 FLOP/s of bf16 at 40% utilisation gives 4 × 1014 effective FLOP/s, so about 2.1 × 108 GPU-seconds ≈ 58,000 GPU-hours, roughly 2.5 days on 1,000 GPUs. Add overhead for restarts, evaluation and data loading. Utilisation (model FLOPs utilisation, MFU) is the key uncertain factor.
Why are modern small models trained far beyond the Chinchilla-optimal token count?
Chinchilla minimises training compute for a target loss, ignoring inference. Serving cost scales with parameters (about 2N FLOPs per token) and is paid on every request forever. Training a smaller model on many more tokens reaches similar quality with a larger one-off training bill but much cheaper, faster inference and a model that fits on consumer or edge hardware. Loss continues to improve slowly past the optimal point, so the trade is worth it for widely deployed models.
Are emergent abilities real or an artefact?
Both views have evidence. Some capabilities do appear only above certain scales in practice (usable in-context learning, multi-step reasoning with chain-of-thought). But many sharp jumps shrink when measured with continuous metrics (log-likelihood of the right answer, partial credit) instead of exact-match accuracy, suggesting smooth underlying improvement crossing a usefulness threshold. A good answer acknowledges the debate and notes that loss scales predictably while task-level abilities are harder to forecast.
Why are LLMs bad at counting letters or doing long arithmetic, and how can this be fixed?
Tokenization hides characters: "strawberry" may be two or three tokens, so letter-level facts must be memorised per token. Numbers are split into irregular chunks, breaking positional digit alignment needed for carrying. Fixed computation per token limits long serial arithmetic. Fixes: digit-level or three-digit tokenization of numbers, chain-of-thought (spell out letters, do column arithmetic step by step), and tool use (code interpreter, calculator), which is the most reliable in production.
What is the difference between outcome and process reward models?
An outcome reward model (or rule-based checker) scores only the final answer: cheap, scalable, used heavily in RL with verifiable rewards, but it can reward lucky flawed reasoning and gives a sparse signal. A process reward model scores each intermediate step: denser credit assignment, useful for guiding search over reasoning steps and catching errors early, but step-level labels are expensive and PRMs can themselves be gamed.
How does CLIP enable zero-shot classification, and what are its limitations?
CLIP learns aligned image and text embeddings with a contrastive loss over large image-caption datasets. To classify, embed prompts like "a photo of a {class}" for every class, embed the image, and pick the class with highest cosine similarity; no labelled training images needed. Limitations: sensitivity to prompt wording (prompt ensembles help), weakness at counting, spatial relations and fine-grained or specialised domains (medical images), biases from web data, and limited resolution.
How is a vision-language model like LLaVA built and trained?
Components: a pretrained vision encoder (CLIP/SigLIP-style ViT), a projector (linear layer or small MLP) mapping patch embeddings into the LLM's embedding space, and a pretrained LLM. Stage 1: freeze encoder and LLM, train the projector on image-caption pairs so visual tokens become "readable". Stage 2: instruction-tune on visual question-answering and multimodal conversations, unfreezing the projector and LLM (often with LoRA). Visual tokens are inserted into the prompt sequence like text tokens. Higher-resolution variants tile images into crops.
What are the failure modes of training very large Transformers and how are they handled?
Loss spikes and divergence (from large activations, attention logit growth, bad data batches), instability in low precision, and hardware failures. Mitigations: pre-norm architecture, QK-normalization or logit soft-capping, z-loss on output logits, learning-rate warm-up and careful peak rate, gradient clipping, bf16 instead of fp16, removing biases, skipping or rewinding past bad batches and restarting from checkpoints, and monitoring per-layer activation statistics.
How do encoder-only models produce sentence embeddings for retrieval?
Run text through the encoder and pool the final hidden states, typically mean pooling over tokens or the [CLS] vector, then normalise. Raw BERT embeddings are poor for similarity; embedding models are further trained with contrastive objectives on pairs (query-passage, paraphrases) with in-batch negatives and hard negatives, so cosine similarity reflects semantic relevance. Bi-encoders embed queries and documents independently for fast vector search; cross-encoders read the pair together for more accurate reranking. Details in RAG.
What are the main forms of parallelism used to train LLMs?
Data parallelism: each GPU holds a model replica and processes different batches; gradients are averaged. Sharded variants (ZeRO, FSDP) split optimizer states, gradients and weights across GPUs to save memory. Tensor parallelism: split individual matrix multiplications (for example attention heads, FFN columns) across GPUs within a node. Pipeline parallelism: assign groups of layers to different GPUs and stream micro-batches through them. Sequence/context parallelism: split long sequences across GPUs. Expert parallelism: place MoE experts on different GPUs. Large runs combine them ("3D/4D parallelism").
What is multi-token prediction and why might it help?
Instead of predicting only the next token, the model has additional heads (or sequential modules) that predict tokens 2, 3, ... ahead from the same hidden state during training. This densifies the training signal and encourages representations that plan further ahead, with reported gains on code and reasoning. At inference the extra heads can be discarded or used as a built-in draft for speculative decoding.
Why can sinusoidal or learned absolute encodings fail to extrapolate, while ALiBi or scaled RoPE work better?
Learned absolute embeddings have no vectors for unseen positions. Sinusoidal encodings exist for any position, but the model has never seen the particular combinations of phase values beyond the training length, and absolute signals in the residual stream then behave out-of-distribution. ALiBi uses only relative distance with a monotonic penalty, so longer distances are just "more of the same". RoPE is relative, but unseen large rotation angles in low-frequency dimensions are still out of distribution; interpolation and NTK/YaRN scaling map them back into trained ranges, and a short fine-tune finishes the adaptation.
Why is exact reproducibility hard with LLMs, even at temperature 0?
GPU floating-point arithmetic is not associative, and the order of reductions depends on kernel choice, batch composition and hardware; in serving systems your request is batched with others, so the numerics change between calls. When two tokens have almost equal logits, tiny differences flip the argmax and the continuation diverges. MoE routing can amplify this. Deterministic kernels, fixed batch shapes, seeds and pinned model versions improve reproducibility, but hosted APIs rarely guarantee it.
Scenario & debugging
Your model keeps repeating the same sentence or phrase in a loop. How do you fix it?
- Check decoding: greedy or low-temperature beam search on open-ended text is the classic cause. Switch to sampling (temperature 0.7-0.9, top-p 0.9 or min-p).
- Add a mild repetition penalty (1.1-1.2), frequency/presence penalty, or
no_repeat_ngram_sizeof 3-4. - Verify the prompt and chat template: a wrong template or missing EOS handling makes base-like models ramble; set stop sequences and
max_tokens. - Check the model: a base model instead of an instruct model, or an over-quantized or badly fine-tuned model, loops more. If you fine-tuned it, check for repetitive training data and whether EOS tokens were included in targets.
Outputs are too random and sometimes incoherent. What do you adjust?
Lower temperature (for example from 1.2 to 0.5-0.7); tighten truncation (top-p 0.8-0.9, or min-p 0.05-0.1, or top-k 20-40), but tune one truncation method at a time; remove strong penalties that force unusual words; for tasks with a single right answer (extraction, classification, code) use temperature 0. If incoherence persists at low temperature, the issue is the prompt, the context (conflicting or noisy retrieved text) or the model, not decoding.
Outputs are bland, generic and repetitive across users. What do you change?
Raise temperature moderately (0.8-1.1), use top-p 0.95 or min-p instead of a low top-k, add a presence penalty for topical variety, avoid beam search for open-ended generation, and improve the prompt with persona, concrete constraints and examples of the desired voice. For diverse candidates, sample several and rerank. Also check whether heavy alignment or a very low-temperature default in your wrapper is flattening outputs.
Your prompt plus documents exceed the context window and the token budget. What are your options?
- Retrieve instead of stuffing: chunk, embed and include only the top relevant chunks, with reranking (RAG).
- Compress: summarise documents or conversation history hierarchically (map-reduce summarisation), drop boilerplate, shorten the system prompt.
- Split the task: process documents separately and combine answers.
- Use prompt caching for large static prefixes to reduce cost.
- Move to a longer-context or cheaper model only if needed, remembering longer context raises latency and cost and may reduce accuracy in the middle.
- Cap output with
max_tokensand ask for concise formats.
The model hallucinates facts about your company's products. How do you reduce it?
The model cannot know private or recent information, so ground it: RAG over product documentation with instructions to answer only from provided context and to say "I don't know" otherwise; require citations to document IDs and validate them; lower temperature for factual answers; use tools (catalogue lookup, database queries) for exact data like prices and specifications; add an evaluation set of real questions and measure faithfulness; for high-stakes answers, add a verification step or human review. Fine-tuning helps style and format but is not a reliable way to inject changing facts.
Generation latency is too high for a chat product. Where do you look?
- Measure time to first token (prefill) and inter-token latency (decode) separately.
- Long time to first token: shorten or cache the prompt, reduce retrieved context, use prefix caching, chunked prefill.
- Slow tokens: smaller or distilled model, quantization (8/4-bit), GQA models, speculative decoding, better serving engine with continuous batching and paged KV cache, faster hardware.
- Fewer output tokens: concise instructions, lower
max_tokens, avoid reasoning models for simple turns. - Stream tokens to the user so perceived latency drops; route easy queries to a fast model.
Your GPU runs out of memory when serving long conversations with many users. What do you do?
Compute the KV cache per sequence (2 × layers × KV heads × head dim × tokens × bytes); it is usually the culprit. Options: cap context length or summarise old turns, use a serving engine with paged attention and prefix sharing, quantize the KV cache to 8-bit, quantize weights to free memory, pick a model with GQA or MLA, limit concurrent sequences with admission control, offload cold cache to CPU, or shard across more GPUs with tensor parallelism.
You extended a model's context with RoPE scaling and quality on short prompts dropped. Why, and how do you fix it?
Interpolating positions compresses the rotation frequencies, so nearby-token distinctions the model relied on become blurrier, and a long-context fine-tune on only long documents can shift the data distribution. Fixes: use NTK-aware or YaRN scaling that preserves high frequencies (local position resolution), include short-sequence data in the continued training mix, tune the scaling factor to the needed length rather than the maximum, and evaluate both short and long benchmarks before release. Some engines apply dynamic scaling only when the sequence exceeds the original length.
Your fine-tuned model gives great answers but never stops generating. What is wrong?
Most likely the training examples did not end with the EOS token (or it was masked out of the loss), or the chat template at inference differs from training so the model never sees its learned end-of-turn marker. Fix the data formatting to append EOS and compute loss on it, make sure the tokenizer's EOS/pad tokens are set correctly (a pad token equal to EOS that is masked out of the loss is a common cause), use the same template in training and inference, and set stop sequences and max_tokens as a safety net.
Batched inference gives different or garbage outputs compared with single-prompt inference. What could cause it?
Padding problems: for decoder-only models, right padding places pad tokens between the prompt and the generated text; use left padding for generation and pass the attention mask. Missing attention masks let tokens attend to padding. Position IDs must account for padding. A pad token that is not defined (set to EOS without masking) can make the model stop early. Fully masked rows can produce NaN. Small numerical differences between batch sizes are normal; large ones indicate a masking bug.
Training loss suddenly spikes to NaN while pretraining or fine-tuning a Transformer. How do you debug?
Check learning rate (too high, missing warm-up), gradient norms (add clipping at 1.0), precision (fp16 overflow; switch to bf16 or enable loss scaling), masking code (a fully masked attention row produces NaN; use a large negative value instead of −∞ in some kernels), bad data (empty sequences, extremely long lines, corrupted tokens), and division by zero in normalization (epsilon). For large runs, rewind to a checkpoint before the spike and skip the offending batches; consider QK-norm or z-loss for stability.
A support chatbot's API bill is much higher than expected. How do you investigate and cut it?
Log input and output tokens per request and break down input into system prompt, history, retrieved context and user text. Usual culprits: an enormous system prompt, full conversation history resent every turn, too many retrieved chunks, verbose outputs, retries, or a reasoning model used for simple turns. Fixes: trim and cache the static prefix, summarise history, retrieve fewer and better chunks, cap output length, route simple intents to a small model, batch offline jobs, and set per-user budgets. Remember non-English text may use more tokens.
Your model answers correctly in English but poorly and expensively in Hindi or Tamil. Why?
The tokenizer was trained mostly on English, so Indic scripts split into many more tokens per word: more cost, shorter effective context and harder modelling. The pretraining data likely contained far less of these languages, so knowledge and fluency are weaker. Options: choose a model with a multilingual tokenizer and strong multilingual training data, fine-tune on quality target-language data, translate-process-translate pipelines for some tasks, and evaluate per language with native speakers.
You need a classifier for 50 million short documents per day. Would you use GPT-style LLM calls?
Probably not as the main path. Fine-tune a small encoder (a BERT-family model, perhaps distilled) on labelled data, or train on labels produced by a large LLM (distillation). It is far cheaper, faster and more consistent, and runs on your own hardware. Use a large LLM for labelling, handling low-confidence or novel cases, and periodic quality audits. Compute rough costs: 50M documents × tokens per document × price per token usually makes the case clearly.
A long legal document is summarised, but key clauses in the middle are ignored. What do you do?
This is the lost-in-the-middle effect. Split the document into sections, summarise or extract clause information per section (map), then combine (reduce); ask for extraction of specific clause types with quotes before summarising; place the instructions and question after the document; use structured output listing each required clause; and evaluate with a checklist of expected clauses. Choose a model with strong long-context retrieval if single-pass summarisation is required.
The model confidently agrees with false premises in user questions. How do you address it?
This is sycophancy from preference training and the plausibility objective. Mitigations: system instructions to check premises and correct users politely, retrieval to verify claims, prompting the model to first list assumptions, evaluation sets with false-premise questions, and, if you control training, preference data that rewards correcting the user over agreeing. For critical domains add a verification step before answering.
You must choose between a large reasoning model and a fast standard model for a coding assistant. How do you decide?
Segment the traffic: autocomplete and small edits need sub-second latency, so use a fast (possibly small, local) model at low temperature; complex multi-file refactors, debugging and algorithm design benefit from a reasoning model despite higher latency and cost. Measure on your own tasks (pass rate on unit tests, edit acceptance rate), cost per resolved task rather than per token, and latency percentiles. A router or user-selectable "think harder" mode often gives the best trade-off.
Your company wants an LLM that runs fully on-premise for privacy. How do you pick and deploy it?
Shortlist open-weight models whose licence allows your use; evaluate candidates (7B-70B, dense or MoE) on your own tasks for quality, latency and cost. Size hardware from weights (parameters × bytes, with 4-8-bit quantization) plus KV cache for your context length and concurrency. Serve with an efficient engine (continuous batching, paged KV cache), add RAG over internal documents, fine-tune with LoRA if style or domain requires, and put guardrails, logging and evaluation in place. Plan for model upgrades and security patching yourself.
A user pastes a web page into your assistant and it starts following instructions hidden in the page. What happened and how do you defend?
Prompt injection: the model cannot reliably distinguish trusted instructions from untrusted data, since both are just tokens in the context. Defences: clearly delimit untrusted content and instruct the model to treat it as data; restrict tool permissions (least privilege), require confirmation for sensitive actions; filter or scan inputs and outputs; isolate untrusted content processing in a separate model call without tool access; and monitor. No prompt-only defence is complete, so limit the damage an injected instruction can cause.
The same prompt gives different answers in production and in your notebook. How do you track it down?
Compare exactly: model version and quantization, chat template and system prompt, tokenizer version, decoding parameters (temperature, top-p, penalties, max tokens), stop sequences, and whether the notebook uses greedy while production samples. Check preprocessing (whitespace, trailing spaces, Unicode normalisation) since tokens depend on it. Then remember hosted inference can be non-deterministic even at temperature 0 due to batching; log full requests and use seeds where supported.
After fine-tuning on your domain data, the model got worse at general tasks. What happened and how do you prevent it?
Catastrophic forgetting: full fine-tuning on a narrow dataset shifts weights away from general capabilities, and the chat template or alignment behaviour may be disturbed. Prevention: parameter-efficient fine-tuning (LoRA) with modest learning rates and few epochs, mixing general instruction data into the training set, early stopping on a general benchmark alongside domain metrics, and considering RAG instead if the goal is knowledge rather than behaviour. See Fine-Tuning.
A VLM describes objects that are not in the image. How would you reduce this?
Object hallucination comes from strong language priors (a "kitchen" implies a "fridge") overpowering weak visual evidence, low resolution or heavy token pooling. Mitigations: higher resolution or image tiling, prompts asking to describe only clearly visible objects and to say when unsure, lower temperature, grounding outputs with detection or segmentation models, fine-tuning with negative examples, and evaluating with object-hallucination benchmarks on your own images.
Your team debates long-context stuffing versus RAG for a 10,000-document knowledge base. What do you recommend?
10,000 documents will not fit any context window, and even if a subset did, sending millions of tokens per question is slow and expensive and accuracy degrades in long contexts. Use RAG to select relevant passages (hybrid search, reranking, metadata filters), then give the model a moderate context with citations. Long context remains useful for whole-document tasks (analysing one long contract) and for including more retrieved evidence. The combination, retrieval plus a comfortably long window, is the common production answer.
Model evaluation scores look excellent but users complain. What could be wrong?
Benchmark contamination (test items leaked into training), benchmarks that do not reflect your users' tasks, distribution shift (different languages, longer inputs, messier formatting), evaluation with different prompts or decoding settings than production, and metrics that miss what users care about (tone, conciseness, refusal rate, latency). Build an evaluation set from real, anonymised user queries, use rubric-based human or LLM-as-judge scoring validated against humans, and track online metrics like task success and thumbs-down rate.
You are asked to build a small language model from scratch for a narrow domain. Outline your plan.
- Question the premise: fine-tuning an existing open model is usually far cheaper; from-scratch is justified by unusual data (new language, proprietary token types), licensing or research goals.
- Data: collect and clean domain text, deduplicate, train a tokenizer on it.
- Architecture: standard decoder-only (pre-norm, RMSNorm, SwiGLU, RoPE, GQA), size chosen by compute and deployment target; use 6ND to budget and aim well beyond 20 tokens per parameter if data allows.
- Train with AdamW, warm-up and cosine decay, bf16, FlashAttention, checkpointing; monitor loss and downstream probes.
- Post-train: SFT on domain instructions, preference tuning (DPO), evaluation, then quantize for deployment.