本文目录19 个章节
核心目标:不依赖任何高层黑盒库(如 HuggingFace
transformers或tokenizers),纯使用 Python + PyTorch 从底层字节流和矩阵运算出发,端到端亲手实现 Byte-Level BPE 分词器、现代 Transformer 架构 (LLaMA/Qwen 风格)、高性能二进制数据流水线、混合精度预训练引擎,并最终在单张消费级显卡(或苹果芯片/CPU)上完整训练并运行一个能流利自回归生成的 0.04B (约 3600 万参数) 语言模型。
💡 本教程的教学理念与比喻体系
为了让零基础新人也能毫不费力地吃透底层原理,全书采用了一套高度直观、前后连贯的生活化比喻体系:
| 技术模块 | 对应现实生活比喻 | 比喻核心洞察 |
|---|---|---|
| 0.04B 参数量 | 调音台上的 3600 万个微小旋钮 | 训练就是顺着梯度的方向,把这 3593 万个旋钮微调到演奏和谐诗韵的位置 |
| Byte-Level BPE | 化学元素周期表与分子合成 | 256 个基础字节是不可摧毁的基础原子(零 OOV),高频相邻原子化合成大分子(如 [霜。]) |
| RMSNorm | 深山传话的声音电平平衡器 | 抛弃冗余的均值运算,仅用均方根把每层信号能量归一化到标准刻度 |
| RoPE 位置编码 | 每位舞者手腕上的旋转时钟 | 位置不靠生硬的工牌,旋转时钟内积的夹角只由相对距离 决定 |
| SwiGLU 门控 | 带有智能感应龙头的双通道自来水管 | 一根管道承载内容,另一根根据语义平滑控制阀门开度 () |
| GQA 注意力 | 自习室里 8 名提问学生共享 2 套参考书 | 4 分组查询,成倍砍掉 KV-Cache 显存带宽,表达多样性完好无损 |
| 内存映射 Pipeline | 图书馆索引借阅卡 vs 随身大背包 | 数据老老实实呆在 SSD 磁盘,用借书卡按需即时翻阅,物理内存零压力 |
| KV-Cache | 秘书手里的便签条 | 杜绝失忆金鱼反复从头重读文章的 灾难,新词只查历史便签条 |
| 采样解码参数 | 注入大脑的酒量刻度与格律约束 | 灵动吟诗,--rhythm 5/7 状态机强约束五言七言对仗,绝无单字乱跳 |
🎯 任务背景、数据源结构与全生命周期工程期望
1. 任务背景与核心挑战
本项目旨在完全从零手搓一个可完整复现的垂类古典诗词大模型。不同于直接调用现成开源大模型进行微调,本项目要求从最底层的 Byte-BPE 分词、Transformer 算子手写、双轨数据管线治理,直到预训练、SFT 对齐与自回归推理全部自主实现。
在此过程中,古典诗词短文本带来了一个非常特殊的工业级难题——高密度元数据危机:
- 通用长文本(如网页与论文):正文长达数千 Token,标题/作者等元数据占比不足 ,直接混拼预训练影响极小;
- 古典绝句短文本:五言绝句正文仅 20 字,而标题、作者、朝代长达 8~15 字,元数据占篇幅高达 35% ~ 45%!
- 若按常规方式裸拼,0.04B 小模型会产生严重的“先验走捷径偏置”,把参数容量全浪费在死记硬背作者名字上,并在生成正文时严重外泄特殊标记。本项目采用 “8 特殊 Token 原子保护 + 标签 Loss Mask (-100) + 25% Metadata Dropout” 三位一体方案,彻底解决该难题。
2. 数据源全景档案 (Dataset Profile)
- 原始数据源:中华古典诗词数据库(聚合 484 个古典名家诗库
base.json,共计 476,329 首原始诗词,跨越先秦、两汉、魏晋、唐宋至明清全历史时段)。 - 三阶段工业级数据净化漏斗:
- 格式与编号清洗:正则剥离“(其一)”、“卷xx”等排版标记,过滤残损占位符(
□、〇),清洗 15,993 首残缺杂质; - MinHash / SimHash 严格去重:清除 2,058 首同名同文重录篇目;
- 字数律格质检:确保每句诗为 4~8 个纯净汉字,正文总行数 。
- 格式与编号清洗:正则剥离“(其一)”、“卷xx”等排版标记,过滤残损占位符(
- 提纯后资产清单:
- 核心主数据:
data/poetry_meta.jsonl(460,336 首纯净诗篇,29,013,877 纯汉字,单条格式{"title": "...", "author": "...", "dynasty": "...", "content": "..."}),同时驱动预训练与 SFT 微调; - 词表训练专用文本:
data/raw.txt(83.89 MB,剥离元数据的纯诗正文,专供 BPE 词表统计字词合并频次,杜绝元数据标签污染词表); - 打包二进制数据流:
train_tokens.bin(59.37 MB, 31,126,208 Tokens) +train_labels.bin(59.37 MB, 带 -100 前缀掩码),验证集各占 5%。
- 核心主数据:
3. 历史版本演进与架构选型说明
| 架构版本 | 词表大小 | 隐藏层 / 层数 | 总参数量 | 典型吞吐 | 显存占用 | 历史定位与决策原因 |
|---|---|---|---|---|---|---|
| 0.1B 历史原型版 | 8,192 | 768 / 12层 | 82.3M | ~3,100 tok/s | ~3.8 GB | 早期探索原型(现已归档)。在 3100 万 Token 语料下参数量偏大,接近 Chinchilla 过拟合红线,且在轻薄本/核显上耗时翻倍。 |
| 0.04B 黄金标准版 ⭐ | 4,096 | 512 / 12层 | 35.9M | ~7,000 tok/s | ~1.8 GB | 全书官方唯一主线标准。参数与语料呈 1 完美饱和配比,收敛速度翻倍,431MB AdamW 状态对任意消费级显卡极度友好。 |
[!NOTE] 关于历史遗留权重的清理说明: 早期探索产生的旧版 0.1B 权重(
checkpoints/下约 3GB 文件)以及修复 Double-Shift Bug 之前的早期异常跑次(如model_step_500.pt,model_step_2000.pt)已全部归档清理。当前工程目录以checkpoints_0.04b/下经完整验证的权重为唯一基准。
4. 全生命周期阶段性期望指标 (Target Milestones)
| 阶段 / 模块 | 核心执行脚本 | 输入与产出资产 | 耗时期望 | 关键指标期望 | 核心行为预期 |
|---|---|---|---|---|---|
| 分词器构建 | scripts/train_tokenizer_fast.py | raw.txt tokenizer.json | 分钟 | 词表 4,096;孤立标点 | 8 个特殊 Token 原子保护,汉字覆盖率 98.81% |
| 二进制打包 | scripts/prepare_data.py | poetry_meta.jsonl train_tokens/labels.bin | 秒 | 有监督 Token 率 ,掩码率 | 前缀元数据全部填 -100,25% 样本触发 Metadata Dropout |
| 预训练收官 | scripts/run_train.py | train_tokens.bin model_step_1000.pt | 小时 | 1000 步 (1.0 Epoch):Loss ,PPL ,Val Loss | 掌握古汉语词法与韵律,正文生成零元数据标签外泄 |
| SFT 指令对齐 | scripts/run_sft.py | data/sft_data.json model_sft.pt | 分钟 | 300 步:Loss ,PPL | 摆脱 AI 假客套,精准理解人类口语提问,优雅输出 <eos> |
| 自回归推理 | scripts/run_chat.py | model_sft.pt 终端实时对话交互 | 实时流式 | 约束解码五言/七言工整率 100% | 支持命题作诗、风格摹写、意象创作、自由续写 |
📖 完整教材目录大纲与直达链接
第 00 章|0.04B 模型规格设计与新手直觉建立
- 0.1 新手启航:用生活比喻看透大模型核心概念(调音台旋钮、乐高积木、木工工作台显存模型)
- 0.2 0.04B 模型架构超参数配置表(词表 4096、512 维、12 层、SwiGLU 1408 维、GQA 8Q/2KV)
- 0.3 数学推导:这 3593 万参数究竟藏在哪里?(逐层计算量与 Weight Tying 共享参数)
- 0.4 新手问答:喂多少数据才能把小模型训聪明?(Chinchilla 定律与 46 万首纯诗语料的完美饱和)
- 0.5 学习心态与路线图导航
第 01 章|从零实现 Byte-Level BPE 分词器
- 1.1 新手直觉:传统分词的死局与 BPE 的天才破局(词级 OOV 噩梦 vs 字符级序列膨胀)
- 1.2 BPE 算法实战演示:纸上推演 3 分钟(通过玩具数据手工推演最高频 Pair 合并)
- 1.3 预分词正则:为什么在合并前必须用“切菜刀”?(标点吸附正则 Fused Punctuation,彻底消灭孤立标点)
- 1.4 纯 Python 手写 BPE Tokenizer 完整实现(特殊标记、基础 256 字节、倒排索引增量合并、序列化保存与加载)
- 1.5 工业级实战进阶:结构化特殊 Token 与原子保护机制 (避坑指南 1)(防止特殊标记被 BPE 撕裂为字节碎片)
- 1.6 动手试炼:验证分词器的无损还原能力(4096 词表实测抽检:标点占比暴跌至 0.53%)
第 02 章|从零手写现代 Transformer 架构 (构建 0.04B 思考中枢)
- 2.1 现代四大核心算子拆解与新手比喻
- RMSNorm(音量自动平衡器)
- RoPE(手表指针相对距离法)
- SwiGLU(双通道智能特征阀门)
- GQA(8Q : 2KV 分组查询注意力)
- 2.2 组装 0.04B 现代语言模型核心代码(
TransformerBlock与MiniLLaMAForCausalLM) - 2.3 架构验证:出厂体检与精确参数量核算 (35,926,528 参数)
- 🌟 第 02 章数学专题|从高中数学直通现代 Transformer 底层推导(向量点乘、复数旋转、欧拉公式、独立方差推导 、极大似然交叉熵)
第 03 章|语料预处理与高性能二进制数据流水线
- 3.1 新手必读:数据流水线的两大“致命陷阱”(在线分词导致 GPU 饥饿、全读进内存导致 OOM)
- 3.2 工业界解法:离线预加工与“图书借阅卡”机制(
uint16压缩存储、np.memmap零内存压力按需调页) - 3.3 核心解密:工业级统一因果对齐规范(输入与标签同构对齐,移位操作有且仅在 Model 内部执行)
- 3.4 数据特点深度剖析:为什么短文本语料中元数据是剧毒?(五言绝句元数据占近 40%,极易诱发模式坍塌)
- 3.5 三大可选方案权衡与决策矩阵(纯文本预训练+SFT vs 特殊 Token+Loss Mask vs 自然百科包装)
- 3.6 避坑指南 2:三大核心陷阱(双重位移 Bug 根治、元数据 Loss Masking
-100、前缀依赖与 25% Metadata Dropout) - 3.7 离线打包与零拷贝数据加载器实操(
prepare_data.py与src/dataset.py双流二进制加载)
第 04 章|工程级预训练引擎与训练优化实战
- 4.1 新手直觉:Loss 与困惑度 (PPL) 的“多选题考试”比喻(从 4096 瞎蒙到 7 个精准候选)
- 4.2 条件预训练 Loss Masking 计算图原理(
ignore_index=-100实现前缀反向零梯度隔离) - 4.3 优化器配置:修剪盆栽的“精细化修剪法”(2D 矩阵做 Weight Decay,1D 归一化参数绝对不衰减)
- 4.4 学习率调度:热身与入库 (Warmup + Cosine)
- 4.5 工业级速度与显存“双保镖”(AMP 混合精度与梯度累积大 Batch 模拟)
- 4.6 完整预训练引擎源码:
src/trainer.py(断点保存与平滑续训)
第 05 章|自回归推理与 KV-Cache:让模型像人类一样流畅思考
- 5.1 什么是自回归生成?从“成语接龙”讲起
- 5.2 朴素推理的致命陷阱:失忆金鱼的 灾难
- 5.3 破局之刃:手把手教你理解 KV-Cache 的“便利贴记忆法”(单序列仅 6MB 极简显存)
- 5.4 采样策略逐行精讲:温度调节、Top-P 为什么需要移位操作?
- 5.5 格律约束解码 (Rhythmic Masking):状态机硬核保障五言/七言律诗绝对对称
- 5.6 动手实现流式生成器:打造你的专属古典诗人
第 06 章|从代码到智能:端到端实战演练与问题剖析
- 6.1 陪伴式实验课:在你的电脑上跑通全流程闭环(五幕实验与全状态断点续训 Resume)
- 6.2 全新双模生成体验:命题创作 (
--title ... --author ...) 与自由续写 (--prompt ...) - 6.3 新手避坑实验室:六大翻车现场急救处方(双重位移卡死 5.18、元数据复读机、标点垄断排查等)
- 6.4 进阶导师寄语:大语言模型的三级火箭跃迁路线(预训练 SFT 指令微调 DPO 对齐 量化部署)
第 07 章|大模型进阶二段跳:手搓 SFT 有监督微调与指令对齐
- 7.1 从“条件预训练”到“自然语言指令对齐”的二段跳(打通基座到对话助手的最后一公里)
- 7.2 SFT 的核心机密:Prompt 掩码与
ignore_index=-100(只惩罚回答,绝不惩罚提问) - 7.3 工业级对话模板(Chat Template)与特殊标记(
<|im_start|>,<|im_end|>, 杜绝死循环复读) - 7.4 动手实战:从
poetry_meta.jsonl打造 3 万条多样化 Alpaca 指令集(5 大维度动态槽位扰动) - 7.5 手写 SFT 数据加载器与张量对齐(
SFTDataset、动态 Padding 与 Collate Function)
第 08 章|参数高效微调 PEFT:从零手搓 LoRA (低秩自适应)
- 8.1 为什么我们需要 PEFT?单卡玩家的显存焦虑
- 8.2 LoRA 的数学直觉:低秩矩阵分解的艺术()
- 8.3 手写 LoRA 线性层:
LoRALinear与LinearWithLoRA - 8.4 适配器注入与参数冻结流水线(仅微调 0.5% 参数)
- 8.5 权重合并与零延迟上线部署
第 09 章|全流程实战演练与训练总复盘:从预训练收官到 SFT 与 LoRA 落地
- 9.1 真实实战环境与超参数全景配置卡
- 9.2 预训练全景遥测复盘(生理指标、PPL 与时间密码)
- 9.3 SFT 有监督微调实战(让模型学会听指令)
- 9.4 LoRA 参数高效微调实战(单卡极速调优)
- 9.5 人机终极大考(三大阶段模型同台竞技)
- 9.6 导师复盘实验室:大模型工业级八大黄金军规(收录元数据比例红线法则、因果对齐单次位移金律、特殊标记原子保护律等)
- 7.6 SFT 微调黄金军规(超参数与避坑指南)(小学习率防遗忘、百步快速收敛)
- 7.7 终极见证:预训练基模 vs SFT 模型的行为演化录
第 08 章|站在巨人的肩膀上:工业级 LoRA 微调与现代大模型 (Qwen2.5 双轨实战)
- 8.1 显存危机:为什么消费级显卡玩不起“全量微调”?(7B 全量微调需要 120GB 显存的残酷账本)
- 8.2 LoRA 的数学美学:低秩矩阵分解的终极秘密(内在秩假说、、零扰动初始化)
- 8.3 现代基模架构巡礼:为什么 Qwen2.5-1.5B 是 16GB 显卡的黄金甜点?(Qwen2.5 家族 0.5B ~ 72B 选型全景图)
- 8.4 纯 Python 手写极简 LoRA 层(Toy LoRA from Scratch)(不到 30 行 PyTorch 破除黑盒迷信)
- 8.5 权重合并与零成本推理(Weight Merging)(离线融合,部署上线 0 显存增加与 0 延迟惩罚)
- 8.6 Track 1: 0.04B 本地原生手搓 LoRA 极速微调实操(纯 PyTorch、31.9 万低秩参数、1.2MB 独立 Adapter)
- 8.7 Track 2: Qwen2.5-1.5B 工业基模实战轨(站在巨人的肩膀上,ChatML 提示词掩码与流式人机对答)
- 8.8 全书结语:你已经完成了大模型全栈知识闭环
第 09 章|全流程实战演练与训练总复盘:从预训练收官到 SFT 与 LoRA 落地
- 9.1 真实实战环境与超参数全景配置卡(Intel Arc 130T 16GB、46 万纯诗、3463 万 Tokens、0.04B 架构)
- 9.2 第一幕:预训练全景遥测复盘(真实控制台日志轨迹、JIT 编译冷启动解密、PPL 与 Loss 收敛图)
- 9.3 第二幕:SFT 有监督微调实战(数据自动化生成、Prompt 掩码 -100 实训、10 分钟快速对齐)
- 9.4 第三幕:LoRA 低秩微调极速攻坚(0.48% 参数微调、一键离线无损合并)
- 9.5 第四幕:人机终极大考(预训练基模 vs SFT 指令模型同台对决实录)
- 9.6 导师复盘实验室:大模型训练的五大金律
祝你学习愉快,开启手搓大模型的精彩旅程!🚀
REFERENCES
参考链接
所属系列
从零开始手搓大模型