《LLMs from Scratch》源码解读:从零搭一个 GPT,到底要写多少行代码?
这本书最大的价值不是”教你调包”,而是让你看见 ChatGPT 背后的最小可行实现。
为什么值得读?。
99,083 Stars,不是靠营销,是靠内容硬。
Sebastian Raschka 的《Build a Large Language Model (From Scratch)》配套仓库,目标很明确:用 PyTorch 从零实现一个 GPT-like 模型,包括预训练和微调。
不同于很多教程停留在”调用 HuggingFace API”,这本书的每一章都在手写核心组件。读完你会明白:attention 不是魔法,是矩阵乘法 + softmax + 残差连接。
核心架构:最小 GPT 需要哪些模块?。
从仓库的章节结构可以拆出完整管线:
Tokenization → Embedding → Attention → FFN → LayerNorm → Output Head
1. 数据处理层(Ch 2)。
重点不是分词本身,而是理解 BPE(Byte Pair Encoding) 如何把原始文本变成模型能处理的整数序列。仓库提供了可运行的 dataloader.ipynb,包含完整的训练/验证集划分和 DataLoader 封装。
2. Attention 机制(Ch 3)。
这是全书的第一个技术高潮。从零实现:
- Scaled Dot-Product Attention
- Multi-Head Attention
- 因果掩码(Causal Mask)
关键代码片段(Ch 3, multihead-attention.ipynb):
class MultiHeadAttention(nn.Module):
def __init__(self, d_in, d_out, context_length, dropout, num_heads, qkv_bias=False):
super().__init__()
self.d_out = d_out
self.num_heads = num_heads
self.head_dim = d_out // num_heads
self.q = nn.Linear(d_in, d_out, bias=qkv_bias)
self.k = nn.Linear(d_in, d_out, bias=qkv_bias)
self.v = nn.Linear(d_in, d_out, bias=qkv_bias)
self.dropout = nn.Dropout(dropout)
self.register_buffer('mask', torch.triu(torch.ones(context_length, context_length), diagonal=1))
def forward(self, x):
b, num_tokens, _ = x.shape
q, k, v = self.q(x), self.k(x), self.v(x)
q, k, v = [t.view(b, num_tokens, self.num_heads, self.head_dim).transpose(1, 2)
for t in (q, k, v)]
**Scaled dot-product attention。**
attn_scores = q @ k.transpose(-2, -1) / self.head_dim ** 0.5
attn_scores.masked_fill_(self.mask.bool()[:num_tokens, :num_tokens], -torch.inf)
attn_weights = torch.softmax(attn_scores, dim=-1)
attn_weights = self.dropout(attn_weights)
context_vec = (attn_weights @ v).transpose(1, 2).reshape(b, num_tokens, self.d_out)
return context_vec
这段代码的价值在于:没有抽象,没有封装,就是原始操作。看懂这 30 行,你就看懂了 Transformer Attention 的本质。
3. GPT 模型本体(Ch 4)。
gpt.py 是全书的核心交付物,包含:
TransformerBlock:Attention + LayerNorm + FFN + 残差GPTModel:多层 Block 堆叠 + 最终 Linear 投影generate_text_simple:贪心解码 + KV Cache
设计亮点:
- 用
torch.manual_seed保证可复现 - Dropout 只用于训练,推理时自动关闭
- 支持 Flash Attention(通过 PyTorch 2.0+ 的
scaled_dot_product_attention)
4. 预训练与微调(Ch 5-7)。
不是只给模型架构,而是完整训练流程:
- 预训练:OpenWebText 数据集,多 GPU 分布式训练
- 指令微调:Alpaca 格式数据集,LoRA 参数高效微调
- 评估:Perplexity 计算、对比不同 checkpoint
与现有实现的对比。
| 实现 | 代码量 | 可读性 | 可训练性 | 适合人群 |
|---|---|---|---|---|
| LLMs-from-scratch | ~1500 行 | ★★★★★ | ✅ 完整训练 | 初学者 → 中级 |
HuggingFace AutoModel |
1 行 | ★★ | ✅ 但黑盒 | 工程应用 |
nanoGPT (Karpathy) |
~300 行 | ★★★★ | ✅ 单文件 | 有基础者 |
minGPT |
~500 行 | ★★★ | ⚠️ 部分训练 | 参考为主 |
为什么选这本书而不是 nanoGPT?
- nanoGPT 更极简,但缺少”为什么这样设计”的解释
- LLMs-from-scratch 每章都有文字推导、图示、练习题
- 支持从 tokenization 到微调的完整管线,不只是模型架构
源码走读建议。
按这个顺序读:
- ch02/01_main-chapter-code/dataloader.ipynb — 理解数据怎么进模型
- ch03/01_main-chapter-code/multihead-attention.ipynb — 看 Attention 从零实现
- ch04/01_main-chapter-code/gpt.py — 核心模型,反复读
- ch05/training/gpt_train.py — 看预训练怎么跑
- ch06/instruction-tuning/instruction_tuning.py — LoRA 微调实战
重点看:MultiHeadAttention.forward 和 GPTModel.forward 的流控逻辑。前者决定”模型如何思考”,后者决定”模型如何组织”。
性能与边界。
Benchmark 数据:
- 预训练小模型(117M params)在 OpenWebText 上可以达到 ~15.5 PPL
- 微调后 AlpacaEval 评分约 55-65%(与原始 LLaMA-7B 有差距,但符合预期)
局限性:
- 代码教学导向,不是生产级实现
- 分布式训练部分较简化(主要面向单机多卡)
- 没有做推理优化(如 KV Cache 持久化、量化)
适合场景:
- 理解 LLM 原理,准备面试或做技术分享
- 想要在真实数据上训练自己的小模型
- 作为阅读 Transformer 论文前的预备知识
总结。
这本书(和它的代码仓库)不是”教你用 LLM”,而是”教你造 LLM”。
如果你已经会用 ChatGPT API 写应用,但说不清楚 QKV 是什么、LayerNorm 为什么要放在残差连接之后,这个仓库就是最好的起点。
评论区
登录后可评论。