GPT stands for Generative Pre-trained Transformer. Generative means it produces new text. Pre-trained means it learned from massive amounts of text data before you ever interact with it — its weights are the compressed result of that learning. Transformer is the specific neural network architecture that makes modern LLMs possible.

This article explains the mechanics from scratch: how text becomes numbers, how those numbers flow through the model, and why the model's size directly determines how much memory it needs. If you prefer to learn visually: bbycroft.net/llm animates every step of the forward pass in 3D; the Transformer Explainer runs live GPT-2 inference in your browser; the 3Blue1Brown Neural Networks series covers the same concepts through illustrated video. Once you understand the concepts here, Raschka's LLM Architecture Gallery catalogs the architectural variations across more than 70 real-world models.

What is a Transformer?

The Transformer is a neural network architecture introduced in 2017 that has since become the foundation of modern AI. While this article focuses on text generation, the same architecture has been adapted for audio generation and image recognition — making it one of the most broadly applied ideas in machine learning.

For text, the operating principle is straightforward: given a sequence of input text, predict the most probable next token. That single objective — repeated over 300 billion training tokens for GPT-3 — is what produces a model capable of writing, reasoning, and answering questions. Generation is the same loop run in reverse: sample the next token, append it to the input, predict the one after that, repeat.

The core innovation that made this possible is self-attention: a mechanism that lets the model decide which parts of the input are most relevant to each token, capturing meaning and relationships even between words far apart in the sequence. Earlier architectures (recurrent neural networks) processed text one token at a time from left to right, which made it difficult to connect information across long distances. Self-attention collapses that distance — any token can directly relate to any other in a single step, regardless of how far apart they are — which is why Transformers handle long-range dependencies so much more effectively.

Figure 1 is the map for the rest of this article. It shows the complete path a single forward pass takes: token IDs enter at the top, flow through an embedding stage, pass through 96 identical transformer blocks, and exit through an output head that samples one next token. The feedback arc on the right is the generation loop — each sampled token is appended to the input and the process repeats.

Composite GPT-3 architecture overview. A token-ID sequence feeds the embedding stage, where W_E token embeddings and W_P position embeddings are added to produce X0 with shape (N, 12,288). X0 enters the transformer stack: block 1 is expanded to show pre-LN attention and MLP residual updates, while blocks 2 through 96 are collapsed; the stack preserves shape and outputs X96 with shape (N, 12,288). The output head uses only the last row, applies final LayerNorm, projects through W_U to logits of shape (50,257), softmax samples the next token ID, and a feedback loop appends that token ID back to the token-ID sequence with cached K/V reused during decode.
Figure 1. GPT-3's forward pass at a glance. Token IDs enter the embedding stage to produce X0; the transformer stack updates that same-shaped representation through 96 blocks to X96; the output head uses the last row to sample one next token ID; and the decode loop appends that ID back to the token sequence for the next step.

Tokens: Text as Numbers

A model cannot read text. Before anything runs, your input is converted into a sequence of tokens — integer IDs from a fixed vocabulary. For text, modern vocabularies commonly range from tens of thousands to a few hundred thousand tokens; GPT-3 uses exactly 50,257. Each token represents a subword chunk: common words become a single token, rare words split into several (see Figure 2). The vocabulary is built during a separate tokenizer training phase, optimized for compression across a large text corpus. The number of tokens in a prompt determines how much computation the model needs to process it and how much memory the KV cache will consume. A 10,000-word document might be 13,000–15,000 tokens. Try the OpenAI Tokenizer to see how any text splits.

Three tokenization examples. The single common word 'memory' becomes one token. 'memory bandwidth' splits into 'memory' and ' bandwidth' (the space stays with the second token). The bare word 'bandwidth' splits into 'band' plus 'width' because, without a contextual leading space, it is not a single entry in the vocabulary.
Figure 2. The GPT-3 tokenizer maps text to integer IDs; color matches each subword piece in the input to its output cell. Notice how context changes the split: " bandwidth" (with a leading space, common in running text) is selected as one token, but bare "bandwidth" falls back to "band" + "width".

A common approach for building this vocabulary is subword tokenization, with Byte Pair Encoding (BPE) and closely related methods (SentencePiece, WordPiece) being widely used. Byte-Level BPE starts with individual bytes and repeatedly merges the most frequently co-occurring pair of units into a new token — first merging common byte pairs, then common subwords, building up to whole words for the most frequent vocabulary items. The practical benefit: subword tokenizers never produce an "unknown word" token. Any text, no matter how novel or misspelled, can be represented as a sequence of subword tokens that exist in the vocabulary. This is why models can handle code, URLs, foreign words, and typos without explicitly being trained on each one. For a deeper look at the BPE algorithm with working code, see Raschka's Implementing A BPE Tokenizer From Scratch.

Why typos still work

Typo handling is not a separate spell-checking feature. There is usually no normalization step, edit-distance search, or dictionary lookup before the model runs. The tokenizer simply converts the misspelled text into whatever subword sequence it can produce, and the transformer layers try to make useful predictions from that sequence.

For example, "artificial intelligence" and "artificial intellignece" usually become different token ID sequences, but both are still valid inputs. The typo may split into smaller or less common pieces, which gives the model a worse starting representation, but not an invalid one. Because GPT-style models are trained on noisy web text, they see misspellings, informal spelling, OCR errors, code, names, and other irregular strings in contexts that often reveal their meaning.

How the model recovers meaning from those degraded token sequences — through mechanisms described in the sections that follow — is revisited at the end of the MLP section.

Embeddings: Turning IDs into Meaning

Before diving in, here is the embedding stage at a glance — each piece is explained in the sections below.

High-level GPT-3 input embedding stack. Text is tokenized into token IDs. Token IDs select token embeddings through W_E lookup. Token positions select position embeddings through W_P lookup. The two embeddings are added element-wise to produce X0, the initial residual stream input to the first transformer block.
Figure 3. The whole input stage as a component diagram. Tokenization produces IDs; W_E lookup produces token-identity vectors; W_P lookup produces position vectors; and the two are added to produce X0, the initial residual stream passed into the first transformer block.

Each token ID is looked up in an embedding matrix WE — a large table of learned numbers, one row per vocabulary entry. Here is what each part of that table actually contains:

  • Rows (50,257 in GPT-3) — one row per token in the vocabulary. Row 0 is the vector for token ID 0; row 31,673 is the vector for "memory"; row 50,256 is the last entry. The row index is the token ID. The lookup is literally: go to this row, return the entire row.
  • Columns (12,288 in GPT-3) — the dimensions of the embedding space. Each column is one coordinate in a 12,288-dimensional space. The number 12,288 comes from the model's architecture: 96 attention heads × 128 dimensions per head (explained in the next section).
  • Each cell — a single floating-point number: one coordinate of that token's position in the embedding space. Meaningless on its own. The full row of 12,288 numbers together is the representation.
The embedding lookup: the token ID 31,673 (for 'memory') indexes into the embedding matrix W_E. The matrix is 50,257 rows by 12,288 columns. Row 31,673 is highlighted and extracted as a 12,288-dimensional vector containing values like 0.23, -1.4, 0.07, ..., 0.91.
Figure 4. Token ID 31,673 indexes row 31,673 of W_E; the entire row — 12,288 numbers — is the embedding vector for "memory". No computation, just an array index. The same blue marks the same data flowing from input token -> matrix row -> output vector.

The table has 50,257 × 12,288 ≈ 617 million cells, each a floating-point number — over half a billion parameters in the embedding step alone.

The embedding matrix is a learned weight matrix — it is part of the model file, updated during training via backpropagation just like every other parameter, and stored on disk alongside the attention and MLP weights. But it sits outside the transformer blocks: it runs once at the very start (to convert token IDs into vectors) and its counterpart, the unembedding matrix WU, runs once at the very end (to convert the final vector back to token probabilities). Neither is part of any attention layer or MLP layer.

One practical note for local inference

Some engines (including llama.cpp) keep the embedding and unembedding matrices at higher precision — fp16 or fp32 — even when the rest of the model is quantized to Q4. Because these matrices are accessed as index lookups rather than matrix multiplications, quantization artifacts can be more noticeable here. So "Q4_K_M" does not necessarily mean every weight in the file is at 4-bit.

What the 12,288 dimensions represent

No single column is labeled "emotion" or "syntax" or "topic." But the geometry of the full space is absolutely structured around human-understandable concepts — sentiment, formality, syntax, semantic category, and many others. These concepts are encoded as directions: a specific combination of many columns that together point toward a region of the space associated with that concept. It is not column 47 = royalty; it is a particular direction across many columns that the model learned to associate with royalty.

A classic intuition from early static word-embedding research: the vector for “king” minus “man” plus “woman” lands near “queen.” This is a useful starting point; the geometry in full transformer models is considerably richer. Explore embedding structure visually at projector.tensorflow.org, which projects high-dimensional vectors into 3D.

Position: where in the sequence

The embedding matrix WE encodes token identity but not order: the same token ID always retrieves the same row from WE, whether it appears first, tenth, or thousandth in the prompt. GPT-2 and GPT-3 handle order with a learned positional embedding table WP — a departure from the original 2017 Transformer, which used fixed sinusoidal position encodings.

GPT-3’s context window is 2,048 tokens, which means WP is fixed at exactly 2,048 rows — one learned vector for position 0, one for position 1, up to position 2,047. Because a position vector must exist in this table for a token to be processed, this row count is what determines the model's hard context limit. Each row has width 12,288 so it can be added element-wise to the corresponding token embedding row from WE. Like WE, WP is learned during pre-training by backpropagation and stored in the model file; at inference time it is just a lookup table. For GPT-3, WP has 2,048 × 12,288 ≈ 25M parameters.

For a prompt of N tokens, the model looks up N token rows and N position rows, adds them row by row, and the result is X0 with shape (N, 12,288): the initial residual stream. The residual stream is one 12,288-dimensional vector per token position, not a list of token IDs; row i is the model’s current representation of the token at position i.

Many modern LLMs instead use RoPE (Rotary Position Embedding) or similar approaches that inject positional information directly inside the attention computation. The mechanism differs, but the goal is the same: give the model a sense of sequence order while preserving each token row's 12,288-dimensional shape.

Three tensors of shape (2, 12,288) stacked vertically: E contains token embedding vectors from W_E rows 31,673 and 19,484, P contains position embedding vectors from W_P rows 0 and 1, and X0 = E + P is the initial residual stream. Token position 0 ('memory') is shown in blue, token position 1 (' bandwidth') in purple, position embeddings in teal. A callout shows one element: E[0,0] + P[0,0] = 0.23 + 0.01 = 0.24.
Figure 5. E contains the token embedding vectors produced by W_E lookup, and P contains the selected position embedding vectors from W_P. These vectors are added element-wise per token to produce the initial residual stream X0. Two-token example from "memory bandwidth": token position 0 ('memory') in blue, token position 1 (' bandwidth') in purple, position embeddings in teal. The callout shows one element: E[0,0] + P[0,0] = 0.23 + 0.01 = 0.24. All three tensors have shape (N, 12,288).

The Transformer Block

GPT models are decoder-only transformers — they generate text by attending only to previous tokens, never future ones. This is the right architecture for generation. Other architectures exist for other purposes: encoder-only transformers (like BERT) can attend in both directions simultaneously, making them better at understanding and classification tasks but unable to generate. Encoder-decoder models (like T5) combine both: an encoder reads the full input bidirectionally, a decoder generates output attending to the encoded representation. For local inference of chat and coding models, you will almost always be working with decoder-only models.

The model is a sequence of transformer blocks stacked on top of each other — 32 blocks in a typical 7B model, 96 in GPT-3. The GPT-3 paper calls these layers (n_layers = 96); this article uses “block” to distinguish the whole unit from its attention and MLP sublayers. Every block is structurally identical, but each has its own independent set of weights learned during training.

Each block contains its own attention module — in GPT-3, that means 96 attention heads per block, so a single forward pass performs 96 × 96 = 9,216 head-level attention computations in total. Heads only communicate within their own block through concatenation, WO, and the residual stream; the next block then starts with a fresh set of heads. The number of blocks and the number of heads per block are independent design choices; it is a coincidence that GPT-3 uses the same number for both.

Each GPT-3 block holds roughly 604M attention parameters + 1,208M MLP parameters; the final section breaks this down. Each block has two sublayers that operate in sequence:

  1. Attention — lets tokens gather information from other tokens in the sequence.
  2. MLP (feed-forward) — transforms each token's vector independently using learned patterns.

GPT-3 uses pre-normalization, inherited from GPT-2: LayerNorm is applied to the residual stream before each sublayer, and a final LayerNorm is applied after the last block before unembedding. Residual connections add each sublayer's output back into its input. This makes it easier for information to persist — each token's vector accumulates updates on top of its starting point rather than being replaced at each layer, which also helps gradients flow during training. Later layers can still attenuate or overwrite earlier features, but the path for preservation is always open. This flowing, accumulating representation is called the residual stream.

Vertical residual-stream overview. X0, the initial residual stream after embeddings, flows into block 1 and becomes X1. The same-shaped matrix continues through blocks 2 through 95 and then block 96, producing X96. A side callout explains that each X_k is the whole residual-stream matrix with shape (N, 12,288), where row i is token position i, columns are residual dimensions, values change after each block, and shape stays fixed.
Figure 6. The residual stream is the same-shaped layer output carried through the transformer stack. X0 is produced by the embedding stage; each block updates the values and returns another matrix X_k with shape (N, 12,288). Rows stay aligned to token positions, columns stay aligned to residual dimensions, and only the values change.

LayerNorm operates independently on each token row of the residual stream. For one token's 12,288-dimensional vector, it subtracts that row's mean, divides by that row's standard deviation, then applies learned per-dimension scale and shift parameters. This keeps the vector's scale well behaved before the attention or MLP sublayer reads it, while preserving the overall shape (N, 12,288).

Residual-stream spine diagram of one transformer block (pre-LN, or pre-normalization). X with shape (N, 12,288) flows down the spine. LN(X) feeds Attention, which computes delta-attn with shape (N, 12,288) and adds it back to produce X-prime. LN(X-prime) feeds the MLP, which computes delta-MLP with shape (N, 12,288) and adds it back to produce X-next. The dashed boundary is labeled one of 96 blocks.
Figure 7. The internals of one transformer block (GPT-2/3 pre-LN, or pre-normalization, variant). The residual stream is the vertical spine. LayerNorm is applied to each sublayer's input: LN(X) feeds Attention, producing Delta_attn, and LN(X') feeds the MLP, producing Delta_MLP. Each delta has shape (N, 12,288) and is added back into the stream, so the block exits with the same shape it entered.

Attention and QKV: How Tokens Communicate

To perform self-attention, each token's embedding is transformed into three new vectors — a query, a key, and a value. Queries compare against keys to measure how relevant each token is to every other; that relevance score then determines how much of each token's value gets passed forward. The result is a context-aware update for each token, shaped by whatever the rest of the sequence contributed.

Consider the word "mole." In "American true mole" it refers to an animal; in "biopsy of the mole" it refers to a skin lesion. The initial embedding for "mole" is identical in both cases — the same token ID, the same row in the embedding matrix. Attention is the mechanism that fixes this: it lets each token update its vector based on the other tokens around it, incorporating context into the representation.

Each token simultaneously plays two roles: it asks a question about what context it needs, and it offers an answer about what it contains. The three learned projections that implement this are:

  • Q (Query) — the question a token is asking. Example: "are there any adjectives before me?" Computed by multiplying the token's current vector by a learned weight matrix WQ.
  • K (Key) — the label a token offers about itself. Example: "I am an adjective." Computed via WK.
  • V (Value) — what a token sends when attended to. Computed via WV.

Implementation detail: diagrams often show WQ, WK, and WV as separate projections, but inference engines commonly compute them with one fused matrix multiplication and then split the result into Q, K, and V head slices. The algebra and tensor shapes are the same.

H = LN(X) with shape (N, 12,288) fans out to three weight matrices W_Q, W_K, W_V each (12,288 × 12,288), producing Q = H W_Q, K = H W_K, V = H W_V each (N, 12,288). Each is then reshaped into 96 head slices of 128 dimensions: head 0 takes dims 0–127, head 1 dims 128–255, through head 95 taking dims 12,160–12,287. A handoff note reads: Figure 9 uses one slice — Q_h, K_h, V_h each (N, 128).
Figure 8. H = LN(X) is projected by three learned weight matrices — W_Q, W_K, W_V, each (12,288 × 12,288) — to produce Q, K, and V, all shape (N, 12,288). Each is then partitioned into 96 head slices of 128 dimensions: head h receives columns h × 128 through (h + 1) × 128 - 1. Figure 9 zooms into one such slice.

How attention computes relevance

For a given token, attention works as follows:

  1. Compute its Q vector by multiplying its current vector by WQ.
  2. Compute every other token's K vector by multiplying each of their vectors by WK.
  3. Take the dot product of Q with each K — positive means the key aligns with the query (relevant), near zero means unrelated, negative means they point in opposite directions. This produces a row of raw scores. In scaled dot-product attention, those scores are divided by √dhead — √128 in GPT-3 — because unscaled dot products grow with vector width and can push softmax into overly sharp, saturated distributions.
  4. Apply softmax to convert those scores into probabilities that sum to 1. For example, "sat" in "the cat sat down" might produce [0.15, 0.60, 0.25, 0.00] — paying 60% attention to "cat", 25% to itself, 15% to "the", 0% to "down" (masked). Every token in the sequence does this, producing one row each. Stacked together they form the attention pattern: a context-size × context-size grid where each row sums to 1 and the strictly upper triangle is zero due to causal masking, as shown in Figure 9. Dense attention therefore has O(N²) score and weight entries for a sequence of N tokens, which is one reason long context windows are expensive.
  5. Use each token's row of weights to blend the V vectors. "Sat" takes 60% of V("cat") + 25% of V("sat") + 15% of V("the"). The result is a change vector (Δ) — not a replacement, but an update added back into the token's residual stream, refining its representation with contextual information.
Two-phase figure for one attention head, sequence the cat sat down (N = 4). Phase 1: three 4x4 matrices showing Q head times K head transposed divided by sqrt(128) scaled scores, then causal mask with upper triangle set to negative infinity, then row-wise softmax attention pattern A head where row sat shows 0.15, 0.60, 0.25, 0.00. Phase 2: A head (4,4) multiplied by V head (4,128) token rows V the, V cat, V sat, V down produces O head (4,128) output rows; O sat = 0.15 V the plus 0.60 V cat plus 0.25 V sat. 96 per-head outputs concatenate then pass through W_O to form delta_attn.
Figure 9. Scaled dot-product attention for one head, shown on a four-token toy sequence. Phase 1: Q_head K_head^T / sqrt(128) produces one score for every query-token/key-token pair. The causal mask sets future positions to -infinity, and row-wise softmax turns each row into the attention pattern A_head. In the "sat" row, the head attends most to "cat" (0.60), then itself (0.25), then "the" (0.15). Phase 2: A_head * V_head = O_head maps (4, 4) * (4, 128) to one-head output shape (4, 128); for example O_sat = 0.15 V_the + 0.60 V_cat + 0.25 V_sat. Across GPT-3's 96 heads, these outputs concatenate to (N, 12,288), then W_O maps the result back into the residual stream as Delta_attn.

Causal masking constrains the attention pattern: each token can only attend to itself and tokens that came before it. Future tokens are masked out (their scores set to −∞ before softmax, so they receive zero probability). This is what enables the model to predict left-to-right — and it is why generation must be sequential: each new token can only see what came before it. During training, masking also enables efficiency: all token positions can be trained in parallel in a single forward pass, since each position can only see its own prefix.

Multi-head attention runs this entire process in parallel across many independent "heads" — 12 in GPT-2 small, 96 in GPT-3. This is where the 12,288 embedding dimension connects back to what you saw in the embedding matrix:

The three quantities — embedding dimension (12,288), number of heads (96), and dimensions per head (128) — are jointly chosen and must satisfy: dmodel = nheads × dhead. Any two determine the third. The full 12,288-dimensional token vector is split into 96 equal slices, one per head, each 128 dimensions. More heads means smaller slices; fewer heads means larger slices; the total always sums back to 12,288.

What does 128 dimensions per head actually mean?

Each head is handed a 128-dimensional slice of the Q matrix and a 128-dimensional slice of the K matrix. The dot product of Q and K produces one relevance score. So 128 is the resolution of the matching: how nuanced a head's sense of "relevant" can be. With 1 dimension a head could only ask "similar or not." With 128 it can encode much finer distinctions. What each of those 128 numbers represents individually is not human-interpretable — the training process learns what Q and K should look like in 128-number space to make the attention pattern useful. 128 is a canonical choice found to work well empirically; BERT uses 64 per head, for instance.

Each head learns to specialise. One might track subject-verb agreement, another pronoun references, another long-range topic coherence. They run in parallel, their 128-dimensional outputs are concatenated back into a single 12,288-dimensional update, and the model gets 96 different "readings" of the same token at the same time.

Four-stage left-to-right diagram. Left: four representative per-head output tensors O head 0, O head 1, ellipsis, O head 95, each shape (N, 128). Center: the 96 outputs concatenated column-wise into shape (N, 12,288), shown as four labeled column strips: head 0 (128 cols), head 1 (128 cols), dots for 93 more, head 95 (128 cols). Right of concat: W O weight matrix (12,288 by 12,288, approximately 151 million parameters, note: mixes all heads) multiplied to produce delta attn (N, 12,288), which is added to the residual stream.
Figure 10. After the 96 per-head computations from Figure 9, each head’s output O_head has shape (N, 128). The outputs are concatenated column-wise — not summed — placing each head’s 128-column slice side by side to form O_all with shape (N, 12,288). The output projection multiplies this tensor by W_O: O_all * W_O = Delta_attn. This mixes information across heads while preserving shape (N, 12,288); Delta_attn is then added to the residual stream.

What is stored vs what is computed

What actually lives in the model file are the weight matrices WQ, WK, WV, and WO — one set per block, learned during training, permanent. In GPT-3 each is 12,288 × (96 × 128) — input dimension × (heads × dimensions per head) — so the four attention matrices together hold 4 × 12,288 × (96 × 128) ≈ 604M parameters per block, totalling ~58B across all 96 blocks.

Q, K, and V are not model parameters — they are activations computed from the current residual-stream vectors for each forward pass. Q is used immediately to score relevance and then discarded. K and V are retained so that future tokens can attend to past ones without recomputing them. This growing collection of saved keys and values is held dynamically in memory by the inference engine as the KV cache.

Why Q is temporary but K and V persist.

Q encodes what the current token is looking for right now — it is only needed for this one step and is discarded. K and V encode what every prior token offered and sent — information that remains valid for all future decode steps. Saving them avoids recomputing the entire prompt on every new token. This is the KV cache, and it is why the memory cost of inference grows with context length, not just model size.

MLP: Where Patterns Are Stored

After attention, each token's updated vector passes independently through an MLP (multi-layer perceptron) sublayer, also called the feed-forward network (FFN) in transformer papers. Attention is about communication between tokens; MLP works on each token privately, applying learned patterns to its own representation.

The MLP has three operations:

  1. Up-projection (The Keys): multiply the token vector by a large weight matrix, expanding it to a higher dimension (768 → 3,072 in GPT-2 small; 12,288 → 49,152 in GPT-3 — a standard 4× expansion ratio). With the row-vector convention used here, each column of Wup acts as a pattern detector. Research suggests that these columns act as "keys" in a key-value memory, lighting up when the token's context matches a specific learned concept.
  2. Nonlinearity (The Filter): apply an activation function. GPT-2/3 use GELU, a smooth alternative to ReLU; newer models often use SwiGLU. This element-wise nonlinearity acts as a filter: it squashes weak alignments to near zero, allowing only the strongly triggered pattern detectors to fire. Without this step, stacking matrix multiplications would mathematically collapse into a single linear matrix, destroying the network's depth.
  3. Down-projection (The Values): multiply back down to the original dimension. The rows of Wdown act as the "values" associated with the keys. When a pattern detector survives the nonlinearity, it triggers its corresponding row in Wdown — grabbing the actual stored knowledge or vocabulary update — and adds that vector back into the token's residual stream.
Five-stage left-to-right computation. Input: LN(X-prime) shape (N, 12,288). It is multiplied by W up, a (12,288 by 49,152) matrix with approximately 604 million parameters, producing hidden activations (N, 49,152). GELU applies x times Phi(x) element-wise. The result is multiplied by W down, a (49,152 by 12,288) matrix with approximately 604 million parameters, producing delta MLP (N, 12,288), which is added to the residual stream.
Figure 11. The MLP sublayer for one transformer block. LN(X') is the residual stream after attention, normalised before entering the MLP. The up-projection multiplies it by W_up, giving hidden activations with shape (N, 49,152). GELU is applied element-wise as x * Phi(x), smoothly scaling each hidden activation. The down-projection then multiplies by W_down, giving Delta_MLP with shape (N, 12,288). This update is added to the residual stream. W_up and W_down together hold ≈ 1,208M parameters per block — roughly twice the attention sublayer’s parameter count.

A concrete example of what this stores: imagine a column in Wup that acts as a key for the pattern "Michael Jordan". When those words appear in the context, that neuron activates. The corresponding row in Wdown then dumps its value — information about "basketball" — into the residual stream. Multiply this by billions of neurons across all MLP layers and you have a model that stores an enormous amount of world knowledge.

Because of this, MLPs play a major role in factual recall. Meng et al. (2022) even demonstrated that specific facts can be located in mid-layer MLP weights and surgically edited. However, saying MLPs are the only place knowledge lives is a useful approximation, not a complete picture, as attention heads and the residual stream also contribute. What is clearly true is their scale: in GPT-3 each MLP block holds Wup (12,288 × (4 × 12,288)) and Wdown ((4 × 12,288) × 12,288) — the factor of 4 is a standard expansion ratio, together ≈ 1,208M parameters per block — roughly twice the attention weight count. Across 96 blocks that is ~116B, or about two-thirds of GPT-3's 175B total.

Mixture of Experts: splitting the MLP

GPT-3 uses a single MLP per block — a dense design where every token is processed by the same MLP weights. An increasingly common alternative is Mixture of Experts (MoE), which replaces that single MLP with several expert MLPs plus a lightweight learned router. The router examines each token's representation after attention, scores it against the experts, and picks a small top-k set for that token — often 1 or 2 in early MoE models, though some modern models activate more. Each selected expert runs its own up-projection → nonlinearity → down-projection independently; their outputs are weighted by the router's confidence scores and summed back into the residual stream. In the standard transformer MoE variants discussed here, the attention mechanism is unchanged — MoE modifies the feed-forward sublayer. Despite the name, "experts" do not cleanly specialize in human-understandable domains like biology or law; research on Mixtral shows they tend to specialize at the token and syntax level, handling specific tokens in specific contexts.

The practical consequence is a split between total parameters (all experts, which determine the memory footprint because all expert weights must be available to the runtime) and active parameters (the small subset of experts used for a given token, which largely determines per-token feed-forward compute). Mixtral 8x7B has 8 expert MLPs per block and routes each token to 2, giving it 46.7B total parameters but about 12.9B active per token — memory scales like a 47B model, while feed-forward compute is closer to a 13B dense model. More recent examples include Qwen3-235B-A22B (235B total, 22B active), DeepSeek-V3 (671B total, 37B active), and Gemma 4 26B A4B (25.2B total, 3.8B active). For a thorough visual walkthrough of routing, load balancing, and the active-vs-total parameter accounting, see Grootendorst's Visual Guide; the MoE explainer from HuggingFace covers the same ground more concisely. The architecture was popularized by the Switch Transformer (2021), which showed that scaling expert count while keeping active compute roughly constant can improve quality per unit of compute.

How the model recovers from bad tokenizations

The recovery mostly happens later, through context. In “artificial intellignece”, the misspelled token starts from odd subword embeddings, but it appears beside “artificial”. Attention lets that token position gather information from surrounding tokens, and the MLP layers can contribute learned lexical and spelling-pattern associations. By later blocks, the residual-stream vector may be close enough to the intended meaning that the next-token distribution behaves normally.

This breaks down when context is weak or the typo is too far from familiar text. Random keystroke strings, rare proper nouns, technical jargon, and multilingual misspellings are harder. The model may also preserve a typo if copying the user’s exact wording or style is useful.

Superposition: How 12,288 Dimensions Hold Millions of Concepts

The embedding chapter introduced concepts as directions in a 12,288-dimensional space. With the transformer stack now in view — vectors entering from WE, then updated by attention and MLP across 96 blocks — here is how that space actually accommodates millions of concepts and what disturbs it.

Together, attention and MLP produce contextual representations: the same token can end up pointing in completely different directions depending on its surroundings. “Bank” in “river bank” and “bank” in “savings bank” start from the same row in the embedding matrix. But after the attention and MLP sublayers have updated those vectors through the transformer stack, they point in meaningfully different directions — each refined by context into a distinct representation.

An important subtlety: the model needs to represent far more concepts than it has dimensions — royalty, past tense, Python syntax, sentiment, geography, and millions more — yet it only has 12,288 dimensions. How? In high-dimensional space you can fit many more directions than you have dimensions. In 2D you can only have 2 truly perpendicular directions, but you can pack many more nearly perpendicular ones before they start overlapping significantly. At 12,288 dimensions this scales dramatically, allowing an exponentially large number of near-orthogonal directions. The model uses one direction per concept, each encoded as a specific combination of many dimensions rather than a single dedicated one. This packing strategy is called superposition.

Anthropic’s mechanistic interpretability research provides direct evidence for this structure: they found individual directions in transformer representations that correspond to remarkably clean concepts — “this is inside a quotation,” “the sentiment is positive,” “this is Python code” (Towards Monosemanticity, Bricken et al., 2023). Some features are surprisingly human-readable, but most are distributed across many dimensions and discoverable only through specialised analysis.

Quantization disturbs this because it rounds small numerical differences away. Two concepts encoded as slightly different directions may collapse to the same direction after rounding — the model can no longer distinguish them. This is one reason researchers think aggressive quantization can hurt quality disproportionately, though the precise interaction between quantization and representation quality is still an active area of research.

Unembedding: Predicting the Next Token

High-level GPT-3 output stage. The final residual stream X96 enters from the transformer stack. The model selects the last row, applies final LayerNorm, projects through the unembedding matrix W_U to produce logits, applies softmax and sampling to choose the next token, then appends that token to the sequence and repeats decoding.
Figure 12. The output stage as a component diagram. The transformer stack produces X96; the output head uses only the last row, applies final LayerNorm, projects through W_U to produce logits, then converts logits to probabilities and samples the next token.

After the final block and final LayerNorm, the unembedding matrix takes the last token's vector and produces one score for every entry in the vocabulary — 50,257 scores in total for GPT-3. The last token is used because, in a causal (left-to-right) model, each token's representation encodes everything needed to predict what comes next — and the last token has attended to all previous tokens, so it carries the most complete context. These scores are called logits. (Note: Many models tie WU to WET to save parameters, though this only saves a negligible ~617M parameters in a 175B model; we show the untied accounting below).

During training and prompt prefill, every token position has a final residual-stream row and can be projected to logits for its own next-token prediction. During autoregressive generation (the token generation loop), the runtime only needs the last row: that row predicts the single next token to append.

Sampling: choosing one token from logits

The sampler converts logits into one chosen token (as visualized in Figure 13). In a typical inference runtime, the pipeline is: adjust logits with temperature and other logits processors, optionally filter candidates with top-k or top-p, apply softmax or renormalize to get probabilities over the remaining candidates, then sample one token. Libraries differ in the exact ordering of top-k/top-p and softmax, but the intent is the same: shape the candidate distribution before drawing a token.

Temperature controls how the distribution is shaped before sampling:

  • Temperature = 0: implementations usually skip softmax(logits / T) and choose the argmax token directly, giving deterministic greedy decoding.
  • Temperature < 1: high-scoring tokens dominate more aggressively — the model stays on-track but may be repetitive.
  • Temperature = 1: raw probabilities used as-is.
  • Temperature > 1: the distribution flattens — lower-probability tokens become more likely, producing more varied output, at the cost of coherence at high values.

Temperature is a probability-shaping parameter, not a creativity or reasoning dial: it changes how aggressively the sampler favors high-scoring tokens after the model has already computed its logits.

Top-k sampling further limits the candidate pool to the k highest-probability tokens; top-p (nucleus) sampling keeps only the smallest set of tokens whose probabilities sum to at least p.

Five-stage computation. Stage 1: the residual stream has N rows; only the last row (token N-1, shape 1 by 12,288) is used for next-token prediction after final LayerNorm; the preceding N-1 rows are not projected. Stage 2: the last row is multiplied by W_U (12,288 by 50,257, approximately 617 million parameters, equal to W_E transposed if weight-tied), producing logits of shape (50,257). Stage 3: a bar chart shows the 50,257 raw logit scores; a few tokens score much higher (on: 6.2, down: 5.8, quietly: 4.1, purring shown) while 50,253 more tokens score much lower. Stage 4: softmax converts logits divided by temperature T to a probability distribution summing to 1. Stage 5: the next token, here 'on', is sampled and appended to the sequence.
Figure 13. Unembedding: only the last token’s (1, 12,288) residual-stream vector is used for next-token prediction; the preceding N-1 rows are not projected. Final LayerNorm is applied, then the row is multiplied by W_U (12,288 × 50,257), producing 50,257 raw logit scores — one per vocabulary token. The bar chart illustrates the typical shape: a handful of plausible next tokens score much higher than the rest of the vocabulary. Softmax (with temperature T applied to the logits before exponentiation) converts these scores to a probability distribution summing to 1. One token is sampled and appended to the sequence; the decode loop then repeats.

The Generation Loop: Prefill Then Decode

A complete inference run has two distinct phases with fundamentally different performance characteristics:

Prefill processes the entire input — system prompt, conversation history, tool schemas, user message — in one forward pass. All tokens flow through the transformer in parallel. This exploits the GPU's ability to perform massive matrix multiplications across the full sequence simultaneously. Prefill is compute-bound: the speed is limited by how fast the GPU can perform arithmetic. The result is the first generated token and a fully populated KV cache for every input token.

Decode generates output one token at a time in an autoregressive loop — each generated token is appended to the input and becomes context for the next step. Each step processes only the newest token: compute its Q, K, and V; append the new K and V to the cache; run attention against the full cache; run MLP; project to logits; sample the next token. Then repeat. Because each step processes just one token instead of the full sequence, the GPU performs far less arithmetic but must still read the entire model weight set and the full KV cache from memory. Decode is memory-bandwidth-bound: the GPU spends most of its time waiting for data to arrive from memory, not computing.

Throughout the rest of this section, t refers to the current decode position. Before step t begins, the cache holds K and V rows for positions 0 through t−1. The step computes Qt, Kt, and Vt for the new token, appends Kt and Vt to the cache, then uses Qt to attend over all t+1 positions — the current token attends to itself as well as every earlier token.

Table 1. Comparing Prefill and Decode. Prefill runs once per request and is compute-bound; Decode runs iteratively per token and is memory-bandwidth-bound.

Aspect Prefill Decode
How often Once per request Once per generated token
Input token IDs Full prompt, shape (N,) Newest token only, shape (1,)
Residual stream (N, 12,288) (1, 12,288)
Q/K/V computed for All prompt tokens Newest token only
Attention per head (N, N) attention pattern (1, t+1) attention row over positions 0 through t
KV cache Created and populated for all prompt tokens Read, then extended by one K row and one V row
Unembedding Only the last row is needed for generation The single row is projected to logits
Main bottleneck Compute-heavy matrix work Memory bandwidth: weights and growing KV cache

Same weights, different leading dimension. Prefill batches the whole prompt through the model once; decode repeatedly calls the same model one token at a time, reusing cached K and V from earlier tokens. That shape change is why prefill is good at using GPU arithmetic throughput, while decode is dominated by reading weights and the growing KV cache from memory.

Two-region figure. Left: the KV cache shown for one attention head after appending the current token, with K rows (t+1 by 128) and V rows (t+1 by 128) for positions 0 through t. The new K_t and V_t rows are highlighted. The cache box is one head only; the global GPT-3 cache grows by approximately 4.7 MB per token across all 96 layers and 96 heads at FP16. Right: residual row X_t at position t. W_Q, W_K, W_V are all applied: Q_t, K_t, and V_t each have shape (1, 128). Q_t scores against K_0 through K_t to produce attention weights A_t (1, t+1); A_t blends V_0 through V_t to give per-head output O_t (1, 128). O_t feeds into 96-head collect, W_O, MLP, and W_U to sample token ID t+1. Decode is memory-bandwidth-bound.
Figure 14. One autoregressive decode step, shown for one attention head (memory numbers below are global GPT-3). The KV cache (left) is shown after the current rows K_t and V_t have been appended, so it contains positions 0 through t and has shape (t+1, 128) for this head. For the current residual row X_t, all three projections W_Q, W_K, W_V are applied: Q_t, K_t, and V_t each have shape (1, 128). Q_t scores against K_0..t, producing attention weights A_t of shape (1, t+1) after softmax; A_t then blends V_0..t to give per-head output O_t of shape (1, 128). Prior tokens’ K and V are reused, never recomputed. O_t feeds through 96-head concatenation, W_O, MLP, and W_U to sample token ID t+1. Because each step must read the full KV cache and all model weights from memory while performing far less arithmetic than prefill, decode is memory-bandwidth-bound.

This is why memory bandwidth (GB/s) predicts local inference speed — not GPU compute power (TFLOPS), not clock speed.

Every new decode step reads the cached K and V instead of recomputing them from scratch. For GPT-3 at FP16, each token adds 2 (K and V) × 96 layers × 96 heads × 128 dimensions × 2 bytes ≈ 4.7 MB of KV cache. A full 2,048-token context is about 9.7 GB in decimal units, or about 9.0 GiB, separate from the roughly 350 GB needed for FP16 weights. Modern long-context systems can be much cheaper because GQA/MQA use fewer K/V heads, runtimes can manage the cache in pages or blocks, and some also quantize the KV cache.

The size of the cache depends on the model’s architecture. A model with fewer KV heads (GQA) has a dramatically smaller cache than one with full multi-head attention — one of the practical reasons modern models favour GQA.

The attention description above covers standard dense multi-head attention (MHA). To avoid the O(N²) memory bottleneck, modern implementations compute this exact attention using FlashAttention, which vastly speeds up the compute-bound prefill phase without ever materializing the full attention matrix in GPU memory. Real models also vary significantly in their attention patterns: GPT-3 itself alternated dense and locally banded sparse attention layers; Grouped-Query Attention (GQA) shares K/V heads across query groups to cut memory; Multi-head Latent Attention (MLA) compresses K/V into a smaller latent vector; Sliding Window Attention (SWA) limits each token to attending only nearby tokens for long-context efficiency. Raschka’s A Visual Guide to Attention Variants in Modern LLMs covers all of these with diagrams.

One consequence of the autoregressive loop: the model can only work within a fixed context window — the maximum number of tokens it can process at once. This is a hard architectural limit set during training (GPT-3 used 2,048 tokens; modern models typically support 32K to 262K). Everything the model knows about your request must fit inside this window: system prompt, conversation history, tool schemas, documents, and the response being generated. Tokens that fall outside the window are simply invisible to the model.

Speculative decoding: breaking the one-token-at-a-time barrier

Standard decode is strictly sequential — causal masking means each token must exist before the next can be computed. But the hardware is underutilized during decode: the GPU reads the full weight set and KV cache from memory yet performs very little arithmetic on that single token. Speculative decoding exploits this idle compute by having a fast, cheap source propose several draft tokens at once, then verifying all of them in a single parallel forward pass through the full model — similar in cost to prefill, where batch processing is efficient. Tokens the full model agrees with are accepted; the first disagreement triggers re-sampling at that point, and the draft cycle restarts. Because verification uses rejection sampling, the output distribution is mathematically identical to standard decoding — there is no quality loss.

The two main approaches are draft-model speculation, where a separate smaller model (typically 0.5B–3B) proposes tokens (llama.cpp supports this via `--model-draft`), and Multi-Token Prediction (MTP), where the model is trained with auxiliary prediction heads that draft from the target's own representations, without a separate standalone model — Google’s Gemma 4 ships with MTP heads, reporting up to 3× speedup, and Ollama merged native MTP support for Gemma 4 on Mac. A third family, EAGLE, attaches a lightweight trained prediction head to the target model’s internal representations; EAGLE-3 checkpoints are available on HuggingFace for Llama 3.3 70B, Qwen3, and others, and are supported by vLLM and SGLang.

Speculative decoding is becoming a standard inference optimization — it targets the decode bandwidth bottleneck directly by producing multiple accepted tokens per full-model memory read.

Training vs. inference.

The forward pass described above is inference — generating output from a fixed model. During pre-training, the same forward pass runs on enormous amounts of text with a simple objective: predict the next token. The error between the predicted probability and the actual next token is used to adjust every weight in the model through backpropagation. For GPT-3, this process covered 300 billion token positions. After pre-training, a base model exists that can predict text but does not yet follow instructions. A second training phase — instruction fine-tuning, often combined with reinforcement learning from human feedback (RLHF) — teaches the model to be helpful, follow directions, and decline harmful requests. The result is what you interact with as a chat or coding assistant.

Emergent abilities.

A striking property of large-scale pre-training is that models develop capabilities they were never explicitly trained for. A model trained only on next-token prediction can perform translation, summarization, arithmetic, code generation, and logical reasoning — not because these tasks were in the training objective, but because they are implicit in the patterns of a large enough text corpus. These are called emergent abilities: they appear at sufficient scale and are largely unpredictable in advance. Few-shot learning (performing a task from just a few examples in the prompt) and zero-shot generalization (performing a task with no examples at all) are the most practically useful manifestations of this.

Why Model Size Equals Memory Requirement

Every learned parameter described above is a floating-point number that must live in memory while the model runs. For GPT-3, the full tally:

  • WE (embedding matrix): 50,257 × 12,288 = ~617M
  • WP (learned position embeddings): 2,048 × 12,288 = ~25M
  • Attention weights (WQ, WK, WV, WO): 4 × 12,288 × (96 × 128) × 96 blocks = ~58B
  • MLP weights (Wup, Wdown): 2 × 12,288 × (4 × 12,288) × 96 blocks = ~116B
  • WU (unembedding matrix, if untied): 12,288 × 50,257 = ~617M
  • Biases and LayerNorm parameters: ~15M — negligible at this scale
  • Total with untied WU: ~175.2B
  • Total with tied WU = WET: ~174.6B
Two-panel figure. Left: per-block ledger for one of 96 transformer blocks. Attention sublayer: W_Q, W_K, W_V, W_O each 12,288 by 12,288 and approximately 151M parameters, subtotal approximately 604M; 604M times 96 equals approximately 58B total. MLP sublayer: W_up (12,288 by 49,152, approximately 604M) and W_down (49,152 by 12,288, approximately 604M), subtotal approximately 1,208M; 1,208M times 96 equals approximately 116B total. Block total approximately 1,812M. Right: full GPT-3 175B stacked bar showing embeddings W_E plus W_P (approximately 642M, under 0.4 percent), attention across 96 blocks (approximately 58B, 33 percent, blue), MLP across 96 blocks (approximately 116B, 66 percent, purple), and W_U (approximately 617M, under 0.4 percent). Memory rows: FP16 approximately 350 GB, Q4_K_M approximately 87 GB. Biases and LayerNorm approximately 15M, negligible.
Figure 15. GPT-3 parameter ledger. Left: one transformer block holds four attention matrices (W_Q, W_K, W_V, W_O, each 12,288 × 12,288 ≈ 151M) for a 604M attention subtotal, and two MLP matrices (W_up 12,288 × 49,152 and W_down 49,152 × 12,288, each ≈ 604M) for a 1,208M MLP subtotal — 1,812M per block. Each of the 96 blocks has its own independent weights, so transformer blocks alone hold ~174B; adding embeddings, W_U, and biases (~1.3B) reaches ~175.2B total. Right: the full-model stacked bar is at true proportions — MLP visibly dominates at 66%, attention is 33%, and embeddings plus W_U are the barely-visible slivers at each edge (a tiny teal mark in the left sliver indicates the W_P portion). Untied W_U accounting shown; tied accounting reuses W_E^T (subtract ~617M). The lower bars compare memory footprint at FP16 (≈ 350 GB) and Q4_K_M (≈ 87 GB+, a lower bound since real quantized formats include scale and metadata overhead). Both are weights only; the KV cache and runtime allocations add further.

Published model sizes are rounded, so both accounting conventions are compatible with the advertised 175B-parameter scale.

The KV cache is a separate runtime allocation on top of these weights — it is not part of the model file but competes for the same memory pool during inference.

At full 16-bit precision (BF16 or FP16), each parameter occupies 2 bytes. A model with B billion parameters requires approximately 2B bytes — 2 GB per billion parameters — just for the weights. A 70B model at FP16 needs ~140 GB before the KV cache is even considered.

Quantization reduces this by storing weights at lower bit widths. A 4-bit quantized model (Q4_K_M) uses roughly 0.5 bytes per parameter, cutting the 70B footprint to ~40 GB. The tradeoff is precision loss: quantized values are approximations of the originals. The relationship between quantization aggressiveness and quality degradation is not linear — and because of superposition, the impact depends heavily on which weights are compressed and how the model uses them.

By this point you’ve traced the full forward pass: tokens become vectors via WE and WP; the residual stream flows through 96 transformer blocks that update it via attention (token-to-token communication) and MLP (per-token pattern application); the final residual-stream row is projected through WU to logits and sampled. Generation is the same pass repeated once per token, with K and V cached so prior tokens never need to be re-encoded.