第 0 章 项目导览与学习路线 在动任何代码之前,先建立全局心智模型。本章回答三个问题:这是什么?能学到什么?怎么学? 0.1 这个项目是什么 是一个自底向上、工业代码风格的小型 GPT 训练与推理项目,用约 600 行 Python 实现了一条完整的语言模型流水线: 它不手写 Transformer,而是站在 HuggingFace 的肩膀上,专注于把工程流程讲透:配置怎么管、数据怎么来、checkpoint 怎么存续、学习率怎么调度、采样怎么调…… 技术栈一览 类别 | 选型 | 为什么选它 深度学习框架 | PyTorch ≥ 2.
在动任何代码之前,先建立全局心智模型。本章回答三个问题:这是什么?能学到什么?怎么学?
ht-gpt 是一个自底向上、工业代码风格的小型 GPT 训练与推理项目,用约 600 行 Python 实现了一条完整的语言模型流水线:
原始文本 ──► 分词编码 ──► 数据切片 ──► 模型构建 ──► 训练 ──► 推理 ──► Web 演示
它不手写 Transformer,而是站在 HuggingFace transformers 的肩膀上,专注于把工程流程讲透:配置怎么管、数据怎么来、checkpoint 怎么存续、学习率怎么调度、采样怎么调……
| 类别 | 选型 | 为什么选它 |
|---|---|---|
| 深度学习框架 | PyTorch ≥ 2.0 | 工业标准,动态图调试友好 |
| 模型实现 | HuggingFace transformers.GPT2LMHeadModel |
工业级稳定、规模可配 |
| 分词器 | tiktoken (p50k_base) |
OpenAI 出品,Rust 实现,性能强 |
| 数据集 | tiny_shakespeare(Karpathy 经典) | 小(1MB),单机几分钟可训完 |
| Web UI | Gradio | 一行装饰器把函数变成网页 |
| 优化器 | AdamW + 自定义余弦退火 | GPT-2/3 标准配方 |
读完这套教程 + 跑通代码,你将掌握:
| 能力 | 对应章节 |
|---|---|
用 dataclass 管理可复现的实验配置 |
第 2 章 |
用 tiktoken 做分词、构造自回归样本 (x, y) |
第 3 章 |
复用 HuggingFace GPT2LMHeadModel 并自定义规模 |
第 4 章 |
| 写一个带预热 + 余弦退火 + 梯度裁剪的训练循环 | 第 5 章 |
| 实现 temperature + top-k 采样生成 | 第 6 章 |
| 用 Gradio 快速搭一个交互界面 | 第 7 章 |
| 断点续训、设备管理、可复现性等工程细节 | 第 8 章 |
ht-gpt/ ├── config.py ◄── 第 2 章:GPTConfig + TrainConfig(配置即代码) ├── dataset.py ◄── 第 3 章:数据下载 + tiktoken 编码 + DataLoader ├── model.py ◄── 第 4 章:build_model / load_model ├── train.py ◄── 第 5 章:训练主循环(最重的一章) ├── inference.py ◄── 第 6 章:GPTGenerator 自回归生成 ├── app.py ◄── 第 7 章:Gradio Web UI ├── requirements.txt └── README.md
运行后还会自动生成:
data/ # 数据集缓存 checkpoints/ # 训练 checkpoint(含 gpt_final.pt)
config.py ◄─── 被所有模块依赖(单一配置来源) │ ├── dataset.py ◄── 只依赖 config 的 block_size ├── model.py ◄── 把 GPTConfig 映射为 HF GPT2Config │ ├── train.py ◄── 组合 config + dataset + model ├── inference.py◄── 组合 config + dataset(encoder) + model └── app.py ◄── 组合 inference(Web 层)
清晰的分层:配置层 → 数据/模型层 → 训练/推理层 → 应用层。每层只依赖下一层,不反向依赖。
这是整个项目最重要的图,贯穿所有章节:
┌─────────────────────────────────┐ │ 原始文本(莎士比亚,~1MB) │ └─────────────────────────────────┘ │ ▼ get_dataset() │ 本地缓存 → HF datasets → GitHub 直链(三级回退) │ ┌─────────────────────────────────┐ │ tiktoken p50k_base 编码 │ │ → token id 序列(~33 万 token) │ └─────────────────────────────────┘ │ ▼ TextDataset 切片 │ tokens[i : i+block_size+1] │ ┌─────────────────────────────────┐ │ (x, y) 样本对 │ │ x = chunk[:-1] y = chunk[1:] │ └─────────────────────────────────┘ │ ▼ DataLoader 批处理 │ ┌─────────────────────────────────┐ │ GPT2LMHeadModel(25M 参数) │ │ 前向 → logits → CE loss │ └─────────────────────────────────┘ │ ▼ AdamW + 余弦退火 + 梯度裁剪 │ 反向传播更新权重 │ ┌─────────────────────────────────┐ │ checkpoints/gpt_final.pt │ └─────────────────────────────────┘ │ ┌─────────────┴─────────────┐ ▼ ▼ inference.py 命令行 app.py Gradio Web UI (temperature + top-k) (浏览器交互)
后续每章都在细化这条流水的某一段。
把第 2 章的两组配置先列在这里,方便随时对照:
| 字段 | 默认值 | 说明 |
|---|---|---|
vocab_size |
50257 | p50k_base 词表大小(勿改) |
block_size |
128 | 上下文窗口长度 |
n_layer |
6 | Transformer 层数 |
n_head |
6 | 注意力头数 |
n_embd |
384 | 嵌入维度 |
dropout |
0.1 | dropout 概率 |
默认规模约 25M 参数,单 GPU 几分钟可训完。
| 字段 | 默认值 | 说明 |
|---|---|---|
batch_size |
32 | 批次大小 |
learning_rate |
3e-4 | 峰值学习率 |
weight_decay |
0.1 | AdamW 权重衰减 |
betas |
(0.9, 0.95) | AdamW 动量参数 |
max_iters |
5000 | 最大训练步数 |
warmup_iters |
100 | 学习率预热步数 |
grad_clip |
1.0 | 梯度裁剪阈值 |
min_lr_ratio |
0.1 | 余弦退火终点学习率比例 |
save_iter |
500 | checkpoint 保存间隔 |
log_iter |
10 | 日志打印间隔 |
按章节顺序通读,遇到不懂的先标记跳过,第二遍再深入。
💡 核心原则:不要试图一次读懂所有细节。先建立「整体数据流」的心智模型,再逐章深入。每章末尾的「动手实验」是关键——读十遍不如跑一遍改一遍。
三条具体建议:
n_layer 翻倍),观察 loss 曲线、生成质量的变化。这种「反馈循环」比纯阅读强 10 倍。python train.py --max-iters 50 --n-layer 2 --n-embd 64 --n-head 2 --block-size 32,确认环境 OK。环境装好、心智模型建立后,去 第 1 章 环境准备与首次运行 把项目真正跑起来。