Appearance
第8章 · TinyGPT 预训练、恢复与生成
先修:第4章的 CE、第6章的优化器、第7章的 Transformer Block。
本章目标
- 组装 token/position embedding、Transformer blocks、LM head、batch loader 和训练循环。
- 先过拟合一个 batch,再在固定微型语料上训练、采样、保存和恢复。
- 能解释 learning rate、batch、context、depth、width、梯度裁剪和 checkpoint 的作用;分布式训练只做口述。
公式与 shape
语言模型训练目标:
每次更新还要满足梯度裁剪上限 g ← g · min(1, c/||g||),checkpoint 至少保存模型、优化器、step、配置/数据/tokenizer hash。
| 对象 | shape | 说明 |
|---|---|---|
| input ids | (B, T) | 与 shifted targets 相差一个位置 |
| token/position embeddings | (B, T, D) | 位置索引不可越过 block size |
| logits | (B, T, V) | 与 targets 对齐后算 CE |
| optimizer state | 与可训练参数相关 | resume 不能只加载 weights |
| checkpoint metadata | mapping | 保存 step、config/data hash 和相对路径 |
数学桥接:第2章 → 第8章
第4章的 CE loss 是单 token 版本:
第2章 §7 的梯度裁剪 g ← g · min(1, c/||g||) 是本章训练稳定性的第一道防线。当梯度范数超过阈值
Checkpoint 保存 optimizer state 是因为 AdamW 的 momentum_update 的推广)需要跨 resume 保持连续——只加载 weights 不加载动量,恢复后的前几步梯度估计会偏。
前端类比:gradient clipping = CSS 的 max-height: 100vh; overflow: hidden——内容超出视口时不是删掉,而是等比缩放让整体可见。checkpoint = React 的 useReducer + localStorage——把整个 state(model + optimizer + step)序列化,刷新后精确恢复。
交互观察
交互:Softmax + Temperature
把 logits 看成「未归一化分数」。Temperature 越高分布越平,越低越尖。
LOCAL TRAINING TRACE · NO NETWORK
把一次 TinyGPT 更新拆成可回放事件
batch取固定 seed 的 shifted input/target window
B=4 · T=16当前是教学事件图,不执行 Python、不读取文件,也不代表云训练或学习者掌握。
把这里的 logits 视为生成器最后一步的输出,比较温度与 top-k 的职责;真正的 TinyGPT 生成还必须来自受控训练、checkpoint 和 token-level 对拍。
从零实践
用固定 byte 数据集做 one-batch overfit,记录初始 loss、最终 loss 和参数范数变化。
加入周期 checkpoint、恢复和 deterministic smoke;恢复后下一步的 loss/step 应与不中断轨迹一致到冻结容差。
运行当前必修训练测试:
bashpython -m pip install -r requirements.txt PYTHONPATH=python python -m pytest \ python/tests/test_trainable_tinygpt.py \ python/tests/test_checkpoint_recovery.py -q也可以用同一份脱敏 JSON 配置运行可复用的本地 CLI。它会执行真实
backward → AdamW → checkpoint,并在输出目录写入evidence.json;默认 使用合成 byte 语料,不读取凭据或访问网络:bashPYTHONPATH=python python -m llm_train.cli \ smoke --config configs/tiny-cpu.json --output-dir .artifacts/llm_train PYTHONPATH=python python -m llm_train.cli \ inspect-checkpoint .artifacts/llm_train/tinygpt.ptCLI 输出的
status=ok只表示这次本地训练和 checkpoint 结构通过;它不 代表云端资格、云服务部署或学习者 clean-room 掌握已经通过。
当前 python/llm_train/ 和上述测试已在 checkout 中存在,PyTorch 是规范安装的一部分。正式证据必须记录真实 backward/update、loss 下降、无 NaN、checkpoint 恢复和配置 hash;依赖缺失时应阻塞安装,而不是跳过训练 gate。
故障注入与预期信号
| 注入 | 预期失败信号 | 修复后证据 |
|---|---|---|
| 只执行 forward 不调用 optimizer | 参数差异为零,loss 不下降 | 参数更新范数大于零且 loss 下降 |
| target 未 shift | 模型学会复制当前位置 | shifted batch contract 失败并修复 |
| 梯度裁剪或 NaN gate 缺失 | 训练出现非有限值仍退出 0 | NaN 使命令失败并保存可诊断结果 |
论文与延伸
- Scaling Laws for Neural Language Models(Kaplan 等,2020)
- Training Compute-Optimal Large Language Models(Hoffmann 等,2022)
- 选读:GPT-2 的 Language Models are Unsupervised Multitask Learners。
前端/Agent 迁移
训练循环是带 telemetry 的事件循环:batch → forward → loss → backward → update → checkpoint。Agent 恢复同样不能只保存最终输出;要保存可重放的输入、状态版本、步数和副作用前后的 checkpoint。DP/TP/PP/ZeRO 只在本章用状态图和通信代价口述,不启动大规模训练。
口述与自测(不看资料,5–10 分钟)
- 从
(B, T)的 input/target 写出 teacher forcing 的 shift 与(B, T, V)logits 的 CE 对齐方式;解释 one-batch overfit 为什么是训练链路的必要诊断而不是泛化结论。 - 对比 data parallel、tensor parallel、pipeline parallel 与 ZeRO:各自主要分摊什么、引入什么通信/显存代价;再说明 Scaling Laws 与 Chinchilla 不能由一次 tiny run 外推。
- 用第2章的
perplexity(1.0) = 2.0解释 TinyGPT 的 PP=2 意味着什么(平均每次在 2 个候选里猜);PP 从 10 降到 5 代表模型改进了多少。 - 说明 gradient clipping(第2章 §7)和 learning rate schedule 分别是解决什么问题的——一个是梯度爆炸的"紧急刹车",一个是收敛精细调整的"巡航控制"。
实验与参考
动手实验
把 TinyGPT 从零训练跑通,并把检查点恢复做成可验证证据:训练损失单调下降、参数更新范数为正、按相同 config_hash 恢复后指标连续、CLI 输出单行 JSON 可被自动化消费。
环境准备
bash
cd <仓库根>
export PYTHONPATH="$PWD/python"命令与预期输出
smoke 与 inspect-checkpoint 已在「从零实践」跑过,这里补上 examples 独有的 train 与 resume 子命令:
bash
# 用仓库内置 CPU 配置训练并落盘
python -m llm_train.cli train \
--config configs/tiny-cpu.json \
--output-dir .artifacts/llm_train
# 从最近一次 checkpoint 继续训练
python -m llm_train.cli resume \
--resume-from .artifacts/llm_train/checkpoint.pt
# 可选参数:--text、--validation-fraction、--max-secondstext
{"command":"train","status":"ok","steps":120,"initial_loss":4.51,
"final_loss":3.12,"initial_validation_loss":4.48,
"final_validation_loss":3.18,"parameter_update_norm":1.74,
"checkpoint":".artifacts/llm_train/checkpoint.pt",
"evidence":"train-20260810-101530","config_hash":"a91f...",
"data_hash":"b3c2...","tokenizer_hash":"d401..."}
判定信号:
final_loss < initial_loss 且 val loss 同步下降
parameter_update_norm > 0(说明确实学到了东西)
resume 前后 config_hash 一致,loss 曲线无跳变概念图
图:第8章 TinyGPT 训练循环与 checkpoint 管理 — 第2章的 MLP 前向传播 + 交叉熵 + 梯度下降,加上第3–7章的 autograd、BPE、Transformer,在本章首次组装为"配置 → 训练 → checkpoint → 恢复"的完整生产闭环。后续第9章用 KV Cache 优化推理,第10章把 checkpoint 作为 SFT/LoRA 的起点,第13章把训练好的模型接入 Agent harness,第19章把 config_hash → checkpoint → eval → report 串成可审计 artifact chain。
故障注入清单
| 故障 | 表现 | 修复 |
|---|---|---|
| 忘记 optimizer zero_grad | 梯度累积导致 loss 抖动、指标不收敛 | 每一步 optimizer.step 后立即 zero_grad |
| 训练集与验证集切分泄漏 | val loss 异常低、看似过拟合其实数据穿帮 | 严格按 hash 切分并固化随机状态 |
| 恢复时只 load 权重不 load optimizer state | 恢复后 loss 跳变、Adam 动量丢失 | 同时 load 模型和 optimizer 状态 |
| config_hash 与 checkpoint 不一致 | 恢复到错误配置、shape 对不上 | 恢复前先比对 hash、不一致则拒绝 resume |
资源 / 成本 / 隐私
规范路径要求 PyTorch,优先 Apple Silicon MPS/CPU;本地训练预计 gross cost 为 0,不需要 Google Cloud。数据、checkpoint metadata 和 trace 只使用合成 fixture;云训练另走第18章的实时资格与一次性授权门。
Evidence
仓库当前机器证据(只读快照)
evidence/module-manifest-v1.json 中 08.evidence 指向当前文件:evidence/08-runtime-v1.json。这是当前 checkout 的脱敏机器运行记录,只覆盖该 JSON 记录的命令、指标、产物和已知失败;它不是学习者提交,也不能推出学习者已完成本章。其 Python 3.11 运行范围、当前工作树边界和云端未核验状态以 JSON 的 known_failures 为准。
学习者提交模板(待填写,不是当前机器证据)
复制下面模板并填写自己的真实运行结果。所有 <...> 都是未填写状态;actual 和 artifacts 尤其不能被当作已运行或已通过。artifacts 必须替换为本次提交中真实存在的仓库相对路径。
yaml
schema: learn-llm.evidence.v1
module: 08-tinygpt
commit: <learner-commit-sha>
verified_at: <iso-date>
environment: <sanitized-python-device-backend>
seed: 6
commands:
- python -m pip install -r requirements.txt
- PYTHONPATH=python python -m pytest python/tests/test_trainable_tinygpt.py python/tests/test_checkpoint_recovery.py -q
metrics:
- name: parameter_update_norm
expected: '>0'
actual: <recorded-value>
- name: final_loss_minus_initial_loss
expected: '<0'
actual: <recorded-value>
- name: checkpoint_resume_max_error
expected: <versioned-tolerance>
actual: <recorded-value>
artifacts:
- <learner-repo-relative-artifact-path>
cost:
gross_usd: 0
credit_usd: 0
licenses:
- source: <source>
version: <version>
license: <license>
attribution: <attribution>
redistribution: <redistribution>
known_failures:
- <sanitized-failure-or-none>缺依赖、跳过测试、无参数更新或无恢复对拍时,本章保持 gate。