"大道至简"
- 此开源项目旨在完全从 0 开始,仅用 3 块钱成本与 2 小时训练时间,即可训练出规模约为 64M 的超小语言模型 MiniMind。 MiniMind 系列极其轻量,主线最小版本体积约为 GPT-3 的 $\frac{1}{2700}$,力求让普通个人 GPU 也能快速完成训练与复现。
项目同时开源了大模型的极简结构与完整训练链路,覆盖 MoE、数据清洗、预训练(Pretrain)、监督微调(SFT)、LoRA、RLHF(DPO)、RLAIF(PPO / GRPO / CISPO)、Tool Use、Agentic RL、自适应思考与模型蒸馏等全过程代码。
- MiniMind 同时拓展了视觉模态模型 MiniMind-V、多模态 Omni 模型
MiniMind-O、扩散语言模型(MiniMind-dLM)、线性模型(MiniMind-Linear),详见
- 项目所有核心算法代码均从 0 使用 PyTorch 原生实现,不依赖第三方库提供的高层抽象接口。 这不仅是一个大语言模型全阶段开源复现项目,也是一套面向 LLM 入门与实践的教程。 希望此项目能为更多人提供一个可复现、可理解、可扩展的起点,一起感受创造的乐趣,并推动更广泛 AI 社区的进步。
注:本项目基于 Apache 2.0 协议开源,完全免费。“2 小时” 指 SFT 阶段在单张 NVIDIA 3090 上跑完
1 epoch的实测耗时,“3 块钱” 指对应时段的 GPU 租用成本。
📌 项目介绍
大语言模型(Large Language Model, LLM)的出现,引发了全球范围内对 AI 的空前关注。无论是 ChatGPT、DeepSeek 还是 Qwen,都以惊艳的效果让人真切感受到这场技术浪潮的冲击力。然而,动辄数百亿参数的模型规模,使得它们对个人设备而言不仅难以训练,甚至连部署都显得遥不可及。
打开大模型的“黑盒子”,真正去理解其内部运作机制,本应是一件令人心潮澎湃的事。遗憾的是,绝大多数探索最终都止步于使用 LoRA 等技术对现有大模型做少量微调,学习一些新指令或特定任务。这更像是在教牛顿如何使用 21 世纪的智能手机——虽然有趣,却偏离了理解物理本质的初衷。
与此同时,第三方的大模型框架与工具库,如 transformers / trl / peft 等,往往只暴露出高度抽象的接口。只需短短十几行代码,就可以完成“加载模型 + 加载数据集 + 推理 + 强化学习”的全流程训练。这种高效封装固然便利,却也在一定程度上把开发者与底层实现隔离开来,削弱了深入理解 LLM 核心代码的机会。
我认为 “用乐高自己拼出一架飞机,远比坐在头等舱里飞行更让人兴奋”,然而更现实的问题是,互联网上充斥着大量付费课程和营销内容,用漏洞百出、一知半解的讲解包装所谓的 AI 教程。正因如此,本项目的初衷就是尽可能降低 LLM 的学习门槛,让每个人都能从理解每一行代码开始,从 0 开始亲手训练一个极小的语言模型。
是的,从零开始训练,而不是仅仅停留在推理层面。最低只需不到 3 块钱的服务器成本,就能亲身体验从 0 到 1 构建一个语言模型的全过程。
😊 一起感受创造的乐趣吧!
🎉 本项目包含以下内容
- 提供完整的 MiniMind-LLM 结构代码(Dense + MoE),当前主线结构对齐
Qwen3 / Qwen3-MoE生态。- 提供 Tokenizer 与分词器训练代码,支持<tool_call>、<tool_response>、<think>等模板标记。- 覆盖
Pretrain、SFT、LoRA、RLHF-DPO、RLAIF(PPO / GRPO / CISPO)、Tool Use、Agentic RL、自适应思考与模型蒸馏等完整训练流程。
-
提供全阶段开源数据,覆盖收集、蒸馏、清洗与去重后的高质量数据集。- 关键训练算法与核心模块均从 0 实现,不依赖第三方框架封装。- 兼容
transformers、trl、peft等主流框架,以及llama.cpp、vllm、ollama等常用推理引擎与Llama-Factory等训练框架。 -
支持单机单卡与单机多卡(DDP、DeepSpeed)训练,支持 wandb / swanlab 可视化与动态启停训练。- 支持在 C-Eval、C-MMLU、OpenBookQA 等第三方测评集上进行评测,并支持通过 YaRN 实现 RoPE 长文本外推。- 提供兼容 OpenAI API
协议的极简服务端,便于接入 FastGPT、Open-WebUI 等第三方 Chat UI,并支持 reasoning_content、tool_calls、open_thinking。
- 提供基于 Streamlit 的极简聊天 WebUI,支持思考展示、工具选择与多轮 Tool Call。-
包含实验性拓展:离散扩散语言模型(dLM)与线性注意力模型([Linear
Attention](https://github.com/jingyaogong/minimind/discussions/704)),均可基于主线 AR 模型进行续训。
🎉 已发布模型列表
| 模型 | 参数量 | Release | |------|--------|---------| | minimind-3 | 64M | 2026.04.01 | | minimind-3-moe | 198M-A64M | 2026.04.01 | | minimind2-small |
26M | 2025.04.26 | | minimind2-moe | 145M | 2025.04.26 | | minimind2 | 104M | 2025.04.26 | | minimind-v1-small | 26M | 2024.08.28 | | minimind-v1-moe
| 4×26M | 2024.09.17 | | minimind-v1 | 108M | 2024.09.01 |
📝 更新日志
🔥 2026-04-01
- 发布 `minimind-3` / `minimind-3-moe`:结构、Tokenizer、训练链路、推理接口与默认配置全面更新 - 结构主线对齐 `Qwen3 / Qwen3-MoE` 生态:Dense 约 `64M`,MoE 约 `198M-A64M`,并移除了 shared expert 设计 - 默认训练数据切换为 `pretrain_t2t(_mini).jsonl`、`sft_t2t(_mini).jsonl`、`rlaif.jsonl`、`agent_rl.jsonl` 与 `agent_rl_math.jsonl` - 移除独立 `train_reason.py`;思考能力统一由 `chat_template +2025-10-24
- 🔥 新增RLAIF训练算法:PPO、GRPO、SPO(从0原生实现) - 新增断点续训功能:支持训练自动恢复、跨GPU数量恢复、wandb记录连续性 - 新增RLAIF数据集:rlaif-mini.jsonl(从SFT数据随机采样1万条);简化DPO数据集,加入中文数据 - 新增YaRN算法:支持RoPE长文本外推,提升长序列处理能力 - Adaptive Thinking:Reason模型可选是否启用思考链 - chat_template全面支持Tool Calling和Reasoning标签(`2025-04-26
- 重要更新 - 如有兼容性需要,可访问[🔗旧仓库内容🔗](https://github.com/jingyaogong/minimind/tree/7da201a944a90ed49daef8a0265c959288dff83a)。- MiniMind模型参数完全改名,对齐Transformers库模型(统一命名)。 - generate方式重构,继承自GenerationMixin类。- 🔥支持llama.cpp、vllm、ollama等热门三方生态。- 规范代码和目录结构。- 改动词表`为兼容第三方推理框架llama.cpp、vllm,本次更新需付出一些可观代价。本次更新不再支持「直接」加载25-04-26以前的旧模型进行推理。由于Llama位置编码方式与minimind存在区别,导致映射Llama模型后QK值存在差异
minimind2系列旧模型均经过权重映射+(微调训练)QKVO线性层校准恢复而来。
本次更新后将放弃对`minimind-v1`全系列的维护,并在仓库中下线。```
</details>
<details>
<summary> <b>More...</b> </summary>
**2025-02-09**
- 迎来发布以来重大更新,Release minimind2 Series。- 代码几乎全部重构,使用更简洁明了的统一结构。如有旧代码的兼容性需要,可访问[🔗旧仓库内容🔗](https://github.com/jingyaogong/minimind/tree/6e9cd28ef9b34a0a10afbdf6f59e65cb6e628efb)。
- 免去数据预处理步骤。统一数据集格式,更换为`jsonl`格式杜绝数据集下载混乱的问题。- minimind2系列效果相比MiniMind-V1显著提升。- 小问题:{kv-cache写法更标准、MoE的负载均衡loss被考虑等等}
- 提供模型迁移到私有数据集的训练方案(医疗模型、自我认知样例)。
- 精简预训练数据集,并大幅提升预训练数据质量,大幅缩短个人快速训练所需时间,单卡3090即可2小时复现!- 更新:LoRA微调脱离peft包装,从0实现LoRA过程;DPO算法从0使用PyTorch原生实现;模型白盒蒸馏原生实现。- minimind2-DeepSeek-R1系列蒸馏模型诞生!- minimind2具备一定的英文能力!
- 更新minimind2与第三方模型的基于更多大模型榜单测试性能的结果。
**2024-10-05**
- 为MiniMind拓展了多模态能力之---视觉
- 移步孪生项目[minimind-v](https://github.com/jingyaogong/minimind-v)查看详情!
**2024-09-27**
- 09-27更新pretrain数据集的预处理方式,为了保证文本完整性,放弃预处理成.bin训练的形式(轻微牺牲训练速度)。
- 目前pretrain预处理后的文件命名为:pretrain_data.csv。
- 删除了一些冗余的代码。
**2024-09-17**
- 更新minimind-v1-moe模型
- 为了防止歧义,不再使用mistral_tokenizer分词,全部采用自定义的minimind_tokenizer作为分词器。
**2024-09-01**
- 更新minimind-v1 (108M)模型,采用minimind_tokenizer,预训练轮次3 + SFT轮次10,更充分训练,性能更强。
- 项目已部署至ModelScope创空间,可以在此网站上体验:
- [🔗ModelScope在线体验🔗](https://www.modelscope.cn/studios/gongjy/minimind)
**2024-08-27**
- 项目首次开源
</details>
---
# 📌 快速开始
<details>
<summary>本人的软硬件配置(供参考)</summary>
* CPU: Intel(R) Core(TM) i9-10980XE CPU @ 3.00GHz
* RAM: 128 GB
* GPU: NVIDIA GeForce RTX 3090 (24GB) * 8
* Ubuntu==20.04
* CUDA==12.2
* Python==3.10.16
* [requirements.txt](./requirements.txt)
</details>
## 第0步
```bash
# 克隆仓库、安装依赖
git clone --depth 1 https://github.com/jingyaogong/minimind
cd minimind && pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
## Ⅰ 🚀 模型推理
### 1' 下载模型
在项目根目录:
# 方式1
modelscope download --model gongjy/minimind-3 --local_dir ./minimind-3
# 方式2
git clone https://huggingface.co/jingyaogong/minimind-3
### 2' CLI 推理
# 方式1:使用 Transformers 格式模型
python eval_llm.py --load_from ./minimind-3
# 方式2:基于 PyTorch 模型(确保./out目录下有对应权重)
python eval_llm.py --load_from ./model --weight full_sft
### 3'(可选)WebUI
```bash # 可能需要`python>=3.10`,安装 `pip install streamlit` # ⚠️ 须先将 transformers 格式模型文件夹复制到 ./scripts/ 目录下(例如:cp -r minimind-3
./scripts/minimind-3),web_demo 脚本会自动扫描该目录下包含权重文件的子文件夹,如不存在则报错 cd scripts && streamlit run web_demo.py ```
### 4'(可选)第三方推理框架
# ollama
ollama run jingyaogong/minimind-3
# vllm
vllm serve /path/to/model --served-model-name "minimind"
## Ⅱ 🛠️ 模型训练
注:提前确认 Torch 的可用后端
import torch
print(torch.cuda.is_available())
若你计划使用 CUDA 训练,建议先确认当前环境是否已正确识别 GPU。若 `cuda` 不可用,也仍可根据自身设备选择 `CPU` 或 `MPS` 运行,但训练速度与兼容性会有非常大的差异。如需安装或更换 PyTorch 版本,可参考
[torch_stable](https://download.pytorch.org/whl/torch_stable.html)
与[链接](https://blog.csdn.net/weixin_45456738/article/details/141029610?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%AE%89%E8%A3%85torch&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-2-141029610.nonecase&spm=1018.2226.3001.4187)
💡 检查点暂停续训
所有训练脚本均支持检查点保存。添加 `--from_resume 1` 参数后,即可自动检测并恢复训练进度:python train_pretrain.py --from_resume 1
python train_full_sft.py --from_resume 1
# ...
**断点续训说明:**
- 训练过程会自动在 `./checkpoints/` 目录保存完整检查点(模型、优化器、训练进度等)
- 检查点文件命名:`<权重名>_<维度>_resume.pth`(如:`full_sft_512_resume.pth`)
- 支持跨不同 GPU 数量恢复(自动调整 step)
- 支持 wandb 训练记录连续性(自动恢复同一个 run)
> 适合长时间训练或不稳定环境,无需担心训练中断导致进度丢失
cd trainer && python train_pretrain.py
> 训练后,将得到 `out/pretrain_*.pth` 作为输出权重(其中 `*` 为模型 dimension,默认为 `768`)
#### 2.2 指令微调(必须)
cd trainer && python train_full_sft.py
> 训练后,将得到 `out/full_sft_*.pth` 作为输出权重(其中 `full` 表示全参数微调)
#### 2.3 测试已训练模型(可选)
确保待测试的模型 `*.pth` 文件位于 `./out/` 目录下;也可直接前往[此处](https://www.modelscope.cn/models/gongjy/minimind-3-pytorch/files)下载我已训练好的 `*.pth` 权重。
python eval_llm.py --weight full_sft
> `--weight` 用于指定权重名称前缀,例如 `pretrain`、`full_sft` 等;更多参数可直接参考 `eval_llm.py`
注:其它须知
1、所有训练脚本均基于 PyTorch 原生实现,并支持多卡加速。 2、若你的设备有 `N (N > 1)` 张显卡,可通过以下方式启动单机 `N` 卡训练(DDP,也支持扩展到多机多卡):torchrun --nproc_per_node N train_xxx.py
3、可根据需要开启 wandb 记录训练过程。
```bash ... train_xxx.py --use_wandb ``` `2025` 年 `6` 月后,国内网络环境通常无法直连 WandB。MiniMind 当前默认转为使用 [SwanLab](https://swanlab.cn/) 作为训练可视化工具,其接口与 WandB
基本兼容;通常只需将 `import wandb` 替换为 `import swanlab as wandb`,其余调用方式基本无需改动。
Tokenizer介绍
第三方强大的开源模型例如 Yi、Qwen2、ChatGLM、Mistral、Llama 3 的 tokenizer 词表长度如下:| Tokenizer模型 | 词表大小 | 来源 |
|---|---|---|
| Yi | 64,000 | 01万物(中国) |
| Qwen2 | 151,643 | 阿里云(中国) |
| ChatGLM | 151,329 | 智谱AI(中国) |
| Mistral | 32,000 | Mistral AI(法国) |
| Llama 3 | 128,000 | Meta(美国) |
| MiniMind | 6,400 | 自定义 |
{"text": "如何才能摆脱拖延症?治愈拖延症并不容易,但以下建议可能有所帮助。"}
{"text": "清晨的阳光透过窗帘洒进房间,桌上的书页被风轻轻翻动。"}
{"text": "Transformer 通过自注意力机制建模上下文关系,是现代大语言模型的重要基础结构。"}
## Ⅲ SFT数据
`MiniMind-3` 当前主线 SFT 数据为 `sft_t2t.jsonl` / `sft_t2t_mini.jsonl`。相比更早期的 `sft_512 / sft_1024 / sft_2048` 方案,当前版本更强调:
- 统一模板;
- 更适合对话 + 思考标签 + Tool Calling 的混合训练;
- 尽量减少数据预处理分叉,降低复现成本。
其数据来源包括但不限于高质量指令跟随数据、公开对话数据、模型蒸馏合成数据,以及协议友好的开源数据集;在进入 `t2t` 主线前,会统一为当前仓库使用的多轮对话格式。当前主线中也包含大量合成数据,例如本人基于 `qwen3-4b` 合成的约 `10w` 条 `tool call` 数据,以及 `qwen3` 系列的 `reasoning` 数据等。
其中社区主要来源有:[匠数大模型数据集](https://www.modelscope.cn/datasets/deepctrl/deepctrl-sft-data)、[Magpie-Align](https://www.modelscope.cn/organization/Magpie-Align)、[R1-Distill-SFT](https://www.modelscope.cn/datasets/AI-ModelScope/R1-Distill-SFT)、[COIG](https://huggingface.co/datasets/BAAI/COIG)、[Step-3.5-Flash-SFT](https://huggingface.co/datasets/stepfun-ai/Step-3.5-Flash-SFT)
等。
公布版本会确保数据来源与处理链路符合对应开源协议的可传递性约束,并遵守 Apache-2.0、CC-BY-NC-2.0 等相关协议要求。
其中:
- `sft_t2t_mini.jsonl`:适合快速训练对话模型;
- `sft_t2t.jsonl`:适合完整复现主线版本;
- `toolcall` 能力已经并入主线 SFT 数据。
所有 SFT 文件数据格式均为(包含对话数据、Tool Use 数据)
```jsonl { "conversations": [ {"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好!"}, {"role": "user", "content": "再见"}, {"role":
"assistant", "content": "再见!
"} ] } { "conversations": [ {"role": "system", "content": "# Tools ...", "tools": "[...]"}, {"role": "user", "content": "把'你好世界'翻译成english"}, {"role":
"assistant", "content": "", "tool_calls": "[{\"name\":\"translate_text\",\"arguments\":{\"text\":\"你好世界\",\"target_language\":\"english\"}}]"},
{"role": "tool", "content": "{\"translated_text\":\"Hello World\"}"}, {"role": "assistant", "content": "Hello World"} ] } ```
## Ⅳ RL 数据
`MiniMind` 当前主线 RL 数据为 `dpo.jsonl`。数据抽样自 [DPO-En-Zh-20k](https://huggingface.co/datasets/llamafactory/DPO-En-Zh-20k)。
主线中会将这部分样本统一重组为当前仓库使用的偏好学习格式,用于奖励模型或偏好优化阶段训练;其中 `chosen` 表示更符合偏好的回复,`rejected` 表示相对较差的回复。
其中 `dpo.jsonl` 数据格式为
```json { "chosen": [ {"content": "Q", "role": "user"}, {"content": "good answer", "role": "assistant"} ], "rejected": [ {"content": "Q", "role":
"user"}, {"content": "bad answer", "role": "assistant"} ] } ```
除此之外,其他 RL 数据与 SFT 数据格式保持一致,通常是从 SFT 数据中按总长度和对话轮次筛选得到,并将最后一个 `assistant` 位置留空,供 rollout 阶段续写使用。
## Ⅴ MiniMind 训练数据集
> [!NOTE]
> 当前主线训练所需的核心数据集已开源,因此无需再自行预处理大规模数据集,避免重复性的数据处理工作。
MiniMind训练数据集下载地址: [ModelScope](https://www.modelscope.cn/datasets/gongjy/minimind_dataset/files) | [HuggingFace](https://huggingface.co/datasets/jingyaogong/minimind_dataset/tree/main)
> 无需全部clone,可单独下载所需的文件
将下载的数据集文件放到`./dataset/`目录下(✨为推荐的必须项)
```bash ./dataset/ ├── agent_rl.jsonl (86MB) ├── agent_rl_math.jsonl (18MB) ├── dpo.jsonl (53MB) ├── pretrain_t2t_mini.jsonl (1.2GB, ✨) ├──
pretrain_t2t.jsonl (10GB) ├── rlaif.jsonl (24MB, ✨) ├── sft_t2t_mini.jsonl (1.6GB, ✨) └── sft_t2t.jsonl (14GB) ```
注:各数据集简介
* `agent_rl.jsonl` --Agentic RL 主线训练数据,用于 `train_agent.py` 的多轮 Tool-Use / CISPO / GRPO 训练 * `agent_rl_math.jsonl` --Agentic RL 纯数学补充数据,适合带最终校验目标的多轮推理/工具使用场景(用于RLVR) * `dpo.jsonl` --RLHF阶段偏好训练数据(DPO) * `pretrain_t2t_mini`✨ --`minimind-3` 轻量预训练数据,适合快速复现(推荐设置`max_seq_len≈768`) * `pretrain_t2t` --`minimind-3` 主线预训练数据(推荐设置`max_seq_len≈380`) * `rlaif.jsonl`✨ --RLAIF训练数据集,用于PPO/GRPO/CISPO等强化学习算法训练 * `sft_t2t_mini.jsonl`✨ --`minimind-3` 轻量SFT数据(用于快速训练Zero模型),推荐设置`max_seq_len≈768`,其中已混入一部分 Tool Call 样本 * `sft_t2t.jsonl` --`minimind-3` 主线SFT数据,适合完整复现,其中同样已混入 Tool Call 样本 训练参数 `max_seq_len` 目前指的是 tokens 长度,而非绝对字符数。 本项目tokenizer在中文文本上大约`1.5~1.7 字符/token`,纯英文的压缩比在`4~5 字符/token`,不同数据分布会有波动。 数据集命名标注的“最大长度”均为字符数,100长度的字符串可粗略换算成`100/1.5≈67`的tokens长度。 例如: * 中文:`白日依山尽`5个字符可能被拆分为[`白日`,`依`,`山`,`尽`] 4个tokens; * 英文:`The sun sets in the west`24个字符可能被拆分为[`The `,`sun `,`sets `,`in `,`the`,`west`] 6个tokens “推荐设置”给出了各个数据集上最大tokens长度的粗略估计。 须知 `max_seq_len` 可以激进 / 保守 / 均衡地调整,因为更大或更小均无法避免副作用:一些样本短于 `max_seq_len` 后被 padding 浪费算力,一些样本长于 `max_seq_len` 后被截断语义。 在算力效率与语义完整性之间找到平衡点即可说明 & 推荐训练方案
* `minimind-3` 主线推荐采用 `pretrain_t2t` + `sft_t2t` + `rlaif/agent_rl` 的阶段式训练组合。 * 想要最快速度从0实现Zero模型,推荐使用`pretrain_t2t_mini.jsonl` + `sft_t2t_mini.jsonl` 的数据组合 * 推荐具备一定算力资源或更在意效果的朋友完整复现 `minimind-3`;仅有单卡GPU或更在意快速复现的朋友强烈推荐 mini 组合。 * 当前 `sft_t2t / sft_t2t_mini` 已经混入 Tool Call 数据,因此通常不需要再额外做一轮独立的 Tool Calling 监督微调。查看详细说明
Scaling Law 在小模型上往往会呈现出一些不同于大模型的现象。决定 Transformer 参数规模变化的核心参数,通常主要就是 `d_model` 和 `n_layers`: * `d_model`↑ + `n_layers`↓ -> 矮胖子 * `d_model`↓ + `n_layers`↑ -> 瘦高个 经典 Scaling Law 更强调训练数据量、参数量和训练步数的决定性作用,通常会弱化架构差异本身的影响;但在小模型区间,这个结论并不总是完全成立。MobileLLM 的一个核心观察是:在参数量固定时,深度往往比宽度更重要。也就是说,相比“宽而浅”的结构,“深而窄”的模型更容易学到抽象概念。例如当模型参数量固定在 `125M` 或 `350M` 时,`30~42` 层的狭长结构通常会优于 `12` 层左右的矮胖结构,在常识推理、问答、阅读理解等多个基准上都呈现出相近趋势。 这和 MiniMind 在训练过程中围绕 `d_model` 与 `n_layers` 做参数分配实验时观察到的现象是一致的。不过“深而窄”里的“窄”也有下限:当 `d_model < 512` 时,词嵌入维度过窄带来的劣势会明显放大,额外增加 layers 往往不足以完全弥补固定 `q_head` 下 `d_head` 偏小的问题。 相对地,当 `d_model > 1536` 时,继续增加层数往往比单纯继续加宽更划算,更容易带来更高的参数-效果收益。 作为参考,GPT-3 的参数设定如下: ≈1.57¥ | ≈1.10h
≈1.43¥ | ≈0.9h
≈1.17¥ | ≈1.1h
≈1.43¥ | | minimind-3-moe | 198M-A64M | ≈1.69h
≈2.20¥ | ≈1.54h
≈2.00¥ | ≈1.26h
≈1.64¥ | ≈1.54h
≈2.00¥ | ---
训练开销总结&预测
> `minimind-3` >> `pretrain_t2t_mini` + `sft_t2t_mini`单卡 `3090`,`1 epoch` 预计约 `2.31` 小时,成本约 `3.0` 元人民币
可从 0 训练出 `minimind-3 Zero` 对话模型。 > `minimind-3-moe` >> `pretrain_t2t_mini` + `sft_t2t_mini`
单卡 `3090`,`1 epoch` 预计约 `3.23` 小时,成本约 `4.2` 元人民币
可快速得到 `minimind-3-moe` 的基础对话版本。 > 以上均为估算值,仅用于快速感知训练门槛。
👶: 请介绍一下自己。
🤖️: 作为人工智能,我没有实际的生活,也没有自我意识,所以没有自己的生活。我被设计成能够帮助用户解答问题、提供信息、进行对话等。我的设计和功能是由计算机科学、机器学习、人工智能技术和算法所构建的,我通过编程和算法实现。
👶: 推荐一些杭州的特色美食吧。
🤖️: 杭州有很多美味的特色美食,比如鸡肉串、鳗鱼头、水煮鱼、豆腐脑等。这些美食都非常美味,有着独特的风味和口感,绝对是值得一试的美食。
👶: 请为我讲解“大语言模型”这个概念。
🤖️: 大语言模型是一种人工智能技术,它使用大量的文本数据来训练模型,然后在不断的迭代中不断优化模型。它的目标是根据输入的数据来生成符合特定需求的文本,这些文本可以是任何你感兴趣的主题。
👶: Introduce the history of the United States, please.
🤖️: 您提到的“Introok's the believeations of theument." 这个名字来源于中国古代的"groty of of the change."
尽管该版本已经具备基础对话能力,但事实知识与泛化效果仍较有限;它更适合作为 Zero 训练路线可行性的早期参考。
Zero 模型权重保存为 `full_sft_zero_768.pth`(见下文 MiniMind 模型文件链接),如有兴趣可下载体验其对话效果。
---
## Ⅱ 主要训练(必须)
> 所有训练脚本均 `cd ./trainer` 目录执行
### 1' 预训练 (Pretrain):
LLM 首先要学会的是先把尽可能多的基础知识和语言规律吸收到参数里。只有这一步打稳了,模型后面才有能力去理解问题、组织表达,并逐步形成像样的生成能力。预训练做的事情,本质上就是让模型先埋头读大量文本,例如 Wiki
百科、新闻、书籍、对话语料等,从中学习事实知识、语言模式以及上下文之间的统计关系。这个阶段通常是“无监督”的:人类不需要逐条告诉模型哪里对、哪里错,而是让它自己从海量文本里总结规律,逐步建立起对世界知识和语言结构的内部表征。
更直白地说,模型在这一阶段的核心目标就是**学会高质量地词语接龙**。例如输入“秦始皇”,它要能够继续生成“是中国历史上的第一位皇帝”这类符合语义与常识的后续内容。
# 方式1
torchrun --nproc_per_node 1 train_pretrain.py # 1即为单卡训练,可根据硬件情况自行调整 (设置>=2)
# 方式2
python train_pretrain.py
> 训练后的模型权重文件默认每隔`save_interval步`保存为:`pretrain_*.pth`(*为模型具体dimension,每次保存时新文件会覆盖旧文件)

> `768dim` 配置在预训练阶段的 loss 曲线
# 可对预训练结果做简单测试:
python eval_llm.py --weight pretrain
💬: 为什么天空是蓝色的
🧠: 天空之所以看起来是蓝色的,主要是因为太阳光进入大气层后,短波长的蓝光更容易被空气分子散射,因此人眼从各个方向接收到的蓝光会更多。
💬: 解释什么是机器学习
🧠: 机器学习是人工智能的一个重要分支,它通过数据训练模型,使系统能够自动学习规律,并在分类、预测、推荐、自然语言处理等任务中持续改进效果。
### 2' 有监督微调 (Supervised Fine-Tuning):
SFT 并不只是把模型调成“更会聊天”,它同样可以继续向模型中灌入新的知识、行为模式和回答风格。尤其是像 MiniMind 当前主线这样体量达到 `14GB` 的 SFT 数据,本身就已经不只是简单的格式对齐,而更接近一种带有 `mid training` 性质的持续强化过程。如果把预训练理解为先让模型广泛地读书、积累基础语言能力,那么 SFT 更像是在高质量、更有目标的数据上继续深加工。
一方面,它会让模型适应多轮对话、问答、工具调用和思考标签等交互形式;另一方面,它也会继续把特定知识分布、任务模式和助手风格压进参数里。具体到 MiniMind 里,SFT 阶段会让模型适应当前仓库使用的多轮对话模板。模型会逐渐理解 `user / assistant / system / tool` 等角色结构,同时进一步强化指令跟随、稳定回复和任务完成能力。
当前训练时会对指令和回答长度做截断控制,主要是为了兼顾显存占用与训练效率;如果后续需要更长上下文,只需要继续准备少量长样本做增量微调即可。在推理时通过启用 YaRN 外推,可以免训练地将上下文长度扩展到 2048 及以上。
# 方式1
torchrun --nproc_per_node 1 train_full_sft.py
# 方式2
python train_full_sft.py
> 训练后的模型权重文件默认每隔`save_interval步`保存为: `full_sft_*.pth`(*为模型具体dimension,每次保存时新文件会覆盖旧文件)

> `768dim` 配置在 SFT 阶段的 loss 曲线
# 可对SFT结果做简单测试:
python eval_llm.py --weight full_sft
💬: 解释什么是机器学习
🧠: 机器学习是人工智能的核心技术之一,通过算法让计算机从数据中学习规律,并持续改进预测或决策效果,常见应用包括推荐系统、图像识别、语音识别和自然语言处理。
💬: 推荐一些中国的美食
🧠: 例如北京烤鸭、兰州拉面、四川火锅、广东早茶、小笼包和麻婆豆腐等,这些美食分别代表了不同地区的风味特点,也很适合作为了解中国饮食文化的入门选择。
## Ⅲ 其它训练(可选)
> 所有训练脚本均 `cd ./trainer` 目录执行
### 3' 知识蒸馏 (Knowledge Distillation, KD)
知识蒸馏大体可以分成黑盒和白盒两类,MiniMind 当前主线两种思路都有涉及,只是侧重点不同。* 黑盒蒸馏:更常见,也更贴近当前主线的实际做法。严格来说,它本质上仍然是面向教师输出结果的监督微调,也就是基于硬标签继续训练;只是随着 LLM 的流行,这类“对着强模型输出做 FT”的做法也逐渐被广义地归入了蒸馏范畴,因此通常被称为黑盒蒸馏。
它重点学习的是答案、风格和行为模式,学生模型只能看到“老师说了什么”,却看不到老师内部是如何做出这个判断的。像 `DeepSeek R1`、`Qwen3` 的高质量回答,以及 `tool call`、`reasoning`、思维链等数据,都可以看作黑盒蒸馏信号;MiniMind 当前主线 `full_sft` 数据里,其实已经混入了相当一部分这样的思路。
* 白盒蒸馏:更进一步,不只学习教师给出的最终输出,还去学习教师在 token 分布层面的偏好。相比黑盒蒸馏,它额外利用了教师模型输出层更细粒度的分布信息,因此学生模型学到的不只是“标准答案”,还包括教师在候选 token 之间的相对倾向。对应到
`train_distillation.py`,当前实现是在已经完成 SFT 的权重基础上,继续用教师模型提供的分布信号来训练学生模型,因此更适合作为理解 MiniMind 蒸馏流程的参考实现。
黑盒蒸馏本质上等价于对 teacher 生成答案做监督微调:
\mathcal{L}_{blackbox} = \mathrm{CE}(y_{teacher}, p_{student})
白盒蒸馏则通常在监督损失之外,再额外拟合教师分布:
\mathcal{L}_{whitebox} = \alpha \mathcal{L}_{CE} + (1-\alpha) T^2 \mathrm{KL}(p_t^T \parallel p_s^T)
仓库中提供的 `train_distillation.py` 更适合作为理解白盒蒸馏流程的参考实现:它完整展示了教师/学生双模型加载、`CE + KL` 混合损失、温度缩放、MoE 与 dense 组合蒸馏,以及断点续训和分布式训练等关键细节。
# 方式1
torchrun --nproc_per_node 1 train_distillation.py
# 方式2
python train_distillation.py
### 4' LoRA (Low-Rank Adaptation)
LoRA 是一种常见的参数高效微调(Parameter-Efficient Fine-Tuning, PEFT)方法。相比全参数微调,它只更新少量新增参数,而保留原始模型主体权重不变,因此训练成本更低,也更适合做垂直场景适配。它的核心思想是在原有权重矩阵旁引入低秩增量分支,仅训练这部分低秩参数,从而用较小代价完成能力迁移。
相关实现可见 `model_lora.py` 和 `train_lora.py`,整个流程均为纯手写实现,不依赖第三方封装。
# train_lora.py 在 CPU 上通常也能比较轻快地完成
# 方式1
cd trainer && torchrun --nproc_per_node 1 train_lora.py
# 方式2
cd trainer && python train_lora.py
> 训练后的模型权重文件默认每隔`save_interval步`保存为: `lora_xxx_*.pth`(*为模型具体dimension,每次保存时新文件会覆盖旧文件)
LoRA 很适合处理“如何在尽量保留通用能力的前提下,让模型快速适应私有领域或垂直场景”这类问题。例如基础模型医学知识不足时,就可以在原有模型之上叠加一层面向医疗场景的 LoRA 权重,以较小代价获得更好的领域表现。通常只需要准备同样的多轮对话格式数据,放置到
`lora_xxx.jsonl`,再从仓库根目录执行 `cd trainer && python train_lora.py`,即可得到新的 `LoRA` 模型权重。
例1:垂域数据
```jsonl {"conversations": [{"role": "user", "content": "请问颈椎病的人枕头多高才最好?"}, {"role": "assistant", "content": "颈椎病患者选择枕头的高度应该根据..."}]}
{"conversations": [{"role": "user", "content": "请问xxx"}, {"role": "assistant", "content": "xxx..."}]} ```
例2:自我认知数据
{"conversations": [{"role": "user", "content": "你叫什么名字?"}, {"role": "assistant", "content": "您好,我名叫 MiniMind,是由 Jingyao Gong 开发的人工智能助手。我可以帮助你解决各种问题,包括翻译、推荐内容等等。
"}]}
{"conversations": [{"role": "user", "content": "你是谁"}, {"role": "assistant", "content": "您好,我是 MiniMind,由 Jingyao Gong 创建。我的主要职责是提供准确的回答和帮助。"}]}
此时可将【基模 + LoRA 权重】组合使用,从而在保留基础模型通用能力的同时,增强特定领域表现。训练完成后也可以通过 `eval_llm.py` 做简单测试。
# 注意:weight参数指定基础模型类型,需与train_lora训练时使用的基础模型保持一致
python eval_llm.py --weight full_sft --lora_weight lora_medical
👶: 我最近经常感到头晕,可能是什么原因?
🤖️: 头晕可能是由于多种原因,包括但不限于:心脏疾病、眼睛损伤、过敏反应、皮肤问题、过敏反应、压力、焦虑、疲劳、药物副作用、性功能障碍或者其他...
python eval_llm.py --weight full_sft --lora_weight lora_identity
👶: 你和openai是什么关系?
🤖️: 我是 MiniMind,一个由 Jingyao Gong 开发的人工智能助手。我通过自然语言处理和算法训练来与用户进行交互。
PS:如果有更充足的数据,也可以直接做 `full_sft` 全参微调;不过这通常需要更谨慎地混合通用数据与领域数据,否则很容易因为过拟合垂域样本而损失模型原有的通用性。
> `LoRA` 权重可合并回基础模型并导出为新的完整模型权重,可使用 `scripts/convert_model.py` 中的 `convert_merge_base_lora`:
cd scripts && python convert_model.py
### **5' 工具调用 & 自适应思考**
`2026-03` 起,仓库移除了独立的 `train_reason.py`。
当前版本不再单独维护 `reason_*.pth` 权重,而是统一通过 `chat_template`、`
其中 `tools` 挂在 `system` 消息上,`tool_calls` 挂在 `assistant` 消息上;训练时再由 `chat_template` 自动展开为 `<tool_call>...</tool_call>` 与 `<tool_response>...</tool_response>` 片段,因此现在可以直接学习原生 tool call 格式。
Tool Calling 的 chat template 已统一支持解析为:
```text
<tool_call>{"name": "...", "arguments": {...}}</tool_call>
<tool_response>{...tool result...}</tool_response>
也可以直接通过 `eval_toolcall.py` 做简单测试:
python eval_toolcall.py --weight full_sft
💬: 现在几点了?🧠: <tool_call>{"name": "get_current_time", "arguments": {"timezone": "Asia/Shanghai"}}</tool_call> 📞 [Tool Calling]: get_current_time ✅ [Tool
Called]: {"datetime": "2026-03-15 17:18:22", "timezone": "Asia/Shanghai"} 🧠: 现在是2026年3月15日17时18分22秒。
#### 5.2 Adaptive Thinking
`minimind` 将显式思考能力统一到了模板层,这也和当前很多主流大模型的模板设计保持一致:
- `open_thinking=0`:默认注入空的 `# 测试回答
python eval_llm.py --load_from ./minimind-3 --open_thinking 1
OpenAI-API-SDK 用法:
```python response = client.chat.completions.create( model="minimind", messages=[{"role": "user", "content": "你是谁?"}], # ...
extra_body={"chat_template_kwargs": {"open_thinking": True}} # 思考开关 ) ```
注:当前同时开启 Tool Call 与显式思考时,模型通常并不太会稳定地输出思考过程。原因在于现阶段训练数据里还缺少“reasoning 与 tool call 同时存在”的联合蒸馏样本,因此模型尚未充分学会这两种能力的协同表达。
## Ⅳ 强化学习(可选)
在 LLM 的后训练实践中,常见的强化学习路径主要有两条:
1. **基于人类反馈的强化学习 (Reinforcement Learning from Human Feedback, RLHF)**
- 通过**人类**对模型输出的偏好进行评价来训练模型,使其生成更符合人类价值观和偏好的内容。
2. **基于AI反馈的强化学习 (Reinforcement Learning from AI Feedback, RLAIF)**
- 使用**AI模型**或其他可自动验证的机制来提供反馈,而不直接依赖人类标注。
- 这里的“AI feedback”在广义上也可以扩展到规则奖励、Ground Truth 校验、代码解释器、环境反馈等自动化信号。
| 类型 | 裁判 | 优点 | 缺点 |
|-------|----|-----------|