外观
训练:把正确梯度变成可复现实验
训练语言模型不只是循环调用优化器。你需要明确监督目标、数据抽样、归一化、更新规则和验证协议。这里逐步拆解 labs/llm/train.py,让每个日志数字都有清楚的含义;在此基础上再扩大模型和语料,才知道一次失败来自哪里。
输入与目标严格错开一位
从 token 流取长度 [a,b,c,d],目标是 [b,c,d,e]。输入的每个位置都获得一个预测任务,因果 mask 保证第一个位置只能利用 a 预测 b,第二个位置利用 a,b 预测 c。本地 make_batch 返回 [B,T] 的两张整数表,测试用递增序列验证 y == x + 1,避免只检查形状。
跨文档拼接需要定义边界。真实训练通常插入文档结束标记,并决定是否屏蔽跨文档注意力。本地原创短句按换行连接,没有独立 EOS;模型学习的是这段连续短句流,不应解释为通用文档 packing 实现。训练和验证先按行分开,再分别编码,不从同一个随机滑窗池中划分,否则相邻窗口高度重叠,会把几乎相同的文本泄漏到两边。
loss 与 batch 的尺度
训练目标为
perplexity 是
AdamW 在做什么
对梯度
初始均为零,因此用
把
裁剪与学习率
全局梯度范数
学习率先线性 warmup,再 cosine decay 到最大值的 10%。warmup 不会修复错误梯度,但能降低优化器早期状态不稳定带来的冲击。学习率过大可能让 loss 爆炸,过小则可能看似稳定但几乎没有学习。诊断顺序应是:确认数据和梯度正确;小批次能否过拟合;再调学习率、初始化和批大小。
flowchart LR A[固定 seed 抽样窗口] --> B[前向与平均 NLL] B --> C[反向传播] C --> D[记录范数并裁剪] D --> E[调学习率 AdamW] E --> A E --> F[固定验证窗口 记录日志]
查看流程图文本
flowchart LR A[固定 seed 抽样窗口] --> B[前向与平均 NLL] B --> C[反向传播] C --> D[记录范数并裁剪] D --> E[调学习率 AdamW] E --> A E --> F[固定验证窗口 记录日志]
checkpoint 应包含什么
推理最少需要参数、模型配置、tokenizer;精确恢复训练还需要优化器的一二阶矩、步数、随机数状态、数据游标、学习率调度状态。当前 .npz 保存的是推理 checkpoint,不承诺从中恢复完全一致的训练轨迹。文件以 allow_pickle=False 读取,元数据使用 JSON;这也让配置可以直接检查。
本地 metrics.json 记录语料 SHA-256、Python/NumPy 版本、seed、参数量、训练/验证规模、定期 NLL 和生成样本。seed 固定能提高复现性,但换 BLAS、硬件、线程数仍可能产生浮点差异。测试应该允许小数值误差,而非要求跨平台日志逐字节一致。
一次真实小实验如何解释
本仓库实测默认字符模型在 seed 7、300 步时,固定训练窗口 NLL 从约 3.899 降至 0.733,验证窗口从约 3.861 降至 1.266。它说明训练闭环有效;末期验证没有随训练同步改善,提示小语料上的泛化收益开始变弱。这里的指标只是 32 个固定抽样验证窗口,不是整个验证集的无偏精确评分,更不代表真实语言建模基准。完整记录见 实验手册。
自测
batch 翻倍,loss 仍是平均值,梯度为什么还可能变化?
平均消除了直接的倍数关系,但样本组成改变会降低或改变梯度估计噪声,新增窗口也会改变平均方向。若使用 dropout 或不同 packing,差异更多。只有将完全相同的一批复制一次,并保持其它行为一致时,平均梯度才应基本不变。
train loss 下降、validation loss 上升,应该首先增加模型宽度吗?
先检查数据泄漏、验证协议和训练步数,再考虑过拟合与数据分布偏移。更大模型可能加重问题;早停、更多高质量训练数据、合适正则化与匹配的验证集通常更直接。不能凭单个 noisy batch 判定趋势。
来源:AdamW 论文、官方 A1 2025。下一章:生成与推理。