Transformer Architecture: From Token Embeddings to the Training Loop
Contents
Transformer appears to be made up of many components, but a GPT-style forward path can be summarized as:
|
|
This article starts from a simple GPT implementation and explains the role and tensor shape of each step along the data flow. The complete source code is placed at the end of the article. After reading the previous principles, you can compare and understand it with the code.
1. Token Embedding
|
|
Token embedding converts each token ID into a n_embd dimensional vector:
|
|
Assume the batch size is $B$, the sequence length is $T$, the embedding dimension is $C$, and the output shape is $(B,T,C)$:
- $B$: How many sequences are there in a batch;
- $T$: How many tokens are there in each sequence;
- $C$: The vector dimension of each token, namely
n_embd.
For example, when batch_size = 4, sequence_length = 8, n_embd = 32, the input may be:
|
|
After embedding, the shape changes from $(4,8)$ to $(4,8,32)$.
2. Position Embedding
|
|
Token embedding only expresses “which token is this” and does not know where it appears. Without location information, it is difficult for the model to distinguish between cat sat and sat cat.
Therefore, we also assign a vector to each position and add it to the token embedding:
|
|
In this way, the initial representation of each token contains two types of information at the same time: what it is, and where it is.
3. Transformer Blocks
The hidden vectors obtained by Embedding will pass through multiple Transformer blocks in sequence. If n_layer = 4, the output of the previous block is the input of the next block, passing through four layers in total.
The tensor shape of each layer usually remains $(B,T,n_embd)$, what changes is the value in the vector and the information it expresses.
What’s in a Transformer Block?
GPT style Transformer block mainly includes:
- Multi-Head Self-Attention;
- Feed-Forward Network(FFN)。
Each part is also paired with LayerNorm and residual connection. When using the pre-norm structure of norm_first=True, it can be written as:
$$ x’ = x + \operatorname{Attention}(\operatorname{LayerNorm}(x)) $$
$$ y = x’ + \operatorname{FFN}(\operatorname{LayerNorm}(x’)) $$
3.1 LayerNorm
LayerNorm will normalize the hidden vector of each token. For example, a token is represented as [10, 100, -20, 5], and the numerical ranges of different dimensions vary greatly; LayerNorm will adjust them to a more stable range.
LayerNorm does not change shape:
$$ (B,T,n_embd) \rightarrow (B,T,n_embd) $$
Its main function is to improve training stability.
3.2 Multi-Head Self-Attention
Self-Attention lets each token collect information from other tokens:
|
|
Generate Q, K, V
The hidden vector of each token undergoes three linear transformations:
$$ Q=xW_Q,\qquad K=xW_K,\qquad V=xW_V $$
- Query: What information is the current token looking for;
- Key: What features can the current token be found through;
- Value: the information actually provided by the current token.
Split multiple Heads
If n_embd = 12, n_head = 3, then the dimensions of each head are:
$$ head_dim=\frac{12}{3}=4 $$
Q, K, and V will be split into three heads, and each head can learn different attention modes.
Calculate Attention Score
Each head uses scaled dot-product attention:
$$ \operatorname{Attention}(Q,K,V)=\operatorname{softmax}\left(\frac{QK^T}{\sqrt{head_dim}}\right)V $$
For example, when processing sat in The cat sat, a head might give:
|
|
This means that the head is more concerned about cat at this time.
Causal Mask
The language model cannot peek into the future when predicting the next token, so a causal mask is used:
|
|
The first position can only see itself; the second position can see the first and second positions; and so on.
Weighted sum of Value
For the current position $i$, the output of a head is:
$$ h_i^{(1)}=\alpha_{i,1}^{(1)}v_1^{(1)}+\alpha_{i,2}^{(1)}v_2^{(1)}+\cdots+\alpha_{i,i}^{(1)}v_i^{(1)} $$
That is, the information provided by each visible location is weighted and summed according to the current location’s attention to it.
Splice all Heads
Each head gets a head_dim dimensional vector. Put all heads together:
$$ h_i=\operatorname{Concat}(h_i^{(1)},h_i^{(2)},\ldots,h_i^{(H)}) $$
Because n_head × head_dim = n_embd, the concatenated vector is still n_embd dimension. Then go through the output projection:
$$ a_i=h_iW_O $$
This linear layer remixes information from different heads, and the shape remains n_embd → n_embd.
3.3 The first Residual Connection
The attention output is added to the original input of the block:
$$ x’=x+\operatorname{Attention}(\operatorname{LayerNorm}(x)) $$
That is, the original token information is retained, while new information collected from the context is added. Residual connections also make deep networks easier to train and allow gradients to propagate forward more smoothly.
3.4 Feed-Forward Network
Attention is responsible for allowing different tokens to exchange information, while FFN independently processes each token’s own hidden vector:
|
|
The formula is:
$$ \operatorname{FFN}(x)=W_2\operatorname{GELU}(W_1x) $$
If n_embd = 128, dim_feedforward = 512, the dimension change is 128 → 512 → 128. Different positions will pass through the same FFN independently, and FFN itself will not transfer information between positions.
3.5 Second Residual Connection
The output of FFN is also added back to the input:
$$ y=x’+\operatorname{FFN}(\operatorname{LayerNorm}(x’)) $$
This is the final output of a Transformer block. After multiple blocks are stacked, each token will obtain a richer and more abstract context representation layer by layer.
4. Final LayerNorm
After all Transformer blocks are completed, perform LayerNorm again:
|
|
It makes the final hidden representation more stable, the shape is still $(B,T,n_embd)$.
5. LM Head
Finally, project the hidden vector to the entire vocabulary:
|
|
The dimensions change from n_embd to vocab_size, so the shape of the logits is $(B,T,vocab_size)$. For example:
|
|
The output shape is $(4,128,8192)$, that is, each position will give a score to 8,192 candidate tokens.
6. Cross-Entropy Loss
During training, compare logits with the correct next token:
|
|
For example:
|
|
The model learns to predict cat when it sees The, sat when it sees The cat, and then passes:
|
|
Calculate gradients and update parameters.
7. Let’s look at the matrix meaning of Multi-Head Attention again
Assume that the hidden vectors of the three tokens are $x_1,x_2,x_3$ respectively, which are obtained through the shared projection matrix:
$$ Q_i=x_iW_Q,\qquad K_i=x_iW_K $$
Here $Q_i$ and $K_i$ are both vectors. If head_dim = 4:
|
|
Stack the vectors at each position row by row. If $T=3,d=4$, there will be $Q,K\in\mathbb{R}^{3\times4}$. therefore:
$$
QK^T=
\begin{bmatrix}
Q_1K_1^T & Q_1K_2^T & Q_1K_3^T
Q_2K_1^T & Q_2K_2^T & Q_2K_3^T
Q_3K_1^T & Q_3K_2^T & Q_3K_3^T
\end{bmatrix}
$$
The $i$ row of the matrix represents the degree of attention that the token at position $i$ pays to all tokens. For example, the second row indicates how “interested” position 2 is in position 1, position 2, and position 3, respectively. Under causal mask, the scores for future positions are masked before softmax.
8. Complete minimal implementation
Here’s an easy-to-understand example of a single-device GPT training. It omits performance optimization and distributed training, retaining only the most basic data flow.
|
|
Run the example:
|
|
Looking back at Transformer from this minimal implementation, the core is three things: embedding establishes the initial representation, attention exchanges information between tokens, FFN performs non-linear transformation on the representation of each token; after multi-layer stacking, LM Head converts the representation into the prediction score of the next token.
Author zhengxz
LastMod 2026-09-14