从零构建 LLM 七阶段实战教程¶
Ch01.878 从零构建 LLM 七阶段实战教程¶
📊 Level ⭐⭐⭐ | 8.6KB |
entities/llm-from-scratch-7-stage-pytorch-tutorial.md
核心框架:七阶段构建计划¶
| 阶段 | 内容 | 关键产出 |
|---|---|---|
| Stage 1 | 数据准备 + 注意力机制 | 分词器、token 嵌入、位置编码 |
| Stage 2 | 构建 LLM + 预训练 | 1.63 亿参数模型、困惑度从 48,725 → 0.39 |
| Stage 3 | 微调(分类 + 指令) | 分类准确率 95.67%、Alpaca 格式指令微调 |
Stage 1:数据预处理¶
BPE(Byte Pair Encoding,分词算法)¶
GPT-2 采用 Byte Pair Encoding,词汇表 50,257 个 token。核心优势:永不遇到 unknown token——任何词都可以拆成子词甚至单个字符。
词嵌入 + 位置编码¶
- GPT-2 Small 嵌入维度:768
- GPT-3 最大版:12,288
- 位置编码:可训练的位置嵌入,直接加到 token 嵌入上
滑动窗口制造训练数据¶
stride=1 时,输入 [1,2,3] → 输出 [2,3,4],从一篇短篇小说可造出海量的训练样本对。
Stage 2:GPT 架构实现¶
GPT-2 Small 配置(1.24 亿参数)¶
| 参数 | 值 |
|---|---|
| 词汇量 | 50,257 |
| 上下文长度 | 1,024 |
| 嵌入维度 | 768 |
| 注意力头数 | 12(每头 64 维) |
| Transformer 层数 | 12 |
| Dropout | 0.1 |
| 参数量 | 1.63 亿(621 MB @ float32) |
Transformer Block 结构(Pre-LayerNorm)¶
关键设计:- Pre-LayerNorm:先归一化再进子层,比 Post-LayerNorm 训练更稳定
- GELU 激活:比 ReLU 温柔,负数区域也保留非零梯度
- Shortcut(残差连接):给梯度修"高速公路",无 shortcut 时第一层比第五层梯度小 25 倍
- FeedForward:Linear(768 → 3072) → GELU → Linear(3072 → 768),先扩大 4 倍再缩小
因果注意力(不许"开天眼")¶
在注意力权重矩阵右上角加一个上三角掩码(softmax 前设为 -inf),确保预测第 N 个词时只能看到前 N-1 个词。
预训练结果¶
- 训练数据:The Verdict 短篇小说(5,145 tokens)
- 优化器:AdamW
- 10 epochs 后:训练 loss 0.39,验证 loss 6.45(过拟合——数据集太小) | Epoch | Loss | 生成质量 | |-------|------|---------| | 1 | 9.78 | "Every effort moves you,,,,,,,,,,"(逗号复读机) | | 2 | 6.66 | "Every effort moves you, and, and, and..."("and"复读机) | | 9 | 0.54 | 开始输出语法正确的句子 | | 10 | 0.39 | 能写出通顺的英文句子 |
解码策略¶
- Greedy:选概率最高 token,安全但无聊
- Temperature:temperature=0.1 像严谨科学家,temperature=5 放飞自我
- Top-k:只保留概率最高的 k 个 token 再采样
Stage 3:微调¶
分类微调(专才)¶
- 数据集:SMS Spam Collection(5,572 条短信),平衡至 747 spam / 747 not-spam
- 冻结大部分参数,只训练:输出层 + 最后一个 Transformer block + 最后的 LayerNorm
- 只用最后一个 token 的输出做分类(因果注意力掩码保证该 token 看到全部信息)
- 学习率 5e-5,5 epochs,M3 MacBook Air 上跑 5.65 分钟 | 指标 | 数值 | |------|------| | 训练集准确率 | 97.21% | | 验证集准确率 | 97.32% | | 测试集准确率 | 95.67% |
指令微调(通才)¶
- 数据集:1,100 条指令-回答对(Alpaca 格式)
- 使用 GPT-2 medium(3.55 亿参数),因为指令微调任务复杂,小模型撑不住
- target padding 技巧:padding token 在 target 中对应位置设为 -100,PyTorch 交叉熵损失自动忽略
- 学习率 5e-5,2 epochs,A100 GPU 上 52 秒
- 用 Llama 3 8B 做自动化评估,110 条测试集平均分 50.32
关键工程细节¶
- 涌现能力(emergent behavior):GPT-3 96 层、1750 亿参数,没专门学过翻译但能翻译
- 预训练成本:GPT-3 花了 460 万美元云计算费用
- 数据规模:GPT-3 训练了 3000 亿 token(9.5 万年阅读量)
- 节省计算:每个 batch 各自填充到当前 batch 最长长度,而不是整个数据集最长长度
深度分析¶
知识体系的承上启下¶
这篇教程以 Makeling LLM 风格呈现,将大语言模型的核心知识分解为数据预处理、注意力机制、GPT 架构、预训练、微调七个阶段。从初学者视角看,这种渐进式结构降低了学习门槛;从工程师视角看,每个阶段的产出物(分词器、注意力矩阵、预训练模型)都是可验证的实体,兼顾了教学清晰度与工程实践性。
从"婴儿说话"到"通顺句子"的质变轨迹¶
训练 loss 从 9.78(逗号复读机)→ 6.66("and"复读机)→ 0.39(通顺句子)的演变过程,展示了预训练中小数据集过拟合的必然性。这个现象与 GPT-3 使用 3000 亿 token 训练形成对比,提示参数量与数据量的匹配关系:1.63 亿参数的模型在 5,145 tokens 上的过拟合几乎是确定事件,关键在于理解这是小数据集的局限而非模型错误。
因果注意力的工程简洁性¶
教程强调"右上角上三角掩码 + softmax 前设 -inf"的实现方式,相比其他方法(如注意力矩阵后置 mask、随机 mask 策略),这种设计在工程上极为简洁——只需一次矩阵运算即可完成因果约束,且在推理时天然支持增量生成。
微调的两种范式对比¶
| 维度 | 分类微调(专才) | 指令微调(通才) |
|---|---|---|
| 目标 | 单任务高准确率 | 多任务泛化能力 |
| 数据规模 | 1,494 条 | 1,100 条 |
| 模型规模 | GPT-2 Small(1.63亿) | GPT-2 Medium(3.55亿) |
| 训练代价 | 5.65 分钟(M3 MacBook) | 52 秒(A100 GPU) |
| 评估方式 | 测试集准确率 95.67% | Llama 3 8B 打分 50.32 |
| 两者的本质区别在于:分类微调只需要"最后一个 token",因为因果注意力已经保证了该 token 看到了全部上下文;指令微调则需要处理完整的 prompt-completion 对,使用 -100 padding 技巧避免无效计算。 |
实践启示¶
- 小数据集验证流程:在本地用小数据集验证整个流程(数据处理→模型训练→推理),确认 pipeline 正确后再迁移到大数据集。The Verdict 实验完美承担了这个角色。
- 参数冻结策略:微调时冻结大部分参数是工程上常见的选择,可以将分类头视为一个"适配器"(adapter),这与 LoRA 等轻量化微调方法的思想一脉相承。
- Batch 内动态 padding:每个 batch 填充到当前 batch 最长长度而非数据集最长长度,可以显著节省计算资源。这个优化在长上下文场景下尤为重要。
- 预训练权重加载:教程直接加载 OpenAI 的 GPT-2 权重验证模型正确性,这是一个重要的工程技巧——先确保模型架构实现正确,再用自己的数据训练。
- 涌现能力的工程启示:GPT-3 在 96 层、1750 亿参数时才出现涌现能力,这意味着如果只是在 GPT-2 级别(12 层、1.63 亿参数)工作,很多"神奇能力"可能不会出现,需要有合理的预期管理。
相关资源¶
相关实体¶
- Karpathy Llm Wiki V2 2026
- Aws Reinforcement Fine Tuning Llm As Judge
- Llm Finetuning Cost Breakdown
- How Llms Actually Work 0Xkato
- Chatgpt小心翼翼回复风格技术原因
- profiling in pytorch (part 2): from nn.linear to a fused mlp