minimind/course/00_syllabus.md

189 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# MiniMind LLM 系统学习课程总纲
本课程以 MiniMind 源码为主教材,目标不是记住一堆术语,而是把一条完整 LLM 链路真正跑通、看懂、改得动。
核心学习主线:
```text
jsonl 数据
-> tokenizer / chat template
-> input_ids / labels
-> MiniMindForCausalLM
-> logits / next-token loss
-> optimizer / checkpoint
-> SFT / LoRA / DPO / PPO / GRPO
-> eval / API / WebUI
```
建议节奏:28 节,每节 60-90 分钟。每节尽量配一个最小实验,实验目标是验证源码里的关键变量流转,不追求训练出好模型。
从第 13 课开始,课程增加一条手写复现主线:
```text
原理讲解
-> MiniMind 源码走读
-> 手写核心模块
-> 和原源码做对齐测试
-> 阶段结束时组装成可运行脚本
```
目标不是复制所有工程外围,而是在 `course/impl/` 下手写一个教学版 MiniMind 核心实现。tokenizer、原始数据、分布式训练、wandb/swanlab、断点续训、WebUI/API、模型转换等工程能力优先复用原项目。
## 当前课程进度
已完成:
| 课次 | 文件 | 当前状态 |
|---:|---|---|
| 1 | `01_project_overview.md` | 已写,早期格式,后续可统一成新格式 |
| 2 | `02_environment_and_resources.md` | 已写,早期格式,后续可统一成新格式 |
| 3 | `03_cli_inference.md` | 已按新格式重写 |
| 4 | `04_tokenizer_and_special_tokens.md` | 已按新格式重写 |
| 5 | `05_sft_dataset_and_labels.md` | 已按新格式完成 |
| 6 | `06_pretrain_vs_sft.md` | 已按新格式完成 |
| 7 | `07_pretrain_training_entry.md` | 已按新格式完成 |
| 8 | `08_minimind_config_and_params.md` | 已按新格式完成 |
| 9 | `09_embedding_norm_residual_block.md` | 已按新格式完成 |
| 10 | `10_causal_lm_forward_and_loss_shift.md` | 已按新格式完成 |
| 11 | `11_attention_principles_and_source.md` | 已按新格式完成 |
| 12 | `12_rope_and_kv_cache.md` | 已按新格式完成 |
| 13 | `13_ffn_and_moe.md` | 已按手写复现新格式完成 |
| 14 | `14_lr_grad_accum_amp.md` | 已按手写复现新格式完成 |
| 15 | `15_checkpoint_resume.md` | 已按手写复现新格式完成 |
| 16 | `16_full_sft_training_overview.md` | 已按手写复现新格式完成 |
| 17 | `17_pretrain_to_full_sft.md` | 已按手写复现新格式完成 |
| 18 | `18_lora_principles_and_implementation.md` | 已按手写复现新格式完成 |
| 19 | `19_lora_training_flow.md` | 已按手写复现新格式完成 |
| 20 | `20_distillation_training_flow.md` | 已按源码训练链路新格式完成 |
| 21 | `21_dpo_dataset_and_reference.md` | 已按源码训练链路新格式完成 |
| 22 | `22_dpo_loss_source.md` | 已按源码训练链路新格式完成 |
| 23 | `23_ppo_training_flow.md` | 已按源码训练链路新格式完成 |
| 24 | `24_grpo_cispo.md` | 已按源码训练链路新格式完成 |
| 25 | `25_reward_logprob_kl.md` | 已按源码训练链路新格式完成 |
| 26 | `26_tool_use_and_agentic_rl.md` | 已按源码训练链路新格式完成 |
| 27 | `27_model_conversion_api_webui.md` | 已按源码部署链路新格式完成 |
| 28 | `28_final_review_and_capstone.md` | 已按总复盘与小项目格式完成 |
28 节主线课程已完成;后续进入按方向扩展或补强实验。
## 课程结构
| 模块 | 课次 | 主题 | 主要源码 | 实验 |
|---|---:|---|---|---|
| 项目全局 | 1 | 项目地图与学习路线 | `README.md`, `eval_llm.py`, `trainer/*` | 画出主调用链 |
| 项目全局 | 2 | 环境、依赖、数据与权重 | `requirements.txt`, `trainer/trainer_utils.py` | 检查 import、本地数据和权重 |
| 推理入门 | 3 | CLI 推理流程 | `eval_llm.py`, `model/model_minimind.py` | 跑真实或 tiny 推理 |
| Tokenizer | 4 | Tokenizer 与特殊标记 | `model/tokenizer.json`, `model/tokenizer_config.json`, `trainer/train_tokenizer.py` | 编码/解码、观察 special tokens |
| 数据格式 | 5 | SFT 数据、Prompt 与 Labels | `dataset/lm_dataset.py`, `model/tokenizer_config.json` | 打印 SFT prompt 和 labels mask |
| 数据目标 | 6 | Pretrain 与 SFT 的数据目标对比 | `dataset/lm_dataset.py`, `model/model_minimind.py` | 对比 pretrain/SFT 的 `input_ids` 和 `labels` |
| 预训练 | 7 | Pretrain 训练入口如何串起来 | `trainer/train_pretrain.py`, `trainer/trainer_utils.py` | CPU 跑一个 tiny pretrain step |
| 模型结构 | 8 | MiniMindConfig 与参数规模 | `MiniMindConfig`, `MiniMindForCausalLM` | 对比 hidden/layer/head 改变后的参数量 |
| 模型结构 | 9 | Embedding、RMSNorm 与残差结构 | `MiniMindModel`, `RMSNorm`, `MiniMindBlock` | 跟踪 hidden states shape |
| 模型结构 | 10 | Causal LM forward 与 next-token loss | `MiniMindForCausalLM.forward` | 手动验证 logits/labels shift |
| 模型结构 | 11 | Attention 原理与源码 | `Attention.forward`, `repeat_kv` | 追踪 Q/K/V、scores、causal mask |
| 模型结构 | 12 | RoPE 与 KV cache | `precompute_freqs_cis`, `apply_rotary_pos_emb`, `generate` | 查看 RoPE shape,对比 cache 生成 |
| 模型结构 | 13 | FFN 与 MoE | `FeedForward`, `MOEFeedForward` | 对比 dense/MoE 参数量和 aux loss |
| 训练机制 | 14 | 学习率、梯度累积、混合精度 | `get_lr`, `train_epoch` | 打印 lr 曲线和 accumulation step |
| 训练机制 | 15 | checkpoint 与断点续训 | `lm_checkpoint`, `SkipBatchSampler` | 保存/恢复 tiny 权重 |
| SFT | 16 | Full SFT 训练脚本总览 | `trainer/train_full_sft.py`, `SFTDataset` | 跑一个 tiny SFT step |
| SFT | 17 | 从 pretrain 权重到 full_sft 权重 | `init_model`, `train_full_sft.py`, `eval_llm.py` | tiny pretrain -> tiny SFT -> 推理 |
| LoRA | 18 | LoRA 原理和手写实现 | `model/model_lora.py` | 给 Linear 注入 LoRA |
| LoRA | 19 | LoRA 训练流程 | `trainer/train_lora.py` | 验证只更新 LoRA 参数 |
| 蒸馏 | 20 | Distillation 训练链路 | `trainer/train_distillation.py` | 对比 teacher/student logits |
| 偏好学习 | 21 | DPO 数据和 reference model | `trainer/train_dpo.py` | 打印 chosen/rejected mask |
| 偏好学习 | 22 | DPO loss 源码 | `trainer/train_dpo.py` | 手算一个 batch 的偏好 loss |
| RL | 23 | PPO 训练链路 | `trainer/train_ppo.py`, `trainer/rollout_engine.py` | 拆解 rollout/reward/update |
| RL | 24 | GRPO 与 CISPO | `trainer/train_grpo.py` | 对比不同 loss_type |
| RL | 25 | reward、logprob 与 KL penalty | `trainer/trainer_utils.py`, `trainer/rollout_engine.py` | 查看 logprob/KL shape |
| Agent | 26 | Tool Use 与 Agentic RL | `trainer/train_agent.py`, `scripts/eval_toolcall.py` | 解析一次 tool_call |
| 部署 | 27 | 模型转换、API 与 WebUI | `scripts/convert_model.py`, `scripts/serve_openai_api.py`, `scripts/web_demo.py` | 启动 OpenAI 兼容接口 |
| 综合 | 28 | 总复盘与小项目 | 全项目 | 完成 tiny LLM 训练报告 |
## 每节课固定格式
第 3-12 课采用源码讲解 + 观察实验的新格式。第 13 课开始采用“原理 + 源码 + 手写 + 对齐 + 组装”的新格式。
```text
目录(使用可点击跳转链接)
0. 本节主线
1. 原理讲解
2. 源码阅读顺序图
3. MiniMind 源码走读
4. 本节必须会写 / 暂时不要求
5. 手写模块
6. 对齐测试
7. 阶段组装
本节检查
下一课
```
每个原理内部固定回答:
```text
这个原理到底是什么
为什么这节课要懂它
看哪段源码
这段源码证明了什么
理解到哪一步就够
哪些细节暂时不要看
```
源码证据不单独堆在最后,而是嵌入到对应原理里。每段源码都要说明“看它是为了理解什么”。
## 手写复现路线
每节课产出的代码都要能进入阶段实现,而不是停留在零散练习。阶段结束时,优先用 `course/impl/` 下的教学版实现跑通 tiny 或 mini 数据;工程外围需要成熟能力时,再复用 MiniMind 原源码。
| 阶段 | 手写产物 | 阶段验收 |
|---|---|---|
| 模型结构 | `core/model_parts.py`, `core/causal_lm.py`, `core/generation.py` | 手写 RMSNorm、Attention、RoPE、KV cache、FFN、CausalLM,并通过 shape/output 对齐测试 |
| Pretrain | `core/datasets.py`, `core/losses.py`, `core/train_loop.py`, `train_pretrain_impl.py` | 跑通 tiny pretrain,保存并加载 `course_pretrain` 权重 |
| SFT | `train_sft_impl.py` | 手写 SFT labels mask,从 pretrain 权重继续训练,保存 `course_sft` 权重 |
| LoRA | `core/lora.py`, `train_lora_impl.py` | 手写 LoRA Linear,验证只更新 LoRA 参数,跑通短 SFT |
| DPO | `train_dpo_impl.py` | 手写 chosen/rejected logprob 和 DPO loss,跑通短偏好训练 |
| PPO/GRPO | `core/ppo.py`, `core/grpo.py`, `train_grpo_impl.py` | 手写 rollout/logprob/reward/KL/advantage/policy loss 的最小闭环 |
阶段结束课额外包含:
```text
阶段能力检查表
阶段验收命令
源码差异解释
portfolio 记录
```
## 学习记录与产出
课程中的学习记录分三类:
| 位置 | 用途 |
|---|---|
| `course/notes/` | 个人笔记、错题和踩坑记录 |
| `course/impl/` | 手写教学版 MiniMind 核心实现 |
| `course/portfolio/` | 阶段进度、实验记录、实现说明、简历描述草稿 |
`course/notes/mistakes.md` 专门记录 shape、mask、labels、shift、cache、logprob、chosen/rejected 等错误。每次写错代码时,优先记录“错在哪里、为什么错、正确源码在哪里、以后怎么判断”。
## 学完后的能力目标
完成课程后,应该能独立说明并改动:
- tokenizer 如何把文本变成 token id。
- chat template 如何把多轮对话变成 prompt。
- pretrain 和 SFT 的数据、labels、loss 有何不同。
- `MiniMindForCausalLM` 如何从 `input_ids` 得到 logits 和 loss。
- Attention、RoPE、FFN、MoE 在源码里如何组织。
- 训练脚本如何组织 optimizer、lr、amp、checkpoint。
- LoRA 如何注入、训练和保存。
- DPO/PPO/GRPO 在训练目标上和 SFT 有什么差异。
- 如何把模型接到 CLI、OpenAI API 或 WebUI。
- 如何手写 MiniMind 核心训练链路,并说明教学版实现和原项目工程实现的差异。
## 推荐学习纪律
- 每节课先读“本节主线”,再看原理,不要一上来扎进整段源码。
- 每个源码片段只问一个问题:这段代码证明了哪个原理。
- 不跳过 tiny 实验。实验是为了确认变量形状、mask 和 loss 区域。
- 不追求第一次就训练出好模型,先追求能解释每个张量的来源和形状。
- 每个模块结束后写 5-10 行自己的总结,笔记可以放在 `course/notes/`。