nanoGPT GPT 训练、复现与微调实操指南:10 分钟跑通最小闭环
【免费下载链接】nanoGPTThe simplest, fastest repository for training/finetuning medium-sized GPTs.项目地址: https://gitcode.com/GitHub_Trending/na/nanoGPT
nanoGPT 是目前最精简、最快的 GPT 训练与微调仓库:model.py和train.py两个核心文件各约 300 行,单台 8xA100 节点即可复现 GPT-2(124M),一台普通 MacBook 也能在几分钟内训出一个字符级小模型。
项目速览:300 行代码装下了什么
先把话说直白些:nanoGPT 不是一个"功能大而全的训练框架",而是一台结构完全摊开、方便你动手拆改的 GPT 训练机器。它重写了早期的 minGPT,把教育性的冗余砍掉,保留了分布式训练、混合精度、checkpoint 管理这些真正干活的东西。
| 对比维度 | nanoGPT | minGPT | 基于 HuggingFace Trainer 的训练脚本 | 通用 LLM 微调框架 |
|---|---|---|---|---|
| 核心代码量 | 约 600 行(model + train) | 单文件约 300 行 | 通常上百行配置 + 依赖大量封装 | 数千行起 |
| 自带分布式(DDP/多机) | 有,torchrun 直接起 | 无 | 依赖 Trainer 抽象 | 有 |
| 能否直接复现 GPT-2 | 可以(8xA100 约 4 天,loss ≈ 2.85) | 需自行补训练逻辑 | 可,但离底层较远 | 通常面向已有权重微调 |
| 硬件下限 | 一台 MacBook(CPU/MPS 可跑通) | 极低 | 一张消费级 GPU | 多为单卡以上 |
| 适合人群 | 想读懂并魔改 GPT 训练细节的人 | 教学阅读 | 快速实验 | 工程化微调生产 |
一句话定位:它"轻量但完整"——代码量接近教学级,能力却摸到了复现 GPT-2 的门槛。目录结构也很克制,核心入口只有三个文件:模型定义、训练主脚本、采样脚本,其余按用途归在 训练配置目录 和 数据预处理脚本 里。
10 分钟跑通:装环境、训模型、出文本
整个最小闭环是:克隆仓库装依赖 → 把一堆文本变成整数流 → 训练一个字符级小 GPT → 采样出文本。下面按"你手上有 GPU / 只有一台 MacBook"两种情况给命令。
第 1 步:克隆与安装。仓库很小,依赖也简单:
git clone https://gitcode.com/GitHub_Trending/na/nanoGPT cd nanoGPT pip install torch numpy transformers datasets tiktoken wandb tqdm依赖里transformers负责加载 OpenAI 的 GPT-2 权重,tiktoken是 GPT-2 用的 BPE 分词器,wandb只是可选日志,不装也能跑。
第 2 步:准备数据。入门示例用的是莎士比亚全集(约 1MB 文本),脚本会把原文切成逐字符的整数序列,生成train.bin和val.bin:
python data/shakespeare_char/prepare.py第 3 步:训练。直接指向现成的配置文件即可,里面定义了一个 6 层、6 头、384 维、上下文 256 字符的"baby GPT":
# 有 GPU 的机器(A100 上约 3 分钟,验证损失约 1.47) python train.py config/train_shakespeare_char.py # 只有 CPU 的 MacBook:缩小模型与批次,同时关掉编译 # python train.py config/train_shakespeare_char.py --device=cpu --compile=False --block_size=64 --batch_size=12 --n_layer=4 --n_head=4 --n_embd=128 # Apple Silicon 想用上芯片内 GPU:再加 --device=mps,通常能快 2~3 倍CPU 模式下约 3 分钟也能跑完,损失会落在 1.8 左右——文本质量更糙,但闭环完全成立。训练期间 checkpoint 会写到out-shakespeare-char/目录,看到验证损失稳步降到 1.5 附近就可以等着收工了。
第 4 步:生成文本。让采样脚本指向刚才的产出目录:
python sample.py --out_dir=out-shakespeare-char字符级模型只学"下一个字符",所以 3 分钟训出来的效果是"形似莎士比亚的胡话",大致长这样:
OLIVIA: If you do not come, I will give you the whole town, and if you come, I will give you twice as much...
MALVOLIO: And thou art the thing that I do not know.
别被输出劝退——这恰恰说明它已经学到了戏剧台词的排版节奏和词汇分布。想要真正通顺的英文,往下看微调那一节。
生成与调参:sample.py 的参数怎么配
采样脚本 既能加载你训好的模型(--out_dir指向产出目录),也能直接加载 OpenAI 发布的 GPT-2 系列(--init_from),所以它兼作"推理入口"。核心参数如下:
| 参数 | 作用 | 建议值 |
|---|---|---|
--init_from | 模型来源:resume(自己训的)或gpt2/gpt2-medium/gpt2-large/gpt2-xl | 复现实验用resume,零成本体验用gpt2 |
--out_dir | 加载 checkpoint 的目录,仅在init_from=resume时生效 | 与训练时的out_dir一致 |
--start | 提示词文本,也支持FILE:prompt.txt从文件读入 | 以换行\n开头往往更稳 |
--num_samples | 一次生成几条 | 对比调参时设 5~10,正式用 1 |
--max_new_tokens | 每条样本的生成长度 | 200~500 |
--temperature | 采样随机性:1.0 不变,越小越稳,越大越跳脱 | 写摘要/续写 0.5~0.7;创意文本 0.8~1.0 |
--top_k | 只保留概率最高的 k 个候选,其余清零 | 200(默认);求稳降到 100 以下 |
--seed | 随机种子,固定后可复现同一批输出 | 1337(默认) |
--device | 推理设备 | 与训练一致;MacBook 记得mps |
两个典型场景:想让它接着你的话写,就用python sample.py --out_dir=out-shakespeare-char --start="To be, or not to be:" --temperature=0.6 --top_k=100;想零训练体验 gpt2-xl 的水平,就python sample.py --init_from=gpt2-xl --start="What is the answer to life, the universe, and everything?" --num_samples=5 --max_new_tokens=100。经验上,temperature和top_k是"口味旋钮",先动这两个,再动其他。
复现 GPT-2 还是微调:两条路线怎么选
"从零复现"和"站在预训练权重上调教"是两种完全不同的任务,成本差好几个数量级:
| 任务 | 数据 | 硬件门槛 | 耗时 | 期望结果 | 入口 |
|---|---|---|---|---|---|
| 复现 GPT-2(124M) | OpenWebText(约 10 亿 token) | 单节点 8xA100 40GB | 约 4 天 | 验证 loss ≈ 2.85 | python data/openwebtext/prepare.py后起 torchrun |
| 单卡小模型实验 | 任意自定义文本 | 一张消费级 GPU | 小时级 | 取决于数据与规模 | 改 训练主脚本 命令行参数 |
| 微调预训练 GPT-2 | 几万到几十万 token 的小语料 | 单张 GPU | 几分钟 | 风格迁移质量高 | 指向 微调配置 |
| 只评测不训练 | 评测集 | 一张卡即可 | 几分钟 | 得到基线 loss 对照 | config/下的eval_gpt2*.py系列 |
复现路线。先把 OpenWebText 下载并 tokenize(产物同样是train.bin/val.bin,但存的是 GPT-2 BPE 的 token id 而非字符):
python data/openwebtext/prepare.py torchrun --standalone --nproc_per_node=8 train.py config/train_gpt2.py跑满约 4 天后 loss 收敛到 2.85 附近。有个值得记住的细节:直接用 GPT-2 官方权重在 OpenWebText 上评测,验证 loss 是 3.11;把它微调一会儿才降到 2.85——两者差距来自 WebText 与 OpenWebText 之间的领域差。所以"复现达标线"应该对齐 2.85,而不是 3.11。
微调路线。如果你的目标只是"让 GPT-2 学会某种文体/领域说法",微调是性价比之王:数据准备只要几秒,单卡几分钟出结果。以 微调配置 为例,关键设定是:
| 参数 | 取值 | 意图 |
|---|---|---|
init_from | gpt2-xl | 从 1.3B 的预训练权重出发 |
learning_rate | 3e-5 | 比从头训练(6e-4)低约 20 倍,防止冲刷已有知识 |
decay_lr | False | 短微调保持恒定学习率即可 |
batch_size/gradient_accumulation_steps | 1 / 32 | 用梯度累积模拟 32 的等效批量,省显存 |
max_iters | 20 | 小语料约 30 万 token,20 个 iter 已接近一个 epoch |
命令本身和训练完全同构:python train.py config/finetune_shakespeare.py。训完后python sample.py --out_dir=out-shakespeare出的文本就是标准英文莎士比亚腔,例如:
THEODORE: Thou know'st not what thou doest; for I would have thee to be a man of thyself, and not a shadow of a man, that walks in the dark...
决策口诀:要"懂语言"的能力,直接复用预训练权重走微调;要研究训练本身(scaling、超参敏感性),才值得上全量复现。
性能优化与排错:现象 → 原因 → 处理
先看三个几乎白送的提速手段,都来自仓库自带能力:
| 手段 | 怎么开 | 收益 |
|---|---|---|
torch.compile()(默认开启) | 保持默认即可 | 官方环境下单步耗时约从 250ms 降到 135ms,接近 2 倍 |
| bfloat16 混合精度 | GPU 支持时默认启用,--dtype=bfloat16 | 显存与带宽压力下降,大 batch 更容易塞下 |
| 梯度累积 | --gradient_accumulation_steps调大 | 等效大批量训练而不爆显存,复现 GPT-2 时就靠它(12 × 累积 40) |
遇到异常时,按下面的表对症:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| CUDA out of memory | batch_size、block_size或模型规模超过显存 | 依次下调三者;或用梯度累积代替大 batch;微调时换更小的init_from(如gpt2) |
启动即报torch.compile相关错误 | PyTorch 2.0 编译仍是实验特性,部分平台(如 Windows)不支持 | 追加--compile=False,速度慢一些但能跑 |
| MacBook 上训练明显偏慢 | 默认只用了 CPU | 换较新版本 PyTorch 并加--device=mps,调用芯片内 GPU,约提速 2~3 倍 |
| 验证 loss 不降或剧烈震荡 | 学习率偏高或 warmup 太短 | 降低learning_rate,加大warmup_iters;小模型可同步降dropout |
| CPU 上评估又慢又抖 | 默认eval_iters=200取平均的样本太多 | CPU 实验改小(如--eval_iters=20),牺牲精度换速度 |
| 多机训练慢如蜗牛 | 节点间没有 InfiniBand | 启动命令前缀加NCCL_IB_DISABLE=1;有条件先用 iperf3 测一下互联带宽 |
| 生成文本"胡话连篇" | 字符级小模型本身容量有限(正常现象) | 别怪超参——换用 GPT-2 预训练权重微调,或增加数据量与训练步数 |
另外,bench.py是剥离了日志、分布式等外围逻辑后的纯训练循环基准,改模型结构后想快速看"每步多快、显存多少",直接跑它比起完整训练省事得多。
学习路径与小结
跑通闭环之后,有四个性价比很高的深入方向:
- 改模型:模型定义 只有约 300 行,替换位置编码(RoPE、ALiBi)、换注意力变体都只需动少量函数——仓库 TODO 里作者自己也在排这两个。
- 换数据:照抄 数据预处理脚本 的"文本 → uint16 整数流"套路,接任何自有语料。
- 看 scaling:仓库自带的
scaling_laws.ipynb和transformer_sizing.ipynb用实验数据讲"该训多大的模型",适合做训练前的规划读物。 - 追新版:作者已推出继任项目 nanochat(覆盖更完整的应用链路),想从"会训 GPT"迈向"做完整对话应用",读 nanoGPT 打底后可以直接去看。
从 1MB 的莎士比亚文本到 8xA100 复现 GPT-2,nanoGPT 用约 600 行核心代码把 GPT 训练的全部关键环节都摆在了桌面上——看懂它,你就再不需要把"训练一个 GPT"这件事当成黑盒。
【免费下载链接】nanoGPTThe simplest, fastest repository for training/finetuning medium-sized GPTs.项目地址: https://gitcode.com/GitHub_Trending/na/nanoGPT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考