训练的本质:通过数亿次的微调,在参数的高维荒野中寻找最优解
训练的闭环:模型是如何变聪明的
在前面的项目中,我们构建了各种静态部件。项目 07 的任务是让这些部件动起来。我们将实现一个名为 Mini-former 的模型训练系统。训练的过程本质上是一个反馈循环:模型预测 -> 计算误差(Loss) -> 计算如何调整参数(Gradients) -> 更新参数(Optimizer)。
第一阶段:构建训练循环(The Training Loop)
一个标准的训练循环需要严密的逻辑控制:
- 数据分批(Batching):模型不可能一次处理整本书,我们需要将其切分为
(Batch Size, Sequence Length)的张量。 - 前向传播(Forward Pass):输入 $X$,得到模型预测的 Logits。
- 计算损失(Loss Calculation):使用交叉熵损失(Cross Entropy Loss),衡量模型预测概率与真实 Token 之间的距离。
- 反向传播(Backward Pass):PyTorch 会自动根据 Loss 计算每一个权重的梯度。
- 权重更新(Optimization Step):使用 AdamW 优化器,根据梯度微调权重。
第二阶段:学习率调度(Learning Rate Scheduling)
学习率是训练中最重要的超参数。
- Warmup(预热):在训练开始的前几百步,模型权重是随机的,梯度非常大。我们需要缓慢增加学习率,防止模型在第一步就“跑偏”。
- Decay(衰减):随着训练接近尾声,我们需要减小学习率,让模型在最优解附近细微挪动,避免冲过头。 最常用的策略是余弦退火(Cosine Decay with Warmup)。
第三阶段:过拟合与验证集(Evaluation)
模型训练最怕的是“死记硬背”。如果模型在训练集上 Loss 极低,但在新文本上表现极差,这就是过拟合。 因此,我们必须定期执行 Validation Step:
- 切换到
model.eval()模式。 - 停用 Dropout 和梯度计算。
- 在未见过的验证数据上计算 Loss。 如果验证集的 Loss 开始上升,即便训练集 Loss 仍在下降,也必须停止训练。
关键工程代码片段
# 一个典型的训练步骤逻辑
optimizer.zero_grad(set_to_none=True)
logits, loss = model(x, y)
loss.backward()
# 梯度裁剪:防止梯度爆炸
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
lr_scheduler.step()
观察指标与可视化
在训练过程中,你需要实时监控以下图表:
- Loss Curve:理想曲线应该呈现平滑下降,最后趋于平缓。
- Perplexity(困惑度):Loss 的指数形式,$e^{loss}$。它代表模型在预测下一个词时,平均在多少个候选词中纠结。
- Gradient Norm:如果这个值突然飙升,通常意味着训练已经崩溃。
- Generate Samples:每隔 500 步,让模型生成一段话。你会亲眼看到它从完全的随机乱码,进化到能拼出单词,再到能写出符合语法的短句。
总结
训练不是魔法,而是极致的工程。每一个细节(Batch 大小、学习率的形状、梯度的裁剪)都会直接影响最终模型的质量。当你第一次看到模型能够续写出你输入的句子时,你将真正理解参数中蕴含的统计力量。
版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。
(采用 CC BY-NC-SA 4.0 许可协议进行授权)
本文标题:项目 07:Mini-former 训练实战:从随机扰动到文本预测
本文链接:https://www.sshipanoo.com/blog/ai/llm-roadmap/lab-07-training/
本文最后一次更新为 天前,文章中的某些内容可能已过时!