类型:实验索引 · 运行环境:CPU 即可 · 最近审阅:2026-10
我喜欢把同一个东西写两遍。第一遍不用 PyTorch,逼自己看清每一个数字从哪里来;第二遍再交给 tensor、module 和 autograd,让它真的学起来。
高层 API 当然不是坏东西,但如果一开始就封装所有核心计算,后续 shape、mask 或 state 出错时,很难定位不收敛的原因。
如果对 view、broadcasting 或自动求导还不熟,先读 PyTorch:从张量到训练。那里用小例子把存储、梯度和完整训练循环接起来,再回这里实现模型。
第一阶段:用纯 Python / NumPy 验证计算
| 文件 | 依赖 | 验证什么 |
|---|---|---|
tokenizer_from_scratch.py |
Python 标准库 | BPE merge rules、词表(vocabulary)、encode/decode |
sequence_numpy.py |
NumPy | RNN 展开、LSTM gates、scaled dot-product attention、causal mask |
前两个文件不使用 autograd。每一个 hidden state、gate 和 attention weight 都能直接从公式追到数组,适合在还没被训练循环淹没之前把机制看清。
python tokenizer_from_scratch.py
python sequence_numpy.py
第二阶段:用 PyTorch 完成训练
| 文件 | 做什么 | 建议命令 |
|---|---|---|
sequence_torch.py |
自行实现 RNN/LSTM cell;训练 delay-copy 或 encoder–decoder reversal | python sequence_torch.py --model lstm --task reverse |
vanilla.py |
2017 encoder–decoder Transformer | 由 vanilla_demo.py 调用 |
vanilla_demo.py |
形状追踪、反转序列、cross-attention 对齐 | python vanilla_demo.py |
model.py |
现代 decoder-only:RMSNorm + RoPE + GQA + SwiGLU + KV cache | 由测试和训练脚本调用 |
test_model.py |
因果性、cache 等价、RoPE 相对性、GQA 分组 | python test_model.py |
train.py |
训练 decoder-only 完成 induction / copy task | python train.py |
这些实现不调用 nn.MultiheadAttention 或 F.scaled_dot_product_attention。PyTorch 提供 tensor、自动求导,以及 Linear、Embedding、LayerNorm、cross-entropy 和优化器这类基础件;attention、mask 和整体结构都逐行写出。
单篇笔记还配有更小的检查脚本,从对应笔记的“动手验证”进入,例如 attention_numpy.py(纯 NumPy 多头注意力(multi-head attention))、attention_torch.py(手写版对照 F.scaled_dot_product_attention 与 nn.MultiheadAttention,所以不受上面那条限制)和 norm_compare.py(三种归一化的统计轴与 batch size 1)。
快速验证
python test_learning_path.py
python test_model.py
test_learning_path.py 检查 tokenizer round-trip、RNN/LSTM 形状、causal attention 的上三角严格为 0,以及 PyTorch 两种 cell 的输出契约。
建议运行顺序
tokenizer_from_scratch.py
↓
sequence_numpy.py
↓
sequence_torch.py --task delay
↓
sequence_torch.py --task reverse
↓
vanilla_demo.py
↓
test_model.py → train.py
为什么保留两套实现
无框架版本适合回答“公式里的每个量来自哪里”;PyTorch 版本适合回答“参数怎样注册、梯度怎样流、训练循环怎样组织”。只看第一种会停在前向演示,只看第二种则容易把 shape、mask 和 state bug 误判成框架问题。
Transformer 最容易“看起来能跑”的四个错
- 因果性:改第 $t$ 个 token,位置 $<t$ 的 logits 必须严格不变。
- KV cache 等价性:增量解码必须复现一次性前向。
- RoPE 相对性:attention score 的位置部分只依赖相对距离。
- GQA 分组:query heads 必须映射到正确的 KV group。
make_figures.py 用真实训练的小模型生成决策边界(decision boundary)、隐藏空间等图;make_norm_figures.py 生成归一化轴示意图和实测的残差梯度图;make_arch_figures.py 画的是结构示意图(Transformer block、三处 attention、KV cache),不是测量结果。
本页术语 3
- 词表 vocabulary
- 模型能输出的所有 token 的集合
- 多头注意力 multi-head attention
- 把注意力拆成若干组并行计算再拼回来
- 决策边界 decision boundary
- 模型对输入作出不同分类的分界线或分界面