189 lines
10 KiB
Markdown
189 lines
10 KiB
Markdown
# 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/`。
|