Building a GPT Model Architecture
Initializing the 124M GPT model and printing its output tensor gives a shape of [2, 4, 50257], where 50257 is the tokenizer's vocabulary size.
Why the Numbers Seem Wrong
When you build the 124-million-parameter GPT model in this chapter, a common first reaction is confusion. You set up a model with that name, then add up the sizes of its parameter tensors, and the total comes out noticeably larger. It is easy to assume the setup has a bug or that the count is wrong. Neither is true. The gap comes from a design choice in the original GPT-2 architecture, and understanding that choice is the main purpose of this article.
Predicting the Parameter Total
The model is initialized with the GPT_CONFIG_124M configuration. Its total is computed by adding the element count of every parameter tensor. In Python, the element count of a tensor comes from the numel() method, and the total is produced by the expression below. Before you look at the answer, commit to a number of your own, because the point of the exercise is to notice where your intuition about the name and the actual count disagree.
What do you think happens?
The model is named 124M. Before computing anything, what total would you expect sum(p.numel() for p in model.parameters()) to return?
Reveal answer
163,009,536
The raw total is 163,009,536, which is larger than the 124 million in the name. The difference comes from the output layer, which this implementation counts separately from the token embedding layer until weight tying is applied.
Total number of parameters: 163,009,536The Shared Weight Matrix
The resolution to the mismatch is weight tying. In the original GPT-2 architecture, the weights of the token embedding layer are reused in the output layer. Instead of storing two separate matrices, the model keeps one set of values and both layers draw on it. This is the definition to hold onto: weight tying means reusing the token embedding weights in the output layer.
The sizes make the connection concrete. Both layers in this model have a weight tensor of shape 50257 by 768. The 50257 comes from the tokenizer's vocabulary, with one row for each token, and 768 is the embedding dimension, so each token has a 768-value vector. The output layer must map each hidden vector back to one score per vocabulary token, so its matrix has the same vocabulary-by-embedding dimensions. Those matching shapes are what make reuse possible. Reuse is only possible because the two matrices have identical dimensions.
Subtracting the Output Layer
Under weight tying, the output layer does not add its own large block of values. It reads from the same stored weights that the embedding layer uses. Because the output layer alone accounts for 38,597,376 values here, sharing it is a substantial saving. The tied count is therefore not a separate calculation of the model's size. It is the full count minus the parameters that weight tying makes unnecessary.
Computing the trainable count with weight tying
The raw total is 163,009,536 and the output layer holds 38,597,376 parameters. What is the trainable parameter count once weight tying is applied?
- 1Start with the full total
The raw count from summing every parameter tensor is 163,009,536.
- 2Identify the redundant parameters
Under weight tying the output layer reads the embedding weights, so its 38,597,376 parameters are not stored again. The output layer's count is the amount to remove.
- 3Subtract the output layer
Compute $163{,}009{,}536 - 38{,}597{,}376$ to get the tied count.
$163{,}009{,}536 - 38{,}597{,}376 = 124{,}412{,}160$ trainable parameters, which matches the 124 million name.
Reading the Output Tensor Shape
Parameter counts describe the model's size, but initialization also produces an output you should be able to read. The model is run on a batch of two input texts, each with four tokens. The output tensor therefore has shape [2, 4, 50257]. Each dimension has a clear meaning. The first is the batch size, which is 2 here. The second is the sequence length, which is 4 tokens per text. The last is the vocabulary size of the tokenizer, which is 50257.
The final dimension is the important one to interpret. Each token position receives a vector of 50,257 numbers, one for each token in the vocabulary. These are not yet words. A later step converts each of these 50,257-dimensional vectors back into tokens. At this stage, the goal is only to confirm that the shape is what the design predicts. Reading the shape this way means that for any position in any text in the batch, you know there is one score per vocabulary entry.
Weight Tying as a Design Trade-off
Weight tying is a trade-off, not a rule that every model must follow. It reduces the overall memory footprint and the computational complexity of the model. The author of the course text also reports that keeping separate token embedding and output layers led to better training and model performance. For that reason, the GPTModel implementation in this chapter keeps the layers separate. Weight tying will be revisited in chapter 6, when pretrained weights from OpenAI are loaded. Modern LLMs also follow the separate-layer approach.
Common Mistakes When Counting Parameters
Common mistake Assuming the raw total is wrong because it does not match the 124M name
Why it failsThe name describes the GPT-2 design as a whole, including weight sharing. The raw total counts every parameter tensor in the object you built, so it can legitimately be larger.
Do this insteadCompare the raw total against the name only after accounting for weight tying.
Common mistake Assuming the output layer and the embedding layer each store their own matrix in the GPT-2 design
Why it failsUnder weight tying the output layer reads the token embedding weights, so the two layers do not store two separate matrices.
Do this insteadSubtract the output layer's parameters, 38,597,376, from the raw total to get the tied count.
Common mistake Reading the last dimension of the output as a list of words
Why it failsEach position receives 50,257 numbers, one per vocabulary token. These are scores, not yet tokens or words.
Do this insteadTreat the final dimension as a vocabulary-sized vector per token position; converting it to tokens is a later step.
Practice Predicting Counts and Shapes
A GPT model with the same design is run on a batch of 3 input texts, each with 6 tokens. Using the vocabulary size of 50257, what is the shape of the output tensor? Then, if the output layer held 38,597,376 parameters and the raw total were 163,009,536, what would the tied trainable count be?
Hints
- The first dimension of the output is the batch size and the second is the number of tokens per text.
- The last dimension is the vocabulary size, which stays 50257 regardless of batch size or sequence length.
- Subtract the output layer's parameters from the raw total to get the tied count.
Key Takeaways
- The raw parameter total of 163,009,536 is larger than the 124M name because the output layer is counted separately in this implementation.
- Weight tying reuses the token embedding weights in the output layer, which are both shaped 50257 by 768.
- Subtracting the output layer's 38,597,376 parameters from the raw total gives the tied trainable count of 124,412,160.
- The output tensor shape [2, 4, 50257] reads as batch size, sequence length, and vocabulary size, with one vocabulary-sized score vector per token position.
- Weight tying saves memory and computation, but this chapter keeps separate layers because they train and perform better, a choice modern LLMs also make.