nanoGPT 是什么,为什么值得逐行读
一句话讲清 GPT 在做什么,给 nanoGPT 仓库画张地图,并用五分钟跑通一个字符级莎士比亚模型,先建立手感,再动手拆代码。
nanoGPT 是什么,为什么值得逐行读
在拆代码之前,先花几分钟把「它到底是个什么东西」想清楚。很多人学 Transformer 卡壳,不是因为哪一行看不懂,而是因为始终没搞清整件事在求解什么问题。
一句话:GPT 是个「猜下一个字」的机器
把所有花哨的说法丢掉,GPT 在做的事,朴素到一句话能讲完:
给它一段文本,它预测「下一个 token 最可能是什么」。
就这么简单。你手机输入法打「今天天气真」,它弹出「好」——这就是一个极其简陋的「下一个字预测器」。GPT 是同一件事,只是:
- 它看的上文更长(nanoGPT 默认能一次看 1024 个 token);
- 它「见过」的文本多到离谱(整个互联网的一大截);
- 它内部用来「理解上文」的机器,是我们要拆的那套 Transformer。
那「生成一整段文章」又是怎么回事?也简单:预测一个字,把它接到句子后面,再拿新句子去预测下一个字,如此反复。这个「自己吃自己尾巴」的过程叫自回归(autoregressive),我们在第四站会逐行看它。
token 是什么? 你可以先粗略理解成「模型眼里的一个字符或一个词片」。在本专栏入门用的字符级例子里,一个 token 就是一个字符(如 a、,、空格);在真正的 GPT-2 里,一个 token 通常是一个「子词」(比如 ing、 the)。下一章讲数据时,你会亲眼看到字符是怎么变成 token 编号的。
给仓库画张地图
git clone 下来,nanoGPT 的目录乍看有点乱,但真正的主角只有几个文件。先记住这张地图,后面每一站你都知道自己站在哪:
| 文件 | 行数(量级) | 干什么 | 在第几站讲 |
|---|---|---|---|
data/*/prepare.py | 几十行 | 数据:把原始文本编码成 train.bin / val.bin | 第一站 |
model.py | 约 300 | 模型:GPT 的完整定义,五个类全在这 | 第二站 |
train.py | 约 300 | 训练:数据加载 + 训练主循环 + 存档 | 第三站 |
sample.py | 约 90 | 采样:载入训练好的模型,生成新文本 | 第四站 |
configurator.py | 约 40 | 配置:一套「简陋但好用」的命令行参数覆盖 | 第三站 |
config/*.py | 几十行 | 各种现成的训练配置(如 train_shakespeare_char.py) | 第三站 |
看出来了吗?核心就 model.py + train.py 两个文件,加起来六百来行。 其余都是配套。这也是 nanoGPT 最迷人的地方——它把「一个能训练的 GPT」压缩到了一个人一个下午读得完的体量,却没有偷工减料。
先跑起来,再拆开看
读源码最忌讳「干读」。强烈建议先把最小的例子跑通,有了「它真的能动」的手感,再回头看代码会踏实得多。nanoGPT 自带一个能在笔记本上、甚至纯 CPU 上跑的例子:字符级莎士比亚。三步:
第一步:准备数据。 下载莎士比亚文集,编码成整数存盘。
python data/shakespeare_char/prepare.py跑完你会在 data/shakespeare_char/ 下看到 train.bin、val.bin、meta.pkl 三个文件。这一步在干什么,正是第一站要逐行拆的。
第二步:训练。 用一份专为「小数据 + 能跑就行」调好的配置开练:
python train.py config/train_shakespeare_char.py如果你没有 GPU,加两个参数让它在 CPU 上也能挪动:
python train.py config/train_shakespeare_char.py --device=cpu --compile=False --eval_iters=20 --log_interval=1 --block_size=64 --batch_size=12 --n_layer=4 --n_head=4 --n_embd=128 --max_iters=2000 --lr_decay_iters=2000 --dropout=0.0屏幕上会滚动出 iter 0: loss 4.2...、iter 100: loss 2.6... 这样的日志。看着那个 loss 一点点往下掉,就是模型在「学」莎士比亚的过程——第三站我们会逐行看这个循环。
第三步:采样。 让训练好的模型写几段:
python sample.py --out_dir=out-shakespeare-char它会吐出几段「莎士比亚味儿」的文本。刚训几百步时多半是胡言乱语,但已经有模有样地在换行、加标点、拼出像单词的东西了。训久一点,它能写出以假乱真的伪莎士比亚。这一步背后,就是第四站的 generate。
CPU 上训练很慢,上面的迷你参数只是为了让你看到它能动,别指望质量。真要出效果,还是得有块 GPU。跑不动也完全不影响读代码——手感有了就行。
一张图看懂整条流水线
把上面三步串起来,nanoGPT 的全貌就是一条清清楚楚的流水线:
- 左边(数据):文本 → 整数,这是第一站。
- 中间(模型 + 训练):整数进模型出预测,和真实答案比得到
loss,再用梯度把模型参数调准——反复几千上万次。这是第二、三站,也是重头戏。 - 右边(采样):训练好的模型,反复「猜下一个」把新文本生成出来。这是第四站。
整个专栏,就是沿着这张图从左走到右,把每个箭头背后的代码都摊开。
下一站,我们从最左边开始:一段莎士比亚,到底怎么变成硬盘上那串数字?👉 数据:一段莎士比亚怎么变成一串数字