先看下效果:
上面这个模型是在MAC Pro 2.6GHz 6c i7(16GB DDR4)上,使用510 条训练集与 90 条验证集,CPU 训练 2000 步。总耗时约 19.78 分钟(1186.95s),得到。
项目依赖:
项目结构:
文末有完整可执行的源码并附step by step操作手册,
欢迎各路大佬检查作业。
自从DeepSeek开启全民AI的浪潮,每个人都直接或间接用过大模型吧。但作为技术人,你了解大模型是什么吗?你了解大模型的架构吗?你训练过大模型吗?你从0到1训练过一个大模型吗?
自从DeepSeek开启全民AI的浪潮,我们每个人都已成为大模型的使用者。但作为技术人,我们是否曾停下来思考:
- 你了解大模型是什么吗? —— 是时候揭开它“黑箱”的神秘面纱。
- 你了解它的内部架构吗? —— 让我们深入Transformer的每一个模块,看清其脉络。
- 你训练过大模型吗? —— 告别简单的微调,体验从零开始塑造一个模型。
- 你从0到1训练过一个大模型吗? —— 这,正是本项目要带你完成的终极挑战。
本项目旨在打破“训练大模型需要昂贵GPU”的迷思,在一台普通CPU电脑上,于一节课(45分钟)内,带你完整实现一个能生成“相关且可读”答案的中文小模型。这不仅是一次技术复现,更是一次从“使用者”到“创造者”的身份转变。
训练什么样的大模型?
一个学习/教学用的小模型,可以用CPU训练,可以在1个小时内训练并演示结束。个人情况千差万别,就以教学这个45分钟课堂场景,来设计并从0到1实现、训练并演示这个大模型。
- 现实约束:课堂时间有限;学生电脑配置不一;模型输出需为“可用答案”,而非随机乱码。
- 核心成果:在 Mac Pro(2.6GHz 6核 i7, 16GB内存)上,使用510条训练数据集与90条验证数据集,仅用19.78分钟(约1186.8秒)完成2000步训练,获得参数量为 3,368,192 的中文GPT模型。经测试,模型生成的中文答案相关且可读,成功回答了“从0到1训练”的挑战。
怎么设计的?
从“是什么”到“如何构建”。
本项目采用业务主流的GPT架构。
- 整体架构:本项目是基于Decoder-only的Transformer(因果语言模型),使用下三角掩码确保每次只关注历史信息,这正是GPT系列模型能够生成连贯文本的核心。
- 核心模块(带你亲手构建的组件):
- 嵌入与输出层权重共享:减少参数量,统一表示空间。
- 自注意力机制:Q/K/V线性变换 → 点积注意力 → 投影输出。
- 前馈网络:线性 → SiLU激活 → 线性。
- 归一化:使用更轻量的RMSNorm,提升训练稳定性。
- 位置编码:采用RoPE(旋转位置编码),增强模型对序列长度的泛化能力。
- 关键代码位置:
- 因果掩码与前向传播:
src/model.py:95–103 - RoPE实现:
src/model.py:18–31 - 自注意力前向:
src/model.py:41–58 - 残差块:
src/model.py:81–84
为什么这么强?
普通CPU?训练不到20分钟?训练出来的模型还是可用的?
这肯定是有故事的。
项目核心亮点:
- 极致轻量化:采用
n_layer=4, n_head=4, n_embd=256, seq_len=128 的小模型配置,大幅降低计算与内存开销。 - 权重共享:嵌入层与输出层共享权重(
src/model.py:93–94),减少参数的同时提升表示一致性。 - 现代组件组合:RoPE + RMSNorm,借鉴现代大语言模型的高效设计。
- 数据与分词解耦:外置
jsonl数据与tokenizer.json词表,无需修改代码即可更换数据或词表。 - 纯CPU友好训练:通过梯度累积、学习率预热与余弦退火、线程控制、量化推理等技术,实现在普通CPU上的高效训练。
- 答案可用性保障:通过目标对齐、推理约束、输出清理与提示词规范化,形成从训练到推理的质量闭环。
怎么做到的?
“原因”都藏在这些技术实现细节里。原理都是Transfer,都是GPT,大家都一样,没啥好讲的。
- 参数量计算(含权重共享):
- 公式:
总参数 = V*d + L*(12*d² + 11*d) + d - 其中:
V=824(词表大小),d=256(嵌入维度),L=4(层数) - 计算结果:3,368,192,与代码统计一致。
- 答案质量保障:
- 首步屏蔽PAD/BOS/UNK等无效标记,前几步屏蔽EOS,避免空答或过早结束。
- 提示词规范化:去除中文空格,确保与训练模板匹配。
- 输出清理:剔除开头标点与空白,提升可读性。
- 停止词与重复惩罚:控制输出冗余与循环。
- 目标对齐:训练时仅对“答案”部分计算损失,忽略问题部分(
src/data.py:24–31)。 - 推理约束:
- 乱码防御:使用Hugging Face ByteLevel BPE,并显式设置字节级解码器。
- CPU训练效率优化:
- 梯度累积:
batch_size=16, micro_batch=4(有效批大小64)。 - 学习率策略:线性预热10% + 余弦退火。
- 线程控制:
torch.set_num_threads(os.cpu_count())。 - DataLoader单线程(macOS下更稳定)。
- 训练后动态量化,生成更快的CPU推理权重。
怎么做?
想不想自己亲自训练一个中文大模型?
来吧,来完成你的第一次“从0到1”。
现在,让我们一起动手,回答最初的挑战。跟随以下步骤,你将亲手完成一次完整的大模型训练。
- 安装依赖:
bash
python -m pip install-r requirements.txt
- 构建分词器:
bash
python -m src.build_tokenizer
- 核对配置(
config.yaml):- 确保
data.train_path 和 data.val_path 指向正确数据文件。 tokenizer.type 为 hf_tokenizers,tokenizer.path 为 tokenizer/tokenizer.json。- 课堂演示建议
training.max_steps: 1500–2000。
- 开始训练(CPU):
bash
python -m src.train
- 训练日志将显示评估损失与累计时间,结束后模型保存于
checkpoints/last.pt 和 quantized.pt。
5. 验证大模型:
- 问题1:
bash
python -m src.infer --prompt"什么是注意力机制?"--ckpt checkpoints/last.pt --temperature0.0--show_label
- 问题2:
bash
python -m src.infer --prompt"解释蒸馏水与纯水区别?"--ckpt checkpoints/last.pt --temperature0.0--show_label
- 若输出过长,可使用
--stop_strings "。" ";" "\n" 添加停止词。
为什么用CPU训练?
- 计算可控:注意力复杂度为序列长度的平方,小模型与短序列使CPU在课堂时间内完成训练成为可能。
- 结果可复现:固定随机种子、统一数据与配置,确保不同学生设备上的实验流程一致。
- 教学友好:代码结构紧凑,模块清晰,便于讲解与定位问题。这正是理解大模型“是什么”和“如何构建”的最佳路径。
怎么变得更强?
- 扩充中文教学问答数据至600-800条,提升模型回答不同问题的稳定性。
- 实现小步数增量训练与自动化A/B测试,仅在质量提升时更新默认权重。
- 适配更广泛的设备与数据,例如通过SentencePiece或更大词表增强对口语及专业术语的覆盖。
相关资料
现在,你可以自信地回答开头的问题了。从这里开始,你不只是大模型的使用者,更是一名实践者。
- 代码与完整说明(GitHub,含权重/LFS):https://github.com/helloworldtang/GPT_teacher-3.37M-cn
- 代码镜像(Gitee,权重外链):https://gitee.com/baidumap/GPT_teacher-3.37M-cn
- 模型权重与配置(Hugging Face):https://huggingface.co/GPTcn/GPT_teacher-3.37M-cn
大家有没有在想,站在业务生产大模型的视角看,上面这个过程处于生态链的哪个位置?
先看概览图:
现代大模型的工业化生产是一个精密的多阶段pipeline,如上图所示。理解我们所处的位置,能更好地看清项目的价值与边界。
- 预训练(Pretraining):在海量、低质量的互联网原始文本上,以“预测下一个词”为目标,耗费数千GPU月训练出具备基础语言和世界知识的基座模型(如 GPT、LLaMA)。这是我们通常意义上“从零训练”的起点,但成本极高。
- 监督微调(Supervised Finetuning):在高质量的指令-回答示范数据上(数万至数十万条),对基座模型进行微调,使其学会遵循指令、扮演助手角色。产出SFT 模型(如 Vicuna)。
- 奖励建模(Reward Modeling):通过人类对模型多个回答的偏好进行比较,训练一个奖励模型,用以量化“好回答”的标准。
- 强化学习(Reinforcement Learning):利用奖励模型,通过强化学习(如PPO)进一步优化SFT模型,使其输出能持续最大化奖励,从而与人类复杂偏好对齐。产出如 ChatGPT、Claude 等高级对话模型。
我们在哪?本次完整实现了从“基座模型”到“SFT 模型” 的从零到一构建过程。
- 我们做了什么:我们没有使用现成的万亿语料基座模型,而是将“预训练”与“监督微调”两个阶段压缩合一。我们使用高质量的指令数据,直接从随机初始化的权重开始,训练一个具备基础问答能力的微型SFT模型。
- 我们没做什么:我们跳过了工业化流程中依赖人类反馈的奖励建模与强化学习阶段。这使得我们的模型能力边界清晰:它能根据指令生成相关回答,但尚未与人类的复杂偏好进行深度对齐。