AI Intermediate Jupyter Notebook

Build a Large Language Model From Scratch

通过 PyTorch 从零实现类 GPT 大语言模型,深入理解 LLM 内部工作原理的完整指南

llmdeep-learningpytorchgpttransformerfrom-scratchgenerative-ai

LLMs-from-Scratch 是什么?

这是 Sebastian Raschka(《Python机器学习》作者)的书籍《Build a Large Language Model (From Scratch)》的配套代码仓库。

一句话总结:通过一行一行编写代码,从零实现一个类 GPT 的大语言模型,深入理解 LLM 内部工作原理。

和调 OpenAI API(黑盒)或者看论文(太理论)不同,这个项目给你的是白盒理解——每个组件都亲手编码:Attention 机制、Tokenizer、Transformer 层、预训练、微调。

核心特性

  1. 从零实现 Attention 机制 — 不调库,手写 Multi-Head Attention
  2. 从零实现 GPT 模型 — 完整的 Transformer Decoder 架构
  3. 从零实现 Tokenizer — BPE 算法及 tiktoken 使用
  4. 预训练流程 — 在无标签数据上训练 GPT
  5. 分类微调 — 少量数据微调做文本分类
  6. 指令微调 — SFT 和 DPO 让模型学会遵循指令
  7. LoRA 微调 — 参数高效微调技术
  8. 主流模型从零实现 — Llama 3.2、Qwen3、Gemma 3/4、Olmo

安装

前置要求:Python 3.10+、PyTorch 2.2.2+,有 GPU 更佳(但不是必须)

# 克隆仓库
git clone --depth 1 https://github.com/rasbt/LLMs-from-scratch.git
cd LLMs-from-scratch

# 安装依赖
pip install -r requirements.txt

Google Colab 快速启动:

pip install uv && uv pip install --system -r \
  https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/refs/heads/main/requirements.txt

第一个示例:Multi-Head Attention

核心组件——带因果掩码的缩放点积注意力:

import torch
import torch.nn as nn

class MultiHeadAttention(nn.Module):
    def __init__(self, d_in, d_out, context_length, num_heads, dropout=0.1):
        super().__init__()
        assert d_out % num_heads == 0
        self.d_out = d_out
        self.num_heads = num_heads
        self.head_dim = d_out // num_heads
        self.W_query = nn.Linear(d_in, d_out, bias=False)
        self.W_key = nn.Linear(d_in, d_out, bias=False)
        self.W_value = nn.Linear(d_in, d_out, bias=False)
        self.out_proj = nn.Linear(d_out, d_out)
        self.dropout = nn.Dropout(dropout)
        # 因果掩码:防止看到未来的 token
        mask = torch.tril(torch.ones(context_length, context_length))
        self.register_buffer(
            "mask",
            mask.masked_fill(mask==0, float('-inf')).masked_fill(mask==1, 0)
        )

    def forward(self, x):
        batch, num_tokens, d_in = x.shape
        keys = self.W_key(x)
        queries = self.W_query(x)
        values = self.W_value(x)
        # 重塑为多头:(batch, num_tokens, num_heads, head_dim)
        keys = keys.view(batch, num_tokens, self.num_heads, self.head_dim).transpose(1, 2)
        queries = queries.view(batch, num_tokens, self.num_heads, self.head_dim).transpose(1, 2)
        values = values.view(batch, num_tokens, self.num_heads, self.head_dim).transpose(1, 2)
        # 缩放点积注意力
        attn_scores = queries @ keys.transpose(2, 3) / (self.head_dim ** 0.5)
        attn_scores = attn_scores + self.mask[:num_tokens, :num_tokens]
        attn_weights = torch.softmax(attn_scores, dim=-1)
        attn_weights = self.dropout(attn_weights)
        out = attn_weights @ values
        out = out.transpose(1, 2).contiguous().view(batch, num_tokens, self.d_out)
        return self.out_proj(out)

常见用法

预训练 GPT

from ch05.gpt_train import GPTModel

config = {
    "vocab_size": 50257,
    "context_length": 256,
    "emb_dim": 384,
    "num_heads": 6,
    "num_layers": 4,
    "drop_rate": 0.1,
    "qkv_bias": True
}
model = GPTModel(config)
optimizer = torch.optim.AdamW(model.parameters(), lr=0.0004, weight_decay=0.1)

model.train()
for batch in dataloader:
    optimizer.zero_grad()
    loss = model(batch, targets=batch)
    loss.backward()
    optimizer.step()

文本生成

from ch05.gpt_generate import generate_text_simple

token_ids = generate_text_simple(
    model=model,
    idx=text_to_tokens("The dog"),
    max_new_tokens=50,
    context_size=256
)
print(tokens_to_text(token_ids))

指令微调

from ch07.gpt_instruction_finetuning import InstructionDataset, train_with_ref

dataset = InstructionDataset(raw_data, tokenizer)
# 使用 SFT + DPO 技术微调模型遵循指令

进阶主题

Attention 变体

机制说明
Grouped-Query Attention (GQA)Query 头多,K/V 头少,节省计算
Multi-Head Latent Attention (MLA)DeepSeek-V2 提出的低秩压缩
Sliding Window Attention高效处理长上下文
Gated DeltaNet新型注意力机制
Mixture-of-Experts (MoE)稀疏激活的专家网络

主流模型从零实现

Bonus 章节包含从头实现主流模型:

  • ch05/07_gpt_to_llama/standalone-llama32.ipynb — Llama 3.2
  • ch05/11_qwen3/ — Qwen3 Dense & MoE
  • ch05/12_gemma3/ — Gemma 3
  • ch05/17_gemma4/Gemma 4 E2B and E4B
  • ch05/13_olmo3/ — Olmo 3

LoRA 微调

from ch07.lora import LoRAConfig, apply_lora

lora_config = LoRAConfig(r=8, lora_alpha=16, lora_dropout=0.05)
apply_lora(model, lora_config)
# 只训练 ~0.5% 的参数

最佳实践

  1. 按章节顺序学习 — 代码之间有依赖关系,不要跳着看
  2. 先跑通 .py 文件 — main-chapter-code 里的精简版先跑通建立信心
  3. 用 Colab 快速试跑 — 所有章节都有 .ipynb 格式
  4. GPU 不是必须的 — 主章节在笔记本上就能跑(只是慢一些)
  5. 看配套视频课程 — Manning 有 17+ 小时配套视频
  6. 做课后练习 — 每章有练习题,Appendix C 有解答
  7. 从 Bonus 章节的 modern from-scratch 模型入手 — Gemma 4、Qwen3 等

常见问题

Q: 这个项目和调 OpenAI API 有什么区别? A: 这个项目给你白盒理解。调 API 是黑盒——你得到输出但不懂怎么工作的。这个适合想深入理解 LLM 而不只是使用的人。

Q: 需要多少 GPU 显存? A: 主章节在笔记本上就能跑(~4GB 显存)。只有预训练大模型才需要高端 GPU。

Q: 有中文翻译吗? A: 暂无官方中文版。GitHub 仓库是英文的,但代码注释可以看。

Q: 会继续添加新模型吗? A: 会!Bonus 章节会定期更新新架构(Gemma 4、Qwen 3.5 都是近期新增的)

下一步