One Transformer block, counted
You now own every part of a Transformer block. The residual stream carries each token up through the model (§5.1), norms keep what each sublayer reads at a fixed scale (§5.2), the feed-forward network transforms each token on its own (§5.3), and RoPE or a learned table tells positions apart (§5.4, §5.5). This section bolts them together and asks the questions an engineer asks of any block before building a model from it. How many parameters does it hold? How many floating-point operations does one token cost, forward and backward? Which of those numbers change when you swap GPT-2's recipe for LLaMA's?
Here is the kind of answer you should be able to give on a whiteboard. One block of GPT-2 small holds exactly 7,087,872 parameters. Pushing one token through it costs about 14.2 million FLOPs in its weight matrices plus 3.1 million in attention over a 1,024-token context (counting the full score matrix), and training on that token costs three times as much. A whole model is copies of the block plus a fixed overhead for the vocabulary, so these per-block numbers are how you budget a run, sanity-check a paper, and catch bugs. A block whose count is off by 1,536 has lost a LayerNorm. Interviewers ask these questions because they separate people who have built models from people who have read about them.
Assembling a decoder block
A GPT-2 block takes the stream for tokens of width and applies two pre-LN residual sublayers (§5.2),
where is causal multi-head attention with heads of size (§4.5, §4.4) and is the GELU MLP of §5.3 with . Every shape along the way is worth writing out once.
| step | operation | shape |
|---|---|---|
| input | stream | |
| norm | ||
| projections | with | |
| split heads | reshape each to | |
| scores | plus causal mask, softmax | |
| mix | weights times , merge heads | |
| write | ||
| FFN |
A model stacks such blocks between an embedding and an unembedding. Token and position embeddings form the first stream , the blocks run in sequence, a final norm normalizes the last stream, and the unembedding turns it into one row of next-token logits per position,
Here the superscript counts blocks (unlike §5.1, where it counted sublayers), and is the vocabulary size. GPT-2 reuses its token table as the unembedding, , which is called weight tying (Press & Wolf, 2017). Building that whole model end to end, embeddings, head, and every last parameter, is the job of §6.2. This section stays with the block, because everything else is a fixed overhead on top of copies of it.
The LLaMA recipe changes five things and keeps the skeleton. LayerNorm becomes RMSNorm (§5.2), learned positions are replaced by RoPE inside attention (§5.5), the GELU MLP becomes SwiGLU with (§5.3), every bias is removed, and the output matrix is a separate parameter rather than tied. Larger LLaMA models also share keys and values across groups of query heads, which is called grouped-query attention (Ainslie et al., 2023, and §12.5), and which matters for counting.
Three families of Transformer
The block is the same in every family. What differs is the attention mask and how the stacks are wired.
| family | attention | trained to | strengths | examples |
|---|---|---|---|---|
| encoder-only | bidirectional, every token sees every token | fill in masked tokens | representations for classification, retrieval | BERT, RoBERTa (§7.1) |
| decoder-only | causal, each token sees its prefix | predict the next token | generation, in-context learning, one stack for everything | GPT, LLaMA, Mistral |
| encoder-decoder | bidirectional encoder, causal decoder with cross-attention to it | map an input sequence to an output sequence | translation, summarization, explicit input/output split | original Transformer, T5, Whisper |
Decoder-only models now dominate because one causal stack covers every task once tasks are phrased as text, because every token of every document provides a training signal, and because generation with a KV cache (§6.5) is simple and efficient. Section 8.1 compares the training objectives behind the three families. An encoder-decoder's decoder blocks contain a third sublayer, cross-attention (§4.6), with its own four projections and its own norm, which shows up in the count below.
Counting one block exactly
Count one GPT-2 block, piece by piece.
- Attention. is with a bias, and is with a bias, so .
- FFN. is with a bias, and is with a bias, so .
- Two LayerNorms. A gain and a shift each, so .
Writing for the parameters of one block, the total is
In plain words, each block costs twelve matrices' worth of weights, four in attention and eight in the FFN, plus a few vectors of size that hardly matter.
GPT-2 small, by hand. With , one block has parameters, and the 12 blocks hold . The rule of thumb is within 0.15% of that. Yet the released checkpoint has about 124 million parameters. The other 39 million live outside the blocks, and §6.2 finds every one of them.
LLaMA-2 7B, by hand. Now there are no biases, the norms are RMSNorm with a gain only ( each), and the FFN is SwiGLU with three matrices of . With and , one block has attention weights, FFN weights, and norm weights, a total of . The 32 blocks hold , almost all of the model's 6.7 billion. Because is rounded up, the block is again (12.06 after the rounding). The rule survives the change of recipe.
Grouped-query attention breaks it. With query heads but only key-value heads, and shrink to , so attention costs . LLaMA-2 70B (, , , ) has , so its attention is instead of . At the same time its FFN is wider than the 8/3 rule (), so the FFN is . The block comes to plus of norm gains, parameters, and more than four fifths of it is FFN. LLaMA 3 8B makes the same trade at ( of 32 heads, so attention is , and ) and lands at per block, plus its two norm gains.
The encoder-decoder block. A decoder block with cross-attention has a second set of four attention projections and a third norm. With and biases it holds , so the original Transformer's base model () has 3,152,384 parameters per encoder block and 4,204,032 per decoder block.
The cell below prints the split for real configurations.
Count one block exactly, for any recipe
Write block_params(cfg) returning the exact number of parameters in one Transformer block, for a config dictionary with these keys.
d_model,n_head,d_ffn_kv_head(defaultn_head), the number of key-value heads for grouped-query attention, each of width =d_model // n_headbias(bool), biases in every linear layer and, for LayerNorm, the shiftnorm,"layernorm"(gain, plus shift whenbiasis true) or"rmsnorm"(gain only)ffn,"mlp"(two matrices) or"swiglu"(three matrices)cross_attn(defaultFalse), whether the block also has a cross-attention sublayer with its own projections and its own norm, as in an encoder-decoder's decoder
A block has one norm per sublayer. The tests check GPT-2 small and XL, LLaMA-2 7B and 70B, LLaMA 3 8B, and a decoder block of the original Transformer, all exactly.
FLOPs per token and the 6N rule
The arithmetic cost of a Transformer is dominated by matrix multiplications, and those are easy to count. Multiplying by takes multiply-adds, or floating-point operations (FLOPs), the convention of §4.7.
Forward, one block. A linear layer with and costs FLOPs, which is per token, two FLOPs per weight per token. A GPT-2 block's matrices hold weights, so they cost FLOPs per token, a third in attention's projections and two thirds in the FFN. The two attention products with no weights, the scores and the weighted sum of values, cost each per head for a token that attends to positions, so per token across all heads (§4.7 counted them product by product). Biases, norms, activations, and the softmax add only or per token, which we ignore. For GPT-2 small at that is million FLOPs in the weights and million in attention, per token and per block.
The whole forward pass. Summing over the blocks and adding the unembedding, a by product that costs per token whether or not it is tied, the forward pass costs about FLOPs per token plus attention. Here counts the weights that take part in matrix multiplications, every block matrix plus the unembedding. Embedding lookups cost no multiplications, so the input tables are not in .
Backward. Given , a linear layer needs two products (§0.2), one to pass the gradient down and one for its own weights,
So the backward pass costs twice the forward, per token, and training costs
for training tokens, where means , which for large models is close to the total parameter count.
In plain words, every weight is used once going forward (a multiply and an add) and twice going backward (once to pass the gradient on, once to compute its own gradient), so training costs six operations per weight per token.
The attention term. The weightless products follow the same rule. Their backward pass is again two products of the same size (§4.3), so training triples the forward per layer, and the full per-token cost is
This counts the whole score matrix. A causal kernel that skips the masked half does about half of that work, since on average each token sees about keys. Papers do not agree on this term, so check which convention a number uses. Kaplan et al. (2020) list a forward term of in their Table 1, half of our full , which §4.7 reads as the causal count, while PaLM's utilization accounting (Chowdhery et al., 2022) uses the full for training.
How big is the attention term? With , its ratio to the weight term is . For GPT-2 small at that ratio is 0.22, and for LLaMA-2 7B at it is 0.17. Counted against everything, unembedding included, attention is 13% and 14% of the training FLOPs of these two models, as the cell below prints. The term grows with context length, which is why long-context training (§12.7) costs more per token than short-context training.
A worked example worth memorizing. GPT-3 has 175 billion parameters and was trained on 300 billion tokens, so FLOPs, and the GPT-3 paper's own table reports (its count uses 174.6 billion). On hardware that sustains FLOP/s per GPU, that is GPU-seconds, about 9,100 GPU-days. How close a real run comes to its hardware's peak, its model FLOPs utilization, is defined and measured in §6.7. The 6N rule is also the bridge to scaling laws, which ask how to split a compute budget between parameters and data (§9.3).
Two refinements come up in practice. If a run recomputes activations during the backward pass to save memory (§10.1), the hardware executes a second forward pass, about FLOPs per token, but the model's own cost is still , and utilization is quoted against the (§11.2). And for a mixture-of-experts model, in the rule is the number of parameters active per token, not the total (Chapter 13).
Inference runs only the forward pass, about FLOPs per generated token plus for attention over earlier tokens. But during one-token-at-a-time decoding, each weight is read from memory to do just two FLOPs, so decoding is limited by memory bandwidth, not arithmetic. Caching past keys and values avoids recomputing the past (§6.5), and serving many requests at once lets each weight read do work for many tokens, the central idea of batching and memory management in serving.
Training FLOPs per token, with the attention term
Write train_flops_per_token(cfg, T) returning , where counts the weights in matrix multiplications. The config uses the block keys of Exercise 5.6f plus vocab_size and n_layer (any other keys are ignored). is the block matrices of all n_layer blocks (respecting n_kv_head and ffn) plus one unembedding, whether or not it is tied, and no biases, norms, or position tables.
Memory per token, in brief
Two memory costs grow with tokens, and each has its own section later. At inference, every layer keeps the keys and values of every earlier token, numbers per token. Section 4.7 already found 128 KiB per token for Llama 3 8B in 16-bit precision, and §6.5 builds the cache and sizes it. In training, each block stores the activations its backward pass needs, about bytes per token in GPT-3-style accounting (Korthikanti et al., 2022), where the is the attention probabilities of the heads and their dropout mask and output. For a GPT-2 small block at that is 87,552 bytes per token, 70% of it attention matrices, which is why FlashAttention never stores them. Section 10.1 derives the 34 tensor by tensor and adds the 16 bytes per parameter that weights, gradients, and Adam's moments cost.
A block, from scratch in NumPy
Here is a GPT-2 block in about a dozen lines, with random weights at a toy size, stacked four deep. The prints check the two properties that matter most, that the parameter count matches and that the stack is causal (changing a later token never changes an earlier position's output).
A GPT-2 decoder block, from scratch
Write gpt2_block(X, p, H) for one token sequence X of shape (T, d), a dictionary of weights p with the keys used in the cell above (ln1_g, ln1_b, W_qkv, b_qkv, W_o, b_o, ln2_g, ln2_b, W_fc, b_fc, W_proj, b_proj), and H heads (the of the text). It is a pre-LN block with causal multi-head attention and a tanh-GELU MLP. W_qkv is laid out as in GPT-2, with the query, key, and value projections side by side in that order, and head i owns columns i*d_k to (i+1)*d_k of each. No loops over heads or positions.
This is the canonical interview implementation. The tests check it against a reference, check causality, check that a block with zeroed output projections is the identity, and catch the usual slips (the scale, the split order, the norm placement).
A stack of these blocks is the body of GPT-2. Section 6.2 adds the token and position embeddings in front, the final norm and the tied head behind, initializes the whole model, and checks it against a reference implementation.
In PyTorch
The same block in PyTorch. Built on the meta device, a GPT-2 small block is counted without allocating any memory. Then a toy-size block runs under PyTorch's FLOP counter, which confirms the forward cost exactly for one sequence of tokens.
Read more
- Radford et al. (2019). Language Models are Unsupervised Multitask Learners. GPT-2, the block counted in this section.
- Touvron et al. (2023). Llama 2, Open Foundation and Fine-Tuned Chat Models. The modern recipe and the configs used in our counts.
- Ainslie et al. (2023). GQA, Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. Grouped-query attention, which changes both the count and the cache.
- Kaplan et al. (2020). Scaling Laws for Neural Language Models. Table 1 gives the per-operation parameter and FLOP counts behind .
- Brown et al. (2020). Language Models are Few-Shot Learners. Appendix D computes GPT-3's training compute.
- Chowdhery et al. (2022). PaLM, Scaling Language Modeling with Pathways. Appendix B counts training FLOPs with the full attention term.
- Korthikanti et al. (2022). Reducing Activation Recomputation in Large Transformer Models. The activation memory of a block, tensor by tensor.
- Karpathy. nanoGPT. A compact GPT-2 implementation to compare with your counts.