学习地图
这一页解决一个问题:面对 nanochat 的 7000 多行代码,先看什么,后看什么,什么时候可以跳过。
你不需要第一次就理解全部。教程把 nanochat 拆成五个阶段,每个阶段只回答一个核心问题。
先看全景
nanochat 的目标很直接:用一套尽量短、可以自己改的代码,从零训练一个能和用户对话的语言模型。
它覆盖的流程是:
text
原始文本
→ 分词器把文本变成词元
→ 训练数据把词元排成固定长度的样本
→ 预训练得到 base 模型
→ 监督微调得到会对话的 SFT 模型
→ 可选:强化学习得到 RL 模型
→ 推理引擎加载模型并生成回答1
2
3
4
5
6
7
2
3
4
5
6
7
这里有三个容易混淆的地方,先记住:
- 预训练不是教模型“回答问题”,而是让它学会根据前文预测下一个词元。
- 监督微调也不是重新灌知识,而是把已经学会的语言能力,整理成“用户问、助手答”的格式,并教它何时调用工具。
- 强化学习不会给模型增加新的事实知识。它根据奖励调整已有回答策略。nanochat 默认只在数学题上用它。
五个阶段分别在做什么
| 阶段 | 输入 | 产出 | 核心问题 |
|---|---|---|---|
| 分词 | 原始文本 | 整数序列 | 文字怎样变成模型能计算的数字? |
| 预训练 | 大量文本分片 | base_checkpoints | 模型怎样学会预测下一个词元? |
| 监督微调 | 对话数据和基础模型 | chatsft_checkpoints | 模型怎样学会按对话格式回答? |
| 强化学习 | 数学题和 SFT 模型 | chatrl_checkpoints | 回答正确时,怎样让模型更倾向于这种回答? |
| 推理 | 模型、分词器和提示 | 一个词元接一个词元 | 训练完的模型怎样真正生成回答? |
每一阶段都依赖上一阶段的产物。比如 SFT 脚本默认会去 base_checkpoints 里找预训练模型;推理脚本又会去 chatsft_checkpoints 或 chatrl_checkpoints 里找对话模型。搞清这些文件在哪里,比死记函数名更有用。
建议的阅读顺序
第一遍:建立直觉
只读这五页:
这一遍不要求会推导注意力,也不要求看懂优化器内部。你只需要能用自己的话解释:一句用户输入,经过哪些数据结构和模型计算,最后变成一个回答。
第二遍:跟着数据走
从一条文本开始,沿着它经过 tokenizer.py、dataloader.py、gpt.py,一直看到 loss_eval.py。
重点不是每一行代码,而是三个问题:
- 张量的形状从什么变成什么?
- 哪一步需要读取磁盘,哪一步在 GPU 上计算?
- 哪一步产生了可以保存下来、供下一阶段使用的文件?
第三遍:做实验
到从 CPU 走到多卡 GPU挑一个改动,例如:
- 改变
--depth,观察参数量和训练时间怎样变化。 - 改变
--max-seq-len,观察显存占用怎样变化。 - 关掉滑动窗口,比较训练速度和验证损失。
- 跳过强化学习,直接比较 SFT 模型和 RL 模型的数学成绩。
只有改过、跑过、看过输出,源码才会真正变成你的知识。
两条硬件路线
| CPU / Apple Silicon | 单卡或多卡 GPU | |
|---|---|---|
| 目的 | 理解流程、验证代码 | 训练可用的模型 |
| 模型规模 | 很小的演示模型 | 默认 d20 到 d24 左右 |
| 主要限制 | 时间,可能要数小时 | 显存和租用成本 |
| 是否需要 GPU | 不需要 | 需要 CUDA 显卡 |
| 能否得到高质量回答 | 通常不能 | 可以达到 GPT-2 附近的能力 |
如果你现在没有 GPU,不要因此停下。先把 CPU 链路走通,理解每一步的输入和输出。等有了 GPU,换掉启动命令和几个规模参数即可。
术语约定
全站固定使用下面这些说法。第一次出现时会给英文,之后不再更换。
| 固定说法 | 英文 | 在本教程中的意思 |
|---|---|---|
| 词元 | token | 分词器输出的最小单位,最终用整数编号表示 |
| 分词器 | tokenizer | 把文本和词元序列互相转换的程序 |
| 预训练 | pretraining | 在大规模文本上训练“预测下一个词元”的基础模型 |
| 监督微调 | SFT | 用带标准答案的对话数据继续训练基础模型 |
| 强化学习 | RL | 根据奖励调整模型回答策略的训练方式 |
| 推理 | inference | 使用训练好的模型生成回答 |
| 损失 | loss | 衡量模型预测和正确答案差距的数值 |
| 键值缓存 | KV Cache | 推理时保存历史的 Key 和 Value,避免重复计算 |
遇到不熟的词,可以直接查术语表。
本教程的边界
- 教程基于 nanochat 提交
92d63d4。上游代码更新后,行号或参数可能变化;每章都会给固定提交的源码链接。 - 教程重点讲清主链路。Flash Attention 的最底层内核、分布式通信的全部细节和 FP8 的数值实现,只在需要时点到为止。
- 示例中的小模型只用于验证流程,不代表最终效果。真正的 GPT-2 级别训练需要 8 张 H100 级别的显卡和上百 GB 数据。
- 所有时间都只是数量级参考。CPU 型号、网络、磁盘和 GPU 供应都会改变实际耗时。