Simple GPT

image.png

1. Token Embedding

self.token_embedding = nn.Embedding(vocab_size, n_embd)

它把每个 token ID 转换成 n_embd 维向量:

125 → [0.1, -0.3, ..., 0.8]
731 → [0.4,  0.2, ..., 0.1]
402 → [0.7, -0.1, ..., 0.5]

如果:
batch_size = B
sequence_length = T
n_embd = C

则输出形状是:
[ (B,T,C) ]

B = batch size:这一批里有多少条 sequence
T = sequence length:每条 sequence 里有多少个 token
C = n_embd:每个 token 用多少维向量表示

比如:
batch_size = 4
sequence_length = 8
n_embd = 32

输入的tokens 可能是:
[
  [12, 45, 81,  3, 19, 27, 31,  9],   # sequence 1
  [ 8, 22, 14, 65, 72, 11,  4, 20],   # sequence 2
  [17, 33, 91, 26,  5, 48, 50, 10],   # sequence 3
  [21, 13, 15, 99, 40, 41, 42, 43]    # sequence 4
]

2. Position Embedding

self.position_embedding = nn.Embedding(max_seq_len, n_embd)

Token embedding 只表示“这是哪个 token”,不知道它出现在什么位置。

例如:
cat sat
sat cat

如果没有位置信息,模型不容易区分顺序。
所以给每个位置也创建一个向量:

位置 0 → position vector 0
位置 1 → position vector 1
位置 2 → position vector 2

然后相加:
hidden = token_embedding + position_embedding

因此,每个 token 的初始表示同时包含:

这个 token 是什么 + 这个 token 在哪里

3. Transformer Blocks

接下来,hidden vectors 会依次经过多个 Transformer blocks:

Block 1 的输出
    ↓
作为 Block 2 的输入
    ↓
Block 2 的输出
    ↓
作为 Block 3 的输入

如果:
n_layer = 4

就会依次经过 4 个 block。
每个 block 的输入和输出形状都保持:
[ (B,T,n_embd) ]

一个 Transformer Block 里有什么?

一个 GPT 风格的 Transformer block 主要有两个部分:
1. Multi-Head Self-Attention
2. Feed-Forward Network

并且每个部分周围都有:
- LayerNorm
- Residual connection
使用 norm_first=True 时,一个 block 的完整流程是:

image.png

可以写成两个公式:

image.png

y 是当前 block 的最终输出。

第一部分:LayerNorm

 x
 ↓
LayerNorm

LayerNorm 会对每个 token 的 hidden vector 做标准化。

假设一个 token 是:
[10, 100, -20, 5]

不同维度数值范围差距很大。LayerNorm 会把它们调整到更稳定的范围。

它不会改变形状:
(B, T, n_embd)
→
(B, T, n_embd)

作用主要是让训练更加稳定。

第二部分:Multi-Head Self-Attention

Self-Attention 让每个 token 从其他 token 收集信息。

内部流程是:

输入 x
  ↓
生成 Query、Key、Value
  ↓
分成多个 attention head
  ↓
计算 QKᵀ
  ↓
除以 sqrt(head_dim)
  ↓
应用 causal mask
  ↓
Softmax
  ↓
对 Value 加权求和
  ↓
拼接所有 head
  ↓
经过输出投影 W_O

2.1 生成 Q、K、V
每个 token 的 hidden vector 分别经过三个线性层:

		Q=xW_Q
		K=xW_K
		V=xW_V

它们分别表示:
- Query:当前 token 想找什么信息;
- Key:当前 token 可以通过什么特征被找到;
- Value:当前 token 实际提供什么信息。

2.2 分成多个 head
假设:
n_embd = 12
n_head = 3

那么:
head_dim=12/3=4

Q、K、V 分别被整理成:
3 个 head
每个 head 4 维

每个 head 都可以学习不同的 attention 模式。

2.3 计算 attention 分数
每个 head 使用:

$$ \frac{QK^T}{\sqrt{head\_dim}} $$