在自然语言处理领域,GPT(Generative Pre-trained Transformer)已经成为最受关注的模型架构之一。要真正掌握GPT的工作原理,我们需要从最基础的注意力机制开始,逐步构建完整的认知框架。
人类大脑在处理语言信息时,会本能地聚焦关键内容。比如看到句子"The pink elephant tried to get into the car but it was too []"时,我们会自动关注"elephant"和"get into the car"这两个关键信息,而忽略"pink"这样的修饰词。这种选择性关注的能力,正是现代语言模型中注意力机制(Attention)的思想来源。
注意力机制的核心功能是:
Andrej Karpathy开发的microgpt项目,用仅200行Python代码实现了GPT的核心功能,没有任何第三方依赖。这个极简实现包含六大核心组件:
这个精简实现移除了所有非必要组件,保留了GPT最本质的计算结构,是理解大型语言模型的绝佳起点。
microgpt使用的名字数据集来自GitHub公开仓库,包含32,033个英文名字。数据处理流程分为三个关键步骤:
python复制# 1. 数据下载(如果本地不存在)
if not os.path.exists('input.txt'):
import urllib.request
names_url = 'https://raw.githubusercontent.com/karpathy/makemore/988aa59/names.txt'
urllib.request.urlretrieve(names_url, 'input.txt')
# 2. 数据清洗
docs = [line.strip() for line in open('input.txt') if line.strip()]
# 3. 数据打乱
random.shuffle(docs)
清洗过程使用列表推导式高效处理:
line.strip()移除每行首尾的空白字符if line.strip()过滤掉空行计算机无法直接处理文本字符,需要将其转换为数字表示。microgpt采用基于字符的分词方案:
python复制uchars = sorted(set(''.join(docs))) # 数据集中所有唯一字符
BOS = len(uchars) # 序列开始/结束的特殊标记
vocab_size = len(uchars) + 1 # 词汇表大小(字母+BOS)
这种分词方式的特点:
提示:生产级模型通常使用更复杂的子词分词(如Byte Pair Encoding),但字符级分词在小型实验中足够且更易理解。
训练神经网络需要计算损失函数对每个参数的梯度。microgpt实现了一个简易的自动微分系统,核心是Value类:
python复制class Value:
__slots__ = ('data', 'grad', '_children', '_local_grads')
def __init__(self, data, children=(), local_grads=()):
self.data = data # 节点存储的数值
self.grad = 0 # 梯度初始化为0
self._children = children # 子节点
self._local_grads = local_grads # 局部梯度
关键属性说明:
data: 前向传播计算得到的标量值grad: 反向传播累积的梯度_children: 计算图中该节点的输入节点_local_grads: 当前节点对各子节点的偏导数以乘法运算为例:
python复制def __mul__(self, other):
other = other if isinstance(other, Value) else Value(other)
return Value(self.data * other.data,
(self, other),
(other.data, self.data))
这里:
反向传播按拓扑逆序遍历计算图:
python复制def backward(self):
# 构建拓扑排序
topo = []
visited = set()
def build_topo(v):
if v not in visited:
visited.add(v)
for child in v._children:
build_topo(child)
topo.append(v)
build_topo(self)
# 反向传播
self.grad = 1.0 # 损失函数对自身的导数为1
for v in reversed(topo):
for child, local_grad in zip(v._children, v._local_grads):
child.grad += local_grad * v.grad
关键点:
microgpt使用单层Transformer配置:
python复制n_layer = 1 # Transformer层数
n_embd = 16 # 嵌入维度
block_size = 16 # 上下文窗口大小
n_head = 4 # 注意力头数
head_dim = n_embd // n_head # 每个头的维度
参数矩阵使用小型随机值初始化:
python复制matrix = lambda nout, nin, std=0.08: [
[Value(random.gauss(0, std)) for _ in range(nin)]
for _ in range(nout)
]
state_dict = {
'wte': matrix(vocab_size, n_embd), # token嵌入
'wpe': matrix(block_size, n_embd), # 位置嵌入
'lm_head': matrix(vocab_size, n_embd) # 输出层
}
多头注意力是Transformer的核心:
python复制# 计算Q,K,V
q = linear(x, state_dict[f'layer{i}.attn_wq'])
k = linear(x, state_dict[f'layer{i}.attn_wk'])
v = linear(x, state_dict[f'layer{i}.attn_wv'])
# 缩放点积注意力
attn_scores = [[(q[i][h] @ k[j][h]) / (head_dim ** 0.5)
for j in range(pos_id+1)]
for i in range(pos_id+1)]
attn_probs = softmax(attn_scores)
# 加权求和
out = sum(attn_probs[i][j] * v[j][h]
for j in range(pos_id+1))
关键步骤:
前馈网络提供非线性变换能力:
python复制# 升维
h = linear(x, state_dict[f'layer{i}.mlp_fc1'])
# ReLU激活
h = [max(0, hi) for hi in h]
# 降维
out = linear(h, state_dict[f'layer{i}.mlp_fc2'])
典型配置:
训练过程采用Adam优化器:
python复制learning_rate, beta1, beta2 = 0.01, 0.85, 0.99
m = [0.0] * len(params) # 一阶矩估计
v = [0.0] * len(params) # 二阶矩估计
for step in range(num_steps):
# 1. 前向计算
loss = forward_pass()
# 2. 反向传播
loss.backward()
# 3. Adam更新
for i, p in enumerate(params):
m[i] = beta1 * m[i] + (1-beta1) * p.grad
v[i] = beta2 * v[i] + (1-beta2) * p.grad**2
m_hat = m[i] / (1 - beta1**(step+1))
v_hat = v[i] / (1 - beta2**(step+1))
p.data -= learning_rate * m_hat / (v_hat**0.5 + 1e-8)
p.grad = 0 # 清零梯度
训练技巧:
推理时从模型采样新名字:
python复制def generate():
tokens = [BOS] # 以BOS开始
while len(tokens) < block_size:
# 前向计算
logits = gpt(tokens[-1], len(tokens)-1)
# 温度采样
probs = softmax([l.data/temperature for l in logits])
next_token = random.choices(range(vocab_size), weights=probs)[0]
if next_token == BOS: # 遇到BOS停止
break
tokens.append(next_token)
return tokens
温度参数控制生成多样性:
梯度消失/爆炸:
过拟合:
模式坍塌:
实操建议:在扩展模型时,建议先在小数据集上验证模型能够过拟合(训练loss接近0),这可以确认模型有足够表达能力。
理解microgpt后,要构建生产级GPT需要考虑:
模型架构扩展:
工程优化:
训练数据扩展:
推理优化:
理解这个从简到繁的演进过程,才能真正掌握现代大语言模型的设计精髓。microgpt的价值在于剥离了所有工程复杂性,让我们可以专注于算法核心。