MiniMind 训练 8 阶段全景:从 Tokenizer 到 Agentic RL 的能力流水线

MiniMind 训练 8 阶段全景:从 Tokenizer 到 Agentic RL 的能力流水线

一个 64M 小模型能学会从「词语接龙」一直进阶到「多步用工具解题」,靠的不是某一个神奇算法,而是八个阶段、层层递进的训练流水线。每一个阶段都解决一个具体问题,每跳过一个,能力天花板就立刻下降。

GitHub jingyaogong/minimind 是过去两年小模型训练圈子里最出圈的开源教学项目之一:58,427 Star / 7,594 Fork / Apache-2.0 / Python 3.10+,描述就一句话:" Train a 64M-parameter LLM from scratch in just 2h!"(2 小时单卡从零训出一个 64M 参数模型)。但很多 Star 它的人是被"快速训好一个对话小模型"吸引进来的,真正值钱的部分却是它完整的训练阶段图谱——9 个独立 trainer 脚本,覆盖从 Tokenizer 重训到 Agentic RL 的全部路径,并附带 OpenAI 兼容推理 API、Web Demo、Tool Call 评测脚本、LoRA 合并脚本、模型转换脚本,是"大模型从 0 到 Agent 是怎么一步步炼成的"的最佳开源教学参考。

本文按作者在 README 中给出的能力递进顺序,逐阶段回答四个问题:解决什么核心问题?没有它会怎么样?MiniMind 是怎么实现的(脚本入口/数据格式)?典型坑和排错线索。读者按文章顺序一步步跑,就能在单卡 3090 上完成从 "2 小时得到可对话 Zero 模型" 到 "做出具备 Tool Call + Reasoning + Agent 轨迹能力的对齐模型"的全过程。

本文提纲

  1. 一张总表 + 一张图先把 8 个阶段定位清楚(含"最小 2 小时路径 vs 完整最佳效果路径")
  2. 阶段 0:Tokenizer(词表 6400 / BPE + ByteLevel / 特殊模板 token)
  3. 阶段 1:Pretrain 预训练——学会「词语接龙」(CE on all tokens)
  4. 阶段 2:Full SFT 监督微调——学会当助手,MiniMind-3 已混入 Tool Call + Reasoning
  5. Pretrain vs SFT 核心差异对照表 + 常见误区:为什么"先学语言再学听话"不能反过来
  6. 可选阶段 3a:LoRA——低成本领域适配(知道自己叫 MiniMind、学会垂直知识)
  7. 可选阶段 3b:Knowledge Distillation 蒸馏——黑盒(好答案做 SFT) vs 白盒(CE + KL 学分布)
  8. 可选阶段 3c:DPO——偏好对齐(RLHF 的"无 Reward Model 版")
  9. 可选阶段 3d:RLAIF——PPO / GRPO / CISPO 三条强化学习路线对比
  10. 可选阶段 3e:Agentic RL——优化整条多轮工具调用轨迹(不是单轮回答)
  11. 脚本与数据格式快速索引 + 仓库代码地图

1. 一表一图先定位:8 阶段 + 两条路径

阶段总表:每阶段「解决什么问题 / 没有会怎样」一句话

阶段 解决的核心问题 没有它会怎样
Tokenizer 文本如何数字化(切词→id) 无法训练,模型看不懂也输出不了人类文字
Pretrain 会不会说人话、有没有基础知识 只会乱码或胡言乱语,连正确的中文句子都拼不出来
Full SFT 会不会当助手、听指令、按对话格式走 会续写但不会对话;你问它"你好",它可能接着写"……今天的天气不错"而不是回你
LoRA 如何低成本适配某特定领域 / 个性 只能全参微调,显存/时间成本高 10~100 倍,容易过拟合毁通用性
Distillation 如何从大模型学能力(teacher→student) 64M 这种小模型的能力上限会非常低,永远达不到基座知识密度
DPO 如何让回答更符合人类偏好(风格/安全/礼貌) 可能答得对但粗鲁、不安全、说话方式和产品要求不符
RLAIF 如何在线探索并持续优化(PPO / GRPO / CISPO) 能力停留在 SFT 天花板,不会在高难任务上"越玩越强"
Agentic RL 如何学会稳定的多步工具调用与解题 不会稳定 tool_call:会用格式但经常忘记查、查错、或者中间卡壳

两条路径 + 总体流程架构图

MERMAID_BLOCK_0

  • 最小可用路径(约 2 小时 / 单卡 3090):Tokenizer → Pretrain → Full SFT → 得到一个已经能对话的 Zero 模型
  • 完整效果路径:在 SFT 之后,按需组合 LoRA / 蒸馏 / DPO / RLAIF / Agentic RL 做能力增强与对齐

增强路径之间不是严格串行的:LoRA 和蒸馏都可以挂在 SFT 基座上并行做;DPO 既可以直接接 SFT,也可以接蒸馏后的 student;RLAIF 一般在 DPO 之后(有了对齐基线再做在线探索);Agentic RL 通常放在最后(要求模型已经具备稳定的 tool_call 格式能力,再优化轨迹级奖励)。

2. 阶段 0:Tokenizer——文本与数字的桥梁

一句话定义:Tokenizer 是 LLM 的"词典 + 切分规则",把自然语言字符串切成离散的 token id 序列喂进模型,推理时再把 token id 解码回字符串。

为什么不能绕开

LLM 是数学函数,它吃的是向量、吐的是向量,不吃"汉字"。没有 Tokenizer,你手里的文本和模型参数之间就没有办法建立任何连接。

MiniMind 的设计

  • 词表大小6400 个 token——刻意精简,远小于 Qwen/Llama 的 15 万级词表。小词表带来两个训练侧的直接好处:embedding / lm_head 两层参数占比大幅下降(这两层参数量 = hidden_dim × vocab_size,vocab 小 20 倍,这两层就省 20 倍);64M 这样的 Tiny 模型里,省下来的参数可以放到 Decoder Layer 去,让推理层更深。
  • 分词算法BPE (Byte Pair Encoding) + ByteLevel。BPE 保证词频高的片段不被切碎、ByteLevel 兜底任意字节(包括生僻字、emoji、乱码字符),两者组合是 LLaMA/GPT 家族的标准范式。
  • 特殊模板 token:预留 <tool_call>、思考标签、对话角色分隔等特殊 token 序列。MiniMind-3 已经把 Tool Call 和 Reasoning 样本在 SFT 阶段就混进了主训练,所以 <tool_call> 这种模板标记必须在 Tokenizer 层就有稳定 id,不能后面临时加。

为什么不建议重训 Tokenizer

这是作者在 README 里非常强硬的一条建议。原因很直接:

  1. 旧权重全废:词表一变,embedding/lm_head 的维度对应关系全变,Pretrain 好的权重直接报废。
  2. 旧数据全废:所有 Pretrain/SFT 数据的 token 化结果全变,等价于数据集重做一遍。
  3. 旧评测全废:同一 prompt 在新旧 Tokenizer 下 token 序列不同,perplexity、准确率等评测结果不再可比。

MiniMind 主线固定使用 minimind_tokenizertrainer/train_tokenizer.py 脚本保留给你想了解"Tokenizer 是怎么训出来的"做教学演示,不建议在已经跑了 Pretrain 后换 Tokenizer

常见坑和排错

  • 特殊模板 token 没加进词表 → <tool_call> 被切成多段 → SFT 里学不到正确格式:先看 train_tokenizer.py 里 special_tokens 列表是否包含你要用的标记。
  • 英文空格/中文标点切分和直觉不一致 → 用 tokenizer.decode(tokenizer.encode(s)) 跑往返一致性测试,看 round trip 是否有损。
  • 句子长度超过 max_seq_len 时的截断点不友好(从中间把一个词切断):预处理阶段先按语义 chunk,不要直接等长截断。

3. 阶段 1:Pretrain(预训练)——学会「词语接龙」

一句话定义:在海量无标注连续文本上做无监督因果语言建模(Causal LM)——给定前文,预测下一个 token。

在学什么

三个层次依次被模型吸收:
1. 语法与语言规律:主谓宾、中文量词、英文时态、标点使用。
2. 常识与世界知识:"秦始皇是中国历史上第一位皇帝"这种事实,是通过无数出现过的上下文统计规律被编码进参数里。
3. 上下文统计关系:相邻段落之间的指代、因果、举例关系。

本质是高质量的续写能力

训练方式

  • 损失函数:Cross Entropy(对全部 token 做下一个 token 分类)。
  • 数据格式:纯文本 jsonl,一行一段连续文本。
{"text": "如何才能摆脱拖延症?治愈拖延症并不容易,但以下建议可能有所帮助。"}
  • 训练脚本trainer/train_pretrain.py(9.6 KB)
  • 产物out/pretrain_768.pth
  • 对应代码文件model/model_minimind.py(18.7 KB)+ dataset/lm_dataset.py(11.2 KB)

结束后模型能做什么 / 不能做什么

能做:续写自然语言、会作诗、会写一小段看起来像人话的段落、常识性填空("秦始皇是___"大概率接"中国历史上的第一位皇帝")。

不能做:区分 user/assistant 角色、按指令对话。你给它一句"你好",它可能续写为"你好,请问你叫什么名字?我叫小明,今天的天气不错……",而不是回你"你好!很高兴认识你。"——因为它学的是续写不是对话。

类比

读了万卷书的人,满腹经纶,但从没上过班、没跟人打过交道——会写文章,但不会做客服。

常见坑和排错

  • Perplexity 下不去而且 tokenizer 也没报错:先查数据里是不是有大量的非文本二进制垃圾(爬取数据时常见),看 lm_dataset.py 里 token 统计分布里 <unk> 是不是太多。
  • Loss 剧烈震荡:检查 batch 中不同样本的 seq_len 是否差异过大(10 vs 2048 混 batch 会毁稳定性),可用分桶 batch。
  • 跑了几轮感觉生成"胡言乱语":先不要怀疑架构,拿 10 条训练集里的文本喂进去 greedy 生成 20 token,看能不能接对——如果连训练集都接不对,说明训练根本没收敛,检查学习率和精度。

4. 阶段 2:Full SFT(监督微调)——学会「当助手」

一句话定义:在高质量的指令/对话数据上继续训练(参数全量更新),让模型适应交互格式、角色结构、任务行为模式。

在学什么(四个东西一次学完)

  1. 对话格式user / assistant / system / tool 等角色结构,让它明白"轮到谁说话了"。
  2. 指令跟随:听懂问题 → 按格式回答,不胡续写。
  3. 任务模式:问答、翻译、推荐、摘要、工具调用模板等。
  4. 风格与知识补充:当 SFT 数据量很大时,也相当于一种 mid-training——除了格式化,还能塞新知识。

MiniMind-3 SFT 的特别之处(重点)

当前主线 sft_t2t 的训练数据中已经混入了三种能力
- ~10 万条 Tool Call 样本(从 Qwen3 蒸馏而来)——做完 Full SFT 就已经会按 <tool_call>...</tool_call> 模板输出结构化工具调用。
- Reasoning 思考链样本——通过 open_thinking 开关在推理时控制是否显式输出思考标签内容(DeepSeek-R1 的思路:训练时显式看 CoT,推理时可以选要不要展开)。
- 统一 chat_template——不再训一个纯对话模型又训一个 reason 模型又训一个 tool-call 模型,一条 chat template 管所有能力,省三条独立模型链路。

这意味着 MiniMind-3 的 SFT 做完就具备"对话 + 基础 Tool Call + Reasoning"三种能力——不再是传统教程里"SFT 只教礼貌对话"那种效果。

训练方式

  • 损失函数:还是 Cross Entropy,但只计算 assistant 回复部分的 token loss,user instruction 和 system prompt 部分被 mask 掉。非常关键的实现细节:如果不 mask instruction 部分,模型会花很多容量去"复述指令"而不是学答案。
  • 数据格式:标准多轮对话 jsonl。
{
  "conversations": [
    {"role": "user", "content": "你好"},
    {"role": "assistant", "content": "你好!"}
  ]
}
  • 训练脚本trainer/train_full_sft.py(9.6 KB)
  • 产物out/full_sft_768.pth
  • 格式控制:SFT 前先把全部 conversations 走一遍 chat_template 拼字符串,再定位 assistant 在拼接文本中的 span,只有 span 内 token 的 label 不是 -100

类比

书读完了,现在开始上岗培训:学会礼貌回答、按工作流程办事、把用户的问题对应到自己的职责范围。

常见坑和排错

  • 训练好但一聊天就"续写 user 说的话":99% 是 mask 逻辑写错了,把 instruction 也算进 loss 了。打印一条样本的 label 序列,检查 user token 位置是不是 -100(PyTorch CE 忽略索引)。
  • Tool Call 格式不稳定:检查 SFT 数据里 Tool Call 样本的 <tool_call> 标签前后有没有被 Tokenizer 切碎。如果 <tool_call> 被切为三段,模型学到的格式就会飘。
  • Reasoning 标签和答案的边界没划清:CoT 样本里 </think> 和最终答案之间必须有稳定的分隔符,否则模型会"把推理写进答案里"。

5. Pretrain vs SFT 核心差异对照表

这是所有大模型训练教程里最重要的一张对照。很多团队把"多塞 SFT 数据"当万能药,其实从原理上就搞错了。

维度 Pretrain Full SFT
训练目标 学语言与知识(会说人话、有常识) 学交互格式与任务(会听话、会按格式做)
数据形态 连续文本(书籍/网页/代码/论文/百科) 多轮对话 / 指令对 / 工具调用模板
监督信号 全部 token 都要预测下一个 token 主要预测 assistant 回复 token;instruction 部分 mask
是否必须 是,绝对不能跳过 是,不做就不能对话
典型 Loss CE on ALL tokens CE on RESPONSE tokens only
数据质量侧重点 语言干净、去重、无乱码 角色对齐、输出格式合规、正确答案比例高
数据量对比 通常 GB~TB 级海量文本 通常 MB~GB 级(万~百万条对话)
失败表现 输出胡言乱语/乱码/非中文 答非所问/续写指令/分不清用户和自己
替换代价 极高——重做 = 全流程重来 较高,但还能复用 Pretrain 权重
正确关系 地基 盖房子

黄金法则:Pretrain 打地基,SFT 盖房子。没有 Pretrain,SFT 很难训出像样的模型(地基是空的);只有 Pretrain 没有 SFT,模型不会"听话"——它会续写文章,但永远不懂你问完问题它要回你。

6. 可选阶段 3a:LoRA——低成本领域适配

一句话定义:Low-Rank Adaptation(低秩适配)。在原权重旁边加两个薄的低秩矩阵 A×B,不冻结主体权重,只训练新增的少量参数

作用

  • 用很少算力做垂直场景适配:医疗问答、法律检索、让模型"知道自己叫 MiniMind 并能自我介绍"等。
  • 不破坏基座模型的主体权重:做完 LoRA 随时可以抛弃适配器回到主基座,也可以随时把 LoRA 合并进基座(scripts/convert_model.py)。

适用场景清单(什么时候选 LoRA,不要选 Full SFT)

  1. 你想让模型在自我介绍里说"我叫 MiniMind,一个小模型"——涉及 persona/自我认知,改动很小,LoRA 足够。
  2. 你想给模型补一个垂直专业领域的知识小语料(几百到几万条)。
  3. 显存/时间有限,跑不动 full fine-tune
  4. 你要同时维护多个行业版本的同基座模型——每个版本存一套 LoRA 权重(几十 MB)比存全量 checkpoint(几 GB)便宜多了。

训练方式

  • 基座full_sft_768.pth 冻结,不更新。
  • 只更新 LoRA 分支:新增的 A/B 低秩矩阵。
  • 脚本trainer/train_lora.py(10.2 KB),配套 model/model_lora.py(2.7 KB)。
  • 合并python scripts/convert_model.py(8.1 KB)把 LoRA 权重合并回完整模型,合并后的文件和正常 SFT 全量文件大小相同,推理零额外开销。

LoRA vs Full SFT 取舍速记

维度 LoRA Full SFT(再训一轮)
更新参数量 <1% 总量 100% 总量
显存需求 低(同 batch 下约省 30~50%)
适合数据量 小~中(几百~几十万条) 大(百万条以上)
是否损坏通用性 几乎不 很容易——垂域数据一塞就把通用对话能力冲没
是否可"撤销" 是,丢 adapter 即还原 否,只能回滚 checkpoint
产品多版本成本 极低(每版几十 MB LoRA 文件) 极高(每版全量几 GB+)

常见坑和排错

  • rank 设太高(>64):LoRA 的低秩特性被破坏,相当于在学全参,反而不如直接 SFT。推荐先从 4/8/16 试。
  • alpha 比例不匹配:常见设置 alpha = 2 * rank;设太小等于没加 LoRA,设太大直接把基座冲毁——合并后推理时 hallucination 明显增加。
  • 把 LoRA 用在 Pretrain 阶段:LoRA 适合适配/对齐风格和格式;学语言和海量知识是 Pretrain 的主场,别用 LoRA 塞百科。

7. 可选阶段 3b:Knowledge Distillation(蒸馏)

一句话定义:让小模型(student)向大模型(teacher)学习,把大模型的能力迁移到小模型参数里。

两条路线

路线一:黑盒蒸馏(MiniMind 主线 SFT 里已大量用)

  • 学什么:只学教师的最终答案。
  • 数据来源:用 Qwen3 等强模型生成高质量问答;Tool Call 那 ~10 万条样本也是 Qwen3 蒸馏出来的。
  • 本质:把"好答案"当作 SFT 数据跑一次 Full SFT。

路线二:白盒蒸馏(trainer/train_distillation.py,13.7 KB)

  • 学什么:不只学答案,还学教师每个 token 的概率分布(logits)。
  • 损失函数CE(student, gold) + KL(teacher_logits || student_logits),CE 保证答案是对的,KL 保证"对的那些备选 token 也跟老师一样"。
  • 价值:能传递更细粒度的"软偏好"——比如老师对两个候选词的概率是 60% vs 30%,纯 CE 只会让学生记住那个 60% 的,对 30% 那个不敏感;加 KL 后学生能学到"那个 30% 也是靠谱备选"这一隐式信息,在 OOD 场景泛化更好。

什么时候选哪条

  • 没有 teacher logits(拿不到教师模型推理环境,只有 API 能拉文本答案):黑盒蒸馏即可。
  • 能本地跑 teacher 模型(比如 teacher 也是开源的,例如自己训的 1B 版本要 distill 给 64M student):白盒蒸馏的收益稳定大于黑盒,值得跑 train_distillation.py

8. 可选阶段 3c:DPO——偏好对齐(RLHF 的无 Reward Model 路线)

一句话定义:Direct Preference Optimization。直接用"同一问题的好回答 vs 差回答"的偏好对来训模型,不需要单独训一个 Reward Model

在学什么

让模型对同一问题,P(chosen) 更高、P(rejected) 更低——在不需要外部 reward 信号的前提下做偏好对齐。更偏价值观/风格/安全对齐,对"做对题"的直接提升有限。

数据格式

{
  "chosen": [
    {"role": "user", "content": "Q"},
    {"role": "assistant", "content": "好回答"}
  ],
  "rejected": [
    {"role": "user", "content": "Q"},
    {"role": "assistant", "content": "差回答"}
  ]
}

技术属性

属性 DPO 细节
训练范式 Off-Policy:静态偏好数据可以反复用,不需要在线采样。
需要的模型 Actor(当前模型)+ Reference Model(参考模型,固定不更新,用于算 KL 偏离惩罚)。
优点 实现简单、训练稳定、显存低;不需要训练 RM 模型、不需要采样 rollout、没有 GAE/优势估计。
局限 不做在线探索。它不会让模型"看到自己没有见过的解题路径并越玩越好"——它只能把你已经给的偏好对压进参数。对"做对题"提升有限,更偏风格与价值对齐。
  • 脚本trainer/train_dpo.py(12.2 KB)
  • 产物out/dpo_768.pth

DPO 用好了能看到的变化

  • 语气更礼貌、更像你的产品要求(产品要求"简洁 3 句"输出就真的短了)。
  • 面对有害/诱导问题拒绝率更高且更一致。
  • <tool_call> 标签格式更稳定(如果你把"格式正确的 tool call"放 chosen、"缺标签/漏参数的放 rejected",DPO 能显著修格式问题)。

别拿 DPO 当万能药

如果你想让 64M 小模型的数学准确率从 20% 提到 80%,直接塞一堆"答对的/答错的"偏好对给 DPO,通常不会有你期望的提升。知识和推理能力的提升,靠 Pretrain + 蒸馏 + RLAIF;DPO 只负责"同一个能力水平下,选更符合你偏好的那种输出方式"。

9. 可选阶段 3d:RLAIF——PPO / GRPO / CISPO 三条 RL 路线

一句话定义:用可自动计算的奖励信号在线采样 + 在线优化策略,而不是靠人逐条标数据。AI(奖励函数)给 AI(策略模型)反馈,故称 RLAIF(Reinforcement Learning from AI Feedback)。

奖励信号来源(三类,可组合)

  1. Reward Model(RM):如 InternLM2-1.8B-Reward 这种预训练好的打分模型,输入一段对话返回一个 -3.0~+3.0 的连续分数。
  2. 规则函数:答案是否等于 ground truth(数学题的 gt 字段)、<tool_call> 标签是否配对、JSON 是否 schema-valid(代码是否通过 AST parse / 是否能在沙箱中跑通)、工具返回 200 还是 error。
  3. 环境反馈:代码执行 exit code = 0 / tool 调用返回 200 / 浏览器动作成功定位到元素。

DPO vs RLAIF 核心区别

维度 DPO RLAIF (PPO / GRPO / CISPO)
数据来源 静态离线偏好对 在线采样一批新回答
有没有探索 没有,只看已有的 chosen/rejected 有,每次采样策略都可能走出新路径
奖励怎么给 隐式的(偏好对比本身就是奖励) 显式的打分函数 / RM 分数
范式 Off-Policy(静态数据可重用) On-Policy(每一轮更新前都重新采样当前策略)
更擅长 风格、礼貌、安全、格式对齐 正确性、难任务上越玩越好、tool-use 探索
实现难度 高(采样、rollout、优势估计、KL 约束、mask 等)

9.1 PPO(Proximal Policy Optimization)

经典 RLHF 路线:三网(Actor + Critic + Reference)架构。

  • Actor:当前要训练的生成模型。
  • Critic:估算每个状态的 value(长期价值),和真实回报差算出 Advantage。
  • Reference:固定不更新的 SFT 模型,算 KL 散度约束 Actor 别跑太偏(防止为了拿奖励疯狂说 RM 喜欢但人类讨厌的话)。
  • 损失核心:裁剪概率比 clip(π_new/π_old, 1-ε, 1+ε),防止一次更新过激把策略冲崩;+ KL 惩罚项。
  • GAE(Generalized Advantage Estimation):把回报平滑分摊回每一步,降低 Advantage 的方差。

  • 脚本trainer/train_ppo.py(26.8 KB,是所有 trainer 里最大的,因为要维护 Actor + Critic + GAE + rollout)。

  • 优点:经典、理论成熟、业界用了很多年。
  • 缺点:三网络训练慢、显存高;64M 小模型上 Critic 估不准 value,reward 信号提升很慢。

9.2 GRPO(Group Relative Policy Optimization)

DeepSeek-R1 路线的基础,现在的主流首选:把 PPO 的 Critic 网络整个去掉,用"同组平均分"做 baseline。

同一问题生成 N 个回答,每个回答的优势:

Advantage_i = (Reward_i - mean(R_group)) / std(R_group)

没有 Critic,不需要训价值网络。

  • 优点:单网络更稳定、训练速度和显存占用都比 PPO 好一大截;小模型上尤其吃香,因为 64M 的 Critic 价值估计根本不准,不如不用。
  • 风险:退化组——N 个回答全是错的、奖励全 0 → 分子分母都接近 0 → 梯度接近 0 → 什么也学不到,整轮浪费。GRPO 的 N 一般要设到 8~16,就是为了降低"全错"的概率。

  • 脚本trainer/train_grpo.py(19.6 KB),通常比 PPO 收敛更稳更快。

9.3 CISPO(Clipped Importance Sampling PO)

GRPO 的一个 loss 变体,修复 PPO/GRPO 里 clip 截断梯度的问题:ratio 被 clip 截断之后,CISPO 保留 log π 的梯度路径,不让 clip 操作把重要性采样的梯度全切断。在 GRPO 脚本里设 loss_type="cispo" 就启用。

CISPO 在一些难任务上比 vanilla GRPO 稳定,属于"免费再试一次"的配置。

小模型做 RL 的特殊问题:奖励稀疏和全 0 陷阱

64M 模型在高难度任务(例如 24 点、代码题)上,很可能生成的 8~16 个回答全部答错,奖励全是 0 → GRPO 优势全是 0 → 梯度全 0 → 这一轮等于白跑,几轮下来模型毫无进步。

MiniMind 的应对策略:
1. 连续型 Reward Model,不用 0/1:用 InternLM2-1.8B-Reward 这种返回 -3.0~+3.0 连续分的 RM,就算都答错也能区分"更差的"和"没那么差的"。
2. 难度必须匹配模型能力边界:不要一上来就给 IMO 数学题,先从"小学 2 位数加减"这类 64M 有一定概率做对的难度喂起,让 RL 在有正梯度的区域先 warm up,再逐步提难度(课程学习)。

10. 可选阶段 3e:Agentic RL——优化整条多轮工具调用轨迹

一句话定义:不再优化"单轮回答的好坏",而是优化整条多轮交互轨迹 τ 的好坏:用户问题 → 思考 → <tool_call> → 工具执行结果 → 再思考 → ... → 最终答案。

与普通 GRPO 的区别(关键)

维度 普通 GRPO(R1 式) Agentic RL
优化对象 单轮回答 y 多轮轨迹 τ(多个 message)
奖励结算时机 回答一生成完就打分 整轮轨迹结束(最终答案给出或超时)才统一结算
交互 无,纯文本生成 有真实或模拟的工具执行(工具返回 200/404 影响后续生成)
数据文件 rlaif.jsonl agent_rl.jsonl
需要的额外模块 奖励函数即可 需要 rollout_engine.py(工具模拟器 + 轨迹控制)

奖励构成(拆开 5 项分算,可加权)

R(τ) = w1·R_answer(是否命中 ground truth)
     + w2·R_tool(工具调用是否合法/是否有返回)
     + w3·R_format(格式有没有对,tool_call 标签合不合规)
     + w4·R_rm(Reward Model 分数)
     - w5·R_unfinished(没在预算内拿到最终答案的惩罚)

一个常见的错误是把所有奖励压到最后("答对就给 1,答错就给 0"),导致模型学不到"怎么拿到正确答案的路径"。把 tool / format 等过程性奖励拆出来,可以让模型在全答错的时候也知道"至少我工具调用的格式是对的"往哪儿走。

脚本与架构

  • 训练入口trainer/train_agent.py(32.1 KB——是整个仓库里最大的 trainer)。
  • Rollout 引擎trainer/rollout_engine.py(10.3 KB),负责在 RL 采样阶段把"生成 tool_call → 模拟或真实调工具 → 把工具结果塞回消息 → 继续生成"这条轨迹跑通。Rollout 和 Learner 通过消息解耦,你可以把 rollout 换成真实的工具后端(搜索、浏览器、数据库)。
  • 评测脚本scripts/eval_toolcall.py(15.3 KB)——端到端测 Tool Call 准确率、格式合规率、解题成功率。

什么时候你需要 Agentic RL

  1. 你的场景要稳定地调多步工具(不是查一次就完了,是查搜索→读网页→填表→再查搜索→汇总)。
  2. 你已经有了可靠的 ground truth 测试集(每道问题知道正确答案、也知道哪些中间步骤是必须的),奖励函数定义得出来。
  3. SFT 阶段已经把 Tool Call 的格式打稳了(不然 Agentic RL 的前几万轮都在修格式,学不到解题)。

11. 脚本与数据格式快速索引 + 仓库代码地图

最后把 MiniMind 整个仓库按"训练者视角"重新整理成一张可查找的索引,读者随时可以定位代码。

Trainer 脚本(9 个,按训练阶段一一对应)

文件名 大小 作用 对应阶段 产物
trainer/train_tokenizer.py 14.2 KB 在新数据上训练 BPE Tokenizer 阶段 0 minimind_tokenizer.json
trainer/train_pretrain.py 9.6 KB Causal LM 预训练 阶段 1 out/pretrain_*.pth
trainer/train_full_sft.py 9.6 KB 全参数监督微调(对话 + Tool Call + Reasoning) 阶段 2 out/full_sft_*.pth
trainer/train_lora.py 10.2 KB LoRA 低秩适配 3a LoRA adapter + 可合并
trainer/train_distillation.py 13.7 KB KD(黑盒 SFT 或白盒 CE+KL) 3b out/distil_*.pth
trainer/train_dpo.py 12.2 KB Direct Preference Optimization 3c out/dpo_*.pth
trainer/train_ppo.py 26.8 KB PPO Actor+Critic 三网 RL 3d out/ppo_*.pth
trainer/train_grpo.py 19.6 KB GRPO + CISPO 单网络 RL 3d out/grpo_*.pth
trainer/train_agent.py + rollout_engine.py 32.1 + 10.3 KB Agentic RL 多轮轨迹优化 3e out/agent_*.pth

其他配套脚本

文件名 大小 作用
scripts/web_demo.py 22.1 KB Gradio Web Demo,打开浏览器聊天 + 看 token
scripts/serve_openai_api.py 10.8 KB OpenAI 兼容 HTTP API,可接 Open WebUI / LobeChat
scripts/chat_api.py 1.7 KB 最小 Python Chat API 示例
scripts/convert_model.py 8.1 KB LoRA merge / 模型格式转换 / 权重裁剪
scripts/eval_toolcall.py 15.3 KB Tool Call 端到端评测脚本
eval_llm.py 5.5 KB LLM 通用 benchmark 评测主入口

数据格式示例(训练者必须对齐的 6 种 JSONL)

数据文件 1 行长什么样 对应阶段
Pretrain jsonl {"text":"...连续文本..."} Pretrain
SFT jsonl {"conversations":[{"role":"user","content":"Q"},{"role":"assistant","content":"A"}]}(支持多轮 + tool/system) Full SFT / LoRA / Distill(黑盒)
KD 白盒 SFT 数据 + 另一个文件存 teacher logits(或同时 forward teacher) Distillation(白盒)
DPO jsonl {"chosen":[...],"rejected":[...]} 每条各是一段对话(同 Q 两答) DPO
RLAIF jsonl 问题集合(每问采样 N 答,奖励函数打分) PPO / GRPO / CISPO
Agent jsonl 问题集合 + 工具后端定义 + ground truth Agentic RL

理解了这 6 种数据格式 + 9 个 trainer 脚本之间的对应关系,你就把 MiniMind 的训练全链路掌握了。剩下的事情只是:准备数据、选合适的脚本、调超参、跑、checkpoint、评估、按评估结果决定"要不要再加一段 LoRA / 要不要补 DPO / 要不要上 GRPO"——这就是大模型训练的完整流程。


作者: itech001
来源: 公众号:AI人工智能时代(the-ai-era)
网站: https://www.theaiera.top/
关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top

本文首发于 AI人工智能时代,转载请注明出处。

posted @ 2026-09-04 21:23  iTech  阅读(12)  评论(0)    收藏  举报