不需要大模型基础,会一点 Python、懂矩阵乘法这样的线性代数基础就够了。我们用 PyTorch 从零手写一个 GPT-2,加载 OpenAI 官方权重,跑通推理和文本生成。
- 不调用任何现成的 Transformer 模块,模型代码
gpt2/model.py不到 200 行 - 用一个 3 个词的例子「猫吃鱼」,从分词一路推到文本生成,每篇都配可运行脚本
- 和 HuggingFace 官方实现逐项对齐,测试保证结果一致
1. 先看懂 Transformer 原论文的架构图
GPT-2 的骨架来自 2017 年的论文 Attention Is All You Need(GPT-2 只用了图中右半边的解码器部分)。我把论文里最有名的这张架构图做成了动态版:按数据流动的顺序一步步高亮,每一步都配有原文和白话解释。
2. 代码看不懂?看矩阵是怎么一格一格算出来的
页首那张动图就是其中一步。同样用「猫吃鱼」3 个词,把一次完整的推理拆成 11 步,每个矩阵都能点「播放」,看每一格是怎么算出来的。读代码卡住的时候,对照着看会容易很多。
这个系列是我自己从零开始、一点一点学大模型留下的笔记。
一开始我也看不懂 Attention 公式里的 Q、K、V,不知道 768 维的向量到底在算什么。所以我给自己定了一个笨办法:每学一个模块,就用最小的例子「猫吃鱼」把矩阵一步步算出来,再亲手写成代码跑一遍,确认真的懂了,才往下走。
15 篇文章,就是这条路上的 15 个台阶。从分词、Embedding、注意力,一直写到加载 OpenAI 的官方权重、让模型真正生成文字。仓库里的每一行代码,我都自己写过、跑过。
如果你也想搞懂大模型,但被公式和论文劝退过,希望这份笔记能帮你少走一些弯路。
名字致敬 Karpathy 的 nanoGPT。NamiGPT 是面向中文零基础读者的入门教程:不追求训练效率,而是用「猫吃鱼」这个例子,把 GPT-2 的每一步拆开讲清楚。
📖 图文版教程:namiai.tech/articles
| # | 主题 | 图文教程 | 原稿 | 代码 |
|---|---|---|---|---|
| 01 | 项目介绍 | 网页 | md | — |
| 02 | Tokenizer 分词器 | 网页 | md | ep02 |
| 03 | Embedding 嵌入层 | 网页 | md | ep03 |
| 04 | Positional Encoding 位置编码 | 网页 | md | ep04 |
| 05 | Self-Attention 自注意力 | 网页 | md | ep05 |
| 06 | Multi-Head Attention 多头注意力 | 网页 | md | ep06 |
| 07 | Residual Connection 残差连接 | 网页 | md | ep07 |
| 08 | LayerNorm 层归一化 | 网页 | md | ep08 |
| 09 | FFN 前馈网络 | 网页 | md | ep09 |
| 10 | Activation Function 激活函数 | 网页 | md | ep10 |
| 11 | Transformer Block | 网页 | md | ep11 |
| 12 | Transformer Stack 堆叠 | 网页 | md | ep12 |
| 13 | Loading Pretrained Weights 加载权重 | 网页 | md | ep13 |
| 14 | Text Generation 文本生成 | 网页 | md | ep14 |
| 15 | Interpretability 可解释性 | 网页 | md | ep15 |
每个脚本都可以单独运行,例如:
python chapters/01-inference/ep06_multi_head_attention.pygit clone https://github.com/aa1143/NamiGPT.git
cd NamiGPT
pip install -r requirements.txt
# 国内网络建议先设置 HuggingFace 镜像(只用来下载官方权重)
export HF_ENDPOINT=https://hf-mirror.comimport tiktoken, torch
from gpt2 import from_pretrained, generate
enc = tiktoken.get_encoding("gpt2")
model = from_pretrained("gpt2") # 手写模型 + 官方 124M 权重
ids = torch.tensor([enc.encode("The cat sat on the")])
out = generate(model, ids, max_new_tokens=30, temperature=0.8, top_k=50)
print(enc.decode(out[0].tolist()))网页版演示(续写 + 每一步的候选词概率):
pip install gradio
python demo/app.pyGPT-2 没有经过对话微调,它只会「接着往下写」,不会回答问题;训练语料以英文为主,建议输入英文。
NamiGPT/
├── gpt2/ # 完整的 GPT-2 实现,可以直接 import
│ ├── config.py # 模型配置(124M / 355M / 774M / 1.5B)
│ ├── model.py # 模型本体:LayerNorm、Attention、FFN、Block、GPT
│ ├── load_weights.py # 把官方权重搬进手写模型
│ └── generate.py # 贪心 / 温度 / top-k 生成
├── chapters/01-inference/ # 每篇文章对应一个演示脚本
├── docs/01-inference/ # 文章原稿
├── demo/app.py # Gradio 网页演示
└── tests/ # 形状检查 + 与 HuggingFace 对齐测试
pytest tests/ -v # 用随机权重对比,不需要下载,几秒钟跑完
TEST_PRETRAINED=1 pytest tests/ -v # 额外下载真实 GPT-2 权重再对比一次- 因果掩码:每个词只能看到自己和前面的词。漏掉这一步,加载官方权重后输出就是错的。
- 权重转置:GPT-2 原始代码用
Conv1D,权重形状是[in, out];nn.Linear是[out, in],搬过来要转置。c_attn还把 Q、K、V 拼在了一起,要先切成三份。 - GELU 版本:GPT-2 用的是 tanh 近似版。PyTorch 的
nn.GELU()默认是精确版,要写approximate="tanh"才能逐位对齐。
- 代码:MIT
- 文章(
docs/目录):CC BY-NC 4.0,转载请注明出处,禁止商用
作者:纳米AI · namiai.tech


