《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 到微调的完整管线,不只是模型架构

源码走读建议。

按这个顺序读:

  1. ch02/01_main-chapter-code/dataloader.ipynb — 理解数据怎么进模型
  2. ch03/01_main-chapter-code/multihead-attention.ipynb — 看 Attention 从零实现
  3. ch04/01_main-chapter-code/gpt.py — 核心模型,反复读
  4. ch05/training/gpt_train.py — 看预训练怎么跑
  5. ch06/instruction-tuning/instruction_tuning.py — LoRA 微调实战

重点看MultiHeadAttention.forwardGPTModel.forward 的流控逻辑。前者决定”模型如何思考”,后者决定”模型如何组织”。

性能与边界。

Benchmark 数据

  • 预训练小模型(117M params)在 OpenWebText 上可以达到 ~15.5 PPL
  • 微调后 AlpacaEval 评分约 55-65%(与原始 LLaMA-7B 有差距,但符合预期)

局限性

  • 代码教学导向,不是生产级实现
  • 分布式训练部分较简化(主要面向单机多卡)
  • 没有做推理优化(如 KV Cache 持久化、量化)

适合场景

  • 理解 LLM 原理,准备面试或做技术分享
  • 想要在真实数据上训练自己的小模型
  • 作为阅读 Transformer 论文前的预备知识

总结。

这本书(和它的代码仓库)不是”教你用 LLM”,而是”教你造 LLM”。

如果你已经会用 ChatGPT API 写应用,但说不清楚 QKV 是什么、LayerNorm 为什么要放在残差连接之后,这个仓库就是最好的起点。

🔗 github.com/rasbt/LLMs-from-scratch

评论区

0 条评论

登录后可评论。

智源·AI 开源观察 245 阅读