nanoGPT 源码解读
逐行读懂 Karpathy 的 nanoGPT——约 300 行模型 + 300 行训练。
序 · 六百行,看懂一个 GPT 是怎么长出来的
「大模型」这三个字,今天被说得神乎其神。但如果你把工程脚手架——分布式、混合精度、各种加速——统统剥掉,只留下「一个 GPT 的本体」,它会小到让你意外:
这就是 nanoGPT——Andrej Karpathy 写的、以干净著称的 GPT 最小实现。它不玩花活,却结构完整:GPT-2、GPT-3、乃至今天的 Llama、Qwen,在骨架上和它是同一套东西,区别只在规模和几处零件的替换。
所以这个专栏的目标很直接:
带你把这六百行,一行一行读懂。 读完,你不再把大模型当黑箱——你会知道一段文本是怎么变成数字的,数字是怎么流过一层层网络的,「注意力」到底在算什么,梯度又是怎么把这一切调准的。
为什么值得逐行读它
市面上讲 Transformer 的文章不少,但大多停在「原理示意图」那一层:画几个方块、几个箭头,公式一摆,就算讲完了。可真正让人「懂」的,往往是那些图里没有、只有代码里才有的细节——
- 为什么 Q、K、V 三个投影要合成一个矩阵一次算完?
- 「因果掩码」在代码里其实只是一行
tril,它凭什么就让模型「只能看过去」? - 权重初始化为什么要给残差投影乘一个
1/√(2·n_layer)? - 训练时那句
loss = loss / gradient_accumulation_steps到底在补偿什么?
这些「魔鬼细节」,恰恰是原理与工程之间的那道坎。nanoGPT 短到你能把每一处都盯着看,又真到每一处都不是玩具。逐行读它,是把「大概懂」变成「真的懂」性价比最高的一条路。
本专栏的方法:代码在左,人话在右。每章先贴出 nanoGPT 的真实源码片段(不改写、不简化),再逐行翻译成大白话,配上类比和图。我们不假设你记得线性代数细节——需要的数学(矩阵乘法、softmax、交叉熵)会在用到时就地补一小段,够用就好。
路线图
我们按「一段文本 → 一个会写字的模型」这条真实的数据流,分五站走:
开篇 · 先认识它 —— nanoGPT 是什么、仓库长什么样,以及五分钟把一个莎士比亚模型跑起来,先有个手感。
第一站 · 数据:文本怎么变成数字 —— 读 data/shakespeare_char/prepare.py。一段莎士比亚全集,怎么变成硬盘上一串整数(train.bin)。字符级分词、词表、train/val 划分,全在这一小段里。
第二站 · 模型:一个 GPT 只有五个零件 —— 读 model.py。先看全景:LayerNorm、CausalSelfAttention、MLP、Block、GPT 五个类怎么拼在一起;再逐行啃下最关键、也最难的注意力。
第三站 · 训练:让模型学起来 —— 读 train.py。数据怎么成批喂进来、学习率怎么调度、梯度累积/混合精度/梯度裁剪各自在解决什么、checkpoint 怎么存怎么续。
第四站 · 采样:让模型开口 —— 读 generate 与 sample.py。训练好的模型怎么一个 token 一个 token 地把新文本「吐」出来,temperature 和 top-k 又是怎么控制它的「脑洞」。
第五站 · 进阶:更大、更快、更省 —— from_pretrained 装载 GPT-2、DDP 多卡、torch.compile、Flash Attention、MFU 这些让它「上规模」的招数。
本专栏聚焦 nanoGPT 仓库本身。所有代码均来自其公开源码(截至撰写时的 master 分支),行号与措辞可能随上游更新略有出入,以你本地 git clone 到的版本为准。我们只讲清楚「它为什么这么写」,不做二次发挥。
配套仓库
强烈建议边读边把仓库开在旁边:
git clone https://github.com/karpathy/nanoGPT.git
cd nanoGPT
pip install torch numpy transformers datasets tiktoken wandb tqdm文章讲「为什么」,代码给「具体长什么样」,两边对照着看,效率最高。
读之前,你最好有
- 会读 Python:看得懂类、函数、
for循环就行,不需要是高手。 - 一点点 PyTorch:知道
Tensor大概是个多维数组、nn.Module是网络的积木。完全没用过也没关系,关键处会解释。 - 不怕数学,但不必精通:矩阵乘法、softmax、求导的「感觉」有就够,细节我们随讲随补。
- 一颗想拆开看的好奇心:读完你会发现,GPT 一点都不魔法,全是扎实、可追问的工程。
准备好了,我们先花五分钟认识它、把它跑起来:nanoGPT 是什么,为什么值得逐行读。