一条完整的学习之旅:从最朴素的 bigram 基线起步,经自注意力搭出最小可训练的
nanoGPT,再扩展到 124M 规模与 SFT + LoRA 微调。
每一章都配交互式可视化 —— 先看懂直觉,再读代码。
最朴素的语言模型。一口气理解 tokenizer / batch / forward /
cross_entropy / 训练循环这条主线。
给模型装上"往回看"的能力。从"对过去做平均"出发,一步步升级成
由内容算权重的自注意力,打破 bigram 的 2.49 天花板。
四块新积木拼出 GPT:多头(同时看多种关系)、FFN(逐位置思考)、残差 + LayerNorm(让深网络训得动),再摞成多层。val loss 从 2.41 掉到 ~1.57。
第 1–3 章的零件拼成整台 tiny GPT(≈0.8M)。两段全自动动画:① 装机(训练把所有权重调到位)+ ② 跑起来(forward 算出 logits → decode 采样,预设开头自回归生成)。跑起来里点开 4×Block 还能掀盖看注意力热力图 + FFN 内部。
对应 phase1-124m/05_sample.py:把推理"从打分到吐字"拆成五步亲手拨——base 只续写不答题、temperature 捏尖/摊平分布、top_k 砍掉长尾、自回归逐 token 滚动、KV-cache 并排省掉重复计算(实测约 2.5–3.1×)。
对应 phase1-124m/04_gpt2_124m.py:把 GPT-2 124M 预训练拆成五步亲手拨——配置从字符级玩具跃迁到 12/12/768、FineWeb-Edu 切 shard 顺序喂、梯度累积攒满 524288 token 再走一步、warmup + 余弦学习率实时画曲线、用两个真实端点(300M→3.65 / 10B→3.02)看数据量 33× 的收敛对照。
动手写代码前先对齐全景与术语:参数量 vs 数据量、任务 vs 手段(SFT/DPO × 全量/LoRA)、SFT 改了哪三处(数据/模板/loss mask)、偏好对齐里 RLHF 与 DPO 的关系。
拿 Phase 1 的 124M base 做监督微调:对话模板 + EOS、loss mask(只对回答算 loss)、训练循环。配套代码 06_sft.py,内含训练前后真实采样对比。
换手段不换任务:同一件 SFT,冻住 124M 底座,只在每层旁挂低秩旁路 B·A,只训 ~0.94% 参数、存 4.7MB adapter。配套代码 07_lora.py,内含真实采样与 loss 曲线。
换任务:从"会答"到"答得合人意"。接在 SFT 之后,用偏好对(chosen/rejected)+ 冻结参考模型做 DPO——不训奖励模型、不走 RL。配套代码 08_dpo.py,真实曲线 loss↓ / margin↑ / 准确率 0→100%;加 --lora 可切 LoRA 手段。