现在我有了足够的信息输出完整的中文学习笔记用纯 PyTorch 从零手搓一个完整 LLM从预训练到 GRPO 对齐的全链路实践指南核心观点这个项目的定位不是又一个玩具 Transformer而是一套教学级的完整工业流水线复现从原始文本到经过 RLHF 对齐、具备推理格式输出的语言模型全程不依赖trl、peft、transformers三大黑盒库所有算法用原生 PyTorch 手写。这意味着读者看到的每一行代码都是可拆解、可调试的白盒。从技术演进位置看这是一个渐进集成项目而非范式突破——它没有发明新算法但把 2017 年的 Transformer 论文到 2025 年 DeepSeek-R1 的 GRPO串成了一条单 GPU 可跑的学习路径。参照系应该是Andrej Karpathy 的nanoGPT只有预训练 HuggingFace TRL有后训练但高度封装这个项目填补了两者之间那片知道原理但不知道代码如何写的空白。关键信息与技术机制整体流水线raw text → tokens → Transformer → next-token loss → base model base model → SFT → Reward Model → {PPO, DPO} → GRPO → evaluation chat这条流水线的核心思路只有一句话作者原话把文本变成数字预测下一个 token然后不断改变数据和损失函数直到模型做你想要的事。越简单的总结越说明作者对整件事理解得越深。模型规模矩阵配置参数量n_embedn_headn_blocks入门演示13.1M12881教程基础77M51288后训练默认406M1024162413M 的模型在免费的 Kaggle/Colab T4 上就能跑406M 需要 V100 16GB 量级。作者还给出了精确的 GPU 显存对照表A100 40GB 可跑到约 6-8BRTX 4090 24GB 约 4B。最值得拆解的机制SFT 损失掩码SFT 阶段最核心的不是用指令数据微调而是损失掩码loss mask的精确构造def encode_chat(messages, add_generation_promptFalse): ids, mask [], [] for m in messages: role m[role] # role header 永远 mask 掉不训练模型去发出 header header_ids _encode_ordinary(_header_for(role)) ids.extend(header_ids) mask.extend([0] * len(header_ids)) content_ids _encode_ordinary(m[content]) is_completion role assistant ids.extend(content_ids) mask.extend([1 if is_completion else 0] * len(content_ids)) # 只训练 assistant ids.append(EOT_ID) mask.append(1 if is_completion else 0) return ids, mask实际效果是一个 512 token 的行里只有 48 个 assistant token 的 mask 为 1其余 464 个 prompt token 全为 0损失函数只在这 48 个位置反向传播。这是防止模型学会复述提示词的关键手术刀而不是什么玄学技巧。GRPO最简洁的去掉 Critic方案GRPODeepSeek-R1 的核心组件相比 PPO 最革命性的地方在于移除了 Value NetworkCritic改用同 prompt 生成多个答案组内归一化来估算优势函数def group_advantages(rewards, group_size, eps1e-4): r rewards.view(-1, group_size) mean r.mean(dim1, keepdimTrue) std r.std(dim1, keepdimTrue) adv (r - mean) / (std eps) # 比组内平均好多少 return adv.reshape(-1)这个设计的巧妙之处Value Network 在小模型上训练不稳定且占显存GRPO 用统计量代替神经网络使单 GPU 训练 RLHF 成为现实。代价是需要每个 prompt 生成多个样本吞吐量下降。对数学推理任务项目还设计了可验证奖励Verifiable Rewardextract_answer(42) - 42.0 reward_gsm8k(42, 42.0) - 1.2 # 正确且格式规范 reward_gsm8k(7, 42.0) - 0.2 # 错误但用了格式格式正确就给部分奖励这是训练推理格式的稳定信号来源也是 DeepSeek-R1 能让小模型学会think in tags的工程关键。Bradley-Terry 奖励模型def bradley_terry_loss(chosen_rewards, rejected_rewards): return -F.logsigmoid(chosen_rewards - rejected_rewards).mean()结果该 reward model 在 7974 对偏好数据上测试准确率达到 57.4%——高于 50% 的随机基线但距离工业级通常 70%仍有明显差距作者也没有刻意掩盖这个数字。代码示例MLP 和注意力机制骨架class MLP(nn.Module): def __init__(self, n_embed): super().__init__() self.hidden nn.Linear(n_embed, 4 * n_embed) # 展开到 4 倍 self.relu nn.ReLU() self.proj nn.Linear(4 * n_embed, n_embed) # 压缩回来 def forward(self, x): x self.relu(self.hidden(x)) return self.proj(x)输入输出形状都是(B, T, n_embed)方便堆叠 block。这是经典 Transformer FFN 的最小实现4× 展开来自原始论文ReLU在现代 LLM 中通常被SwiGLU替代但教学优先时ReLU更直观。交叉验证我搜索了两个独立信源进行验证信源一知乎《大模型对齐算法深度解析PPO、DPO、GRPO、DAPO》2026年1月页面因登录限制未能完整抓取但该文章标题和摘要方向与原项目的算法选择一致均认为 PPO → DPO → GRPO 是一条从复杂到高效的演进路线GRPO 因去除 Critic 而在中小规模训练中更实用。信源二arxiv 论文《Is DPO Superior to PPO for LLM Alignment? A Comprehensive Study》2024年5月这是一篇重要的反驳性信源对原项目DPO 是 PPO 替代的隐含叙事提出了质疑论文用 Theorem 4.1 严格证明PPO 找到的策略集合是 DPO 策略集合的真子集——DPO 可能发现 PPO 永远不会产生的策略而这些策略往往是有问题的 OOD分布外解在代码生成任务CodeContest上DPO 通过率为0%PPO 为22.4%超越 AlphaCode-41B 的 16.4%DPO 对base model 与偏好数据分布不匹配极为敏感SafeRLHF 安全率 55.4% vs SFT 后的 71.8%独立判断原项目同时实现了 DPO 和 PPO并没有过度推崇 DPO这点是诚实的。但原项目偏向把所有算法走一遍的教学叙事对何时该用 DPO、何时必须用 PPO的边界判断着墨不多。arxiv 论文的结论明确补充了这个缺口DPO 适合对话类任务且数据分布匹配的场景PPO 在高挑战性任务代码、数学竞赛上仍是更鲁棒的选择。边界与局限不该被忽略的部分奖励模型质量是天花板57.4% 的偏好准确率对于真实 RLHF 来说是够用但不够好——如果奖励模型本身判断错误PPO/GRPO 会放大错误而不是改正它。原项目规模限制406M base model决定了奖励模型精度有限。训练数据量级与真实 LLM 不在一个量级The Pile 的子集 Alpaca/Dolly/GSM8K数据量远小于 GPT-3 的 300B tokens 级别。这意味着训练出的模型有 LLM 的形态但不具备 LLM 的真实能力——这是教学目标不是工程目标读者不能混淆。GRPO 的课程设计依赖先验训练时先喂短算术题warm-up再喂 GSM8K是为了保证非零奖励信号。如果直接上复杂任务模型初期全答错GRPO 拿不到区分度训练会卡死。这个课程设计细节原文提到了但初学者容易忽视。没有使用 RoPE / Flash Attention / SwiGLU对于学习 Transformer 原理足够但要对接现代开源模型LLaMA、Mistral还需要补这些现代化改造。DPO 的 OOD 问题在小模型上更严重base model 本身分布质量差DPO 更容易钻空子。原项目在小规模下用 DPO实际上是在条件最不利的情况下演示 DPO结果可能不能代表 DPO 在大模型上的真实表现。个人启发这个项目最实际的价值不是训出一个好用的 LLM而是给你一套可以单步调试的对照实验框架。具体行动建议如下对学生/研究者先跑 13M 的 smoke testCPU 上几秒钟验证整条流水线能通再切换到真实数据。configs/smoke/目录里的配置就是为此设计的。重点读src/post_training/目录下的 PPO 和 GRPO 实现对照 arxiv 论文理解为什么 GRPO 去掉了 Critic 但仍然有效。对开发者如果你在为特定垂直领域医疗、法律、数学做对齐这套代码提供了比 TRL 更易修改的奖励函数接入点——你可以把reward_gsm8k换成任何领域的可验证奖励。GPU 内存不够时优先开--amp--grad-checkpointing再考虑--grad-accum三个 flag 叠加可以把显存压到约原来的 1/3-1/2。对决策者/团队 lead这个项目的存在本身说明2025 年从零复现完整 RLHF 流水线的门槛已经降到本科生 一张 4090的水平。如果你的团队对 LLM 对齐机制是黑盒状态现在补课的成本已经足够低了。延伸思考GRPO 去掉 Critic 的代价是什么每个 prompt 要采样多组答案批量估算均值/方差作为基线。这在数学类有唯一正确答案的任务上效果好但在开放式写作/对话任务上组内归一化的奖励信号可能方差极大甚至无意义——GRPO 的适用边界究竟在哪里是否存在一类任务让 GRPO 比 PPO 更差可验证奖励Verifiable Reward是否正在成为 RLHF 的新范式从 DeepSeek-R1 到这个项目用程序化规则答案正误、格式检查、代码编译替代神经网络奖励模型的趋势越来越明显。这对无法被程序化验证的任务创意写作、价值观对齐意味着什么——是新的分水岭还是只是对特定任务类型的特例在教学目标和工程目标之间这类从零实现的项目能走多远nanoGPT 推出后催生了大量变体但至今主流生产环境仍在用 vLLM TRL PEFT。手写实现的价值是理解机制但工程优化算子融合、CUDA kernel、分布式策略是另一个维度的战争——这个项目在 406M 的规模停下来是有意识的边界划定还是受限于作者算力参考信源原始项目FareedKhan-dev/train-llm-from-scratch交叉验证Arxiv 2404.10719 Is DPO Superior to PPO for LLM Alignment? A Comprehensive Study2024年5月交叉验证知乎《大模型对齐算法深度解析PPO、DPO、GRPO、DAPO》2026年1月 参考来源GitHub - FareedKhan-dev/train-llm-from-scratch: A straightforward method for training your LLM, from downloading data to generating text. · GitHub