miniGPT¶
来自karpathy Lets build GPT_ from scratch, in code, spelled out课程,训练字符级gpt,部分步骤与bigram相同
1. 超参数定义¶
| Python | |
|---|---|
1 2 3 4 5 6 | |
字符级词表构建,构建训练、验证集、batch采用均与上节内容相同
2. 总体过程¶
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 | |
3. Token Embedding¶
| Python | |
|---|---|
1 | |
Token Embedding Table是一个可学习的查表矩阵
- 每一行:一个 token(字符)
- 每一列:该 token 在某个语义维度上的分量
在此代码中一共有65个token, 也就是vocab_size的长度, n_embd是语义维为384,每一个 token 被映射成一个 384 维向量
与Bigram embeddingde不同
Bigram 中的 embedding
nn.Embedding(vocab_size, vocab_size)
- 输入 token id
- 直接输出 下一个 token 的 logits
token i → [P(next=0), P(next=1), ..., P(next=64)]
👉 这是一个“查概率表”的模型 GPT 中的 embedding
nn.Embedding(vocab_size, n_embd)
-
token → 语义表示向量
-
不直接预测
-
后面还要经过 Attention + FFN
👉 这是“特征表示”,不是概率
4. Position Embedding¶
| Python | |
|---|---|
1 | |
| Text Only | |
|---|---|
1 | |
-
每一行 = 序列中的一个 位置
-
第 0 个 token、第 1 个 token、第 2 个 token……
为什么Position Embedding
Attention 本身不感知顺序
| Text Only | |
|---|---|
1 | |
| Python | |
|---|---|
1 | |
这一步让模型知道:
“这是第几个 token”
5. GPTLanguageModel模型结构¶
Head:单头自注意力(Self-Attention Head)
| Python | |
|---|---|
1 2 | |
表示 一个 attention head GPT 中通常是 多头注意力 = 多个 Head 并行
初始化函数
| Python | |
|---|---|
1 2 | |
head_size:
- 每个 head 的维度
- 通常:
head_size = n_embd // n_head
Key / Query / Value 线性层
| Python | |
|---|---|
1 2 3 | |
注意:
- GPT 是 self-attention → Q、K、V 都来自同一个
xbias=False是标准 Transformer 设置
下三角 mask(因果掩码)
| Python | |
|---|---|
1 2 3 4 | |
作用:防止“偷看未来”
举例(T=5):
| Text Only | |
|---|---|
1 2 3 4 5 | |
表示:
- 第 t 个 token 只能看到 ≤ t 的 token
- GPT 是 自回归语言模型(causal LM)
📌 register_buffer:
- 不参与训练
- 会自动
.to(device) - 会被保存进
state_dict
Dropout
| Python | |
|---|---|
1 | |
防止 attention 过拟合
forward 过程(重点)
| Python | |
|---|---|
1 2 | |
- B:batch size
- T:序列长度(time steps)
- C:embedding dim
计算 Q、K
| Python | |
|---|---|
1 2 | |
Attention 权重计算(核心公式)
| Python | |
|---|---|
1 | |
维度变化:
| Text Only | |
|---|---|
1 | |
每个 token 对 所有 token 的相似度
Causal Mask
| Python | |
|---|---|
1 2 3 4 | |
- 把未来位置设为
-inf - softmax 后概率为 0
Softmax
| Python | |
|---|---|
1 | |
得到:
| Text Only | |
|---|---|
1 | |
Dropout
| Python | |
|---|---|
1 | |
| Python | |
|---|---|
1 2 | |
每个 token = 所有 token 的 value 加权和
MultiHeadAttention:多头注意力
初始化
| Python | |
|---|---|
1 2 3 | |
- 并行多个 Head
- 每个 head 关注不同模式
输出映射
| Python | |
|---|---|
1 | |
把拼接后的结果映射回 n_embd
forward
| Python | |
|---|---|
1 | |
维度:
| Text Only | |
|---|---|
1 | |
| Python | |
|---|---|
1 | |
单头注意力(Single-Head Attention)
给定输入 \((X \in \mathbb{R}^{L \times d_{\text{model}}})\) :
然后计算 缩放点积注意力:
输出维度仍然是:
多头注意力(Multi-Head Attention)
计算方式
假设有 \(h\) 个头(head):
(1)线性投影(每个头一套参数)
通常: $$ d_k = d_v = \frac{d_{\text{model}}}{h} $$
(2)每个头独立算注意力
(3)拼接 + 线性变换
输出维度仍是: $$ L \times d_{\text{model}} $$
FeedForward`:逐 token 的 MLP
注意:不做 token 间通信 只是对每个 token 独立做非线性变换
结构
| Python | |
|---|---|
1 2 3 | |
这是 GPT 经典结构:
- 升维 → 非线性 → 降维
- 增强表达能力
forward
| Python | |
|---|---|
1 | |
Block`:完整 Transformer Block
Transformer = Attention(通信) + FFN(计算)
初始化
| Python | |
|---|---|
1 2 3 | |
| Python | |
|---|---|
1 2 | |
⚠️ GPT 使用 Pre-LN(比 Post-LN 稳定)
forward(重点)
| Python | |
|---|---|
1 | |
- LayerNorm
- Self-Attention
- Residual(残差连接)
| Python | |
|---|---|
1 | |
- LayerNorm
- FeedForward
- Residual
整体数据流
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 | |
5.1 Token Embedding(字符 → 向量)¶
| Python | |
|---|---|
1 | |
作用
- 把 离散的 token id 映射为 连续向量
- 每个 token 对应一个
n_embd维向量
参数形状
| Text Only | |
|---|---|
1 | |
5.2 Position Embedding(位置 → 向量)¶
| Python | |
|---|---|
1 | |
作用
- 给 Transformer 注入 序列顺序信息
- 第 0 个 token、第 1 个 token……都有独立表示
参数形状
| Text Only | |
|---|---|
1 | |
5.3 Transformer Blocks¶
| Python | |
|---|---|
1 2 3 | |
- 堆叠
n_layer个 Transformer Block -
每个 Block 包含:
-
Multi-Head Self-Attention
- FeedForward
- Residual + LayerNorm
5.4 最后的 LayerNorm¶
| Python | |
|---|---|
1 | |
作用
- 在输出 logits 前稳定特征分布
- GPT 的标准做法(Pre-LN 架构)
5.5 Language Model Head(向词表投影)¶
| Python | |
|---|---|
1 | |
作用
- 把隐藏向量映射成 下一个 token 的 logits
- 每个位置都是一个
vocab_size分类问题
输出形状
| Text Only | |
|---|---|
1 | |
5.6️ 权重初始化¶
| Python | |
|---|---|
1 | |
- 对模型中所有子模块递归调用
_init_weights - 使用 GPT 常用初始化方式
Linear 层初始化
| Python | |
|---|---|
1 2 | |
- 权重:高斯分布
- 标准差
0.02(GPT 论文经验值)
| Python | |
|---|---|
1 2 | |
- bias 全 0
Embedding 初始化
| Python | |
|---|---|
1 2 | |
- token embedding 和 position embedding 都用同样规则
5.7 Transformer Blocks¶
| Python | |
|---|---|
1 | |
- 多层 Attention + FFN
- 融合历史上下文信息
形状保持不变
| Text Only | |
|---|---|
1 | |
5.8 generate:自回归文本生成¶
| Python | |
|---|---|
1 | |
idx: 当前上下文(B, T)max_new_tokens: 要生成多少 token
循环生成
| Python | |
|---|---|
1 | |
截断上下文
| Python | |
|---|---|
1 | |
- 只保留最近
block_size个 token - 防止位置 embedding 越界
前向预测
| Python | |
|---|---|
1 | |
| Python | |
|---|---|
1 | |
形状
| Text Only | |
|---|---|
1 | |
用当前上下文预测下一个 token
Softmax → 概率
| Python | |
|---|---|
1 | |
采样下一个 token
| Python | |
|---|---|
1 | |
输出
| Text Only | |
|---|---|
1 | |
| Python | |
|---|---|
1 | |