# nanochat **Repository Path**: weibifan/nanochat ## Basic Information - **Project Name**: nanochat - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-09 - **Last Updated**: 2026-08-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nanochat ![nanochat logo](dev/nanochat.png) ![scaling laws](dev/scaling_laws_jan26.png) nanochat 是用于训练大语言模型(LLM)最简单的实验工具。它可以在单张 GPU 节点上运行,代码极少且易于修改,并覆盖了 LLM 的所有主要阶段,包括分词、预训练、微调、评估和推理。例如,你可以自行训练一个 GPT-2 水平的 LLM(2019 年训练成本约 4.3 万美元),现在只需 48 美元(约 2 小时的 8 卡 XH100 GPU 节点),并能通过简单的命令行与它对话。如果使用竞价实例,总成本可低至约 15 美元。更普遍地,nanochat 开箱即可通过设置一个单一的复杂度旋钮 `--depth`(GPT 转换器模型的层数,GPT-2 水平恰好大约为 depth 26)训练一整套计算最优的模型系列。其他所有超参数(转换器的宽度、注意力头数、学习率调整、训练时长、权重衰减……)都会自动以最优方式计算。 关于本仓库的问题,我推荐使用 [DeepWiki](https://deepwiki.com/karpathy/nanochat)(来自 Devin/Cognition)提问,或者使用 [Discussions 板块](https://github.com/karpathy/nanochat/discussions),或到 Discord 上的 [#nanochat](https://discord.com/channels/1020383067459821711/1427295580895314031) 频道交流。 ## Time-to-GPT-2 排行榜 目前开发的主要重点是调优预训练阶段,它消耗最多的算力。受 modded-nanogpt 仓库的启发,为激励进展和社区协作,nanochat 维护了一个 "GPT-2 速通" 排行榜,即把 nanochat 模型训练到 GPT-2 水平(以 DCLM CORE 分数衡量)所需的墙上时间。[runs/speedrun.sh](runs/speedrun.sh) 脚本始终反映了训练 GPT-2 水平模型并与之对话的参考方法。当前排行榜如下: | # | 时间 | val_bpb | CORE | 描述 | 日期 | 提交 | 贡献者 | |---|-------------|---------|------|-------------|------|--------|--------------| | 0 | 168 小时 | - | 0.2565 | 原始的 OpenAI GPT-2 检查点 | 2019 | - | OpenAI | | 1 | 3.04 | 0.74833 | 0.2585 | d24 基线,略微过度训练 | 2026年1月29日 | 348fbb3 | @karpathy | | 2 | 2.91 | 0.74504 | 0.2578 | d26 略微欠训练 **+fp8** | 2026年2月2日 | a67eba3 | @karpathy | | 3 | 2.76 | 0.74645 | 0.2602 | 将总批大小提升到 1M 个 token | 2026年2月5日 | 2c062aa | @karpathy | | 4 | 2.02 | 0.71854 | 0.2571 | 更换数据集为 NVIDIA ClimbMix | 2026年3月4日 | 324e69c | @ddudek @karpathy | | 5 | 1.80 | 0.71808 | 0.2690 | 自动研究 [第1轮](https://x.com/karpathy/status/2031135152349524125) | 2026年3月9日 | 6ed7d1d | @karpathy | | 6 | 1.65 | 0.71800 | 0.2626 | 自动研究第 2 轮 | 2026年3月14日 | a825e63 | @karpathy | 我们关心的主要指标是 "time to GPT-2"——在 8 卡 XH100 GPU 节点上超过 GPT-2(1.6B)CORE 指标所需的墙上时间。GPT-2 的 CORE 分数为 0.256525。在 2019 年,GPT-2 的训练成本约 4.3 万美元,因此令人难以置信的是,得益于过去 7 年从底层到上层的诸多进步,我们现在能以更快的速度、不到 100 美元(例如按照当前约 3 美元/GPU/小时的价格,一个 8 卡 XH100 节点约 24 美元/小时,那么 2 小时约 48 美元)做到这一点。 更多关于如何解读和贡献排行榜的文档,请参阅 [dev/LEADERBOARD.md](dev/LEADERBOARD.md)。 ## 快速开始 ### 环境搭建 nanochat 使用 [uv](https://docs.astral.sh/uv/) 进行依赖管理。安装方式: ```bash uv sync --extra gpu # 适用于 CUDA(A100/H100 等) uv sync --extra cpu #(或)适用于仅 CPU / MPS source .venv/bin/activate ``` 用于开发(额外安装 pytest、matplotlib、ipykernel、transformers 等): ```bash uv sync --extra gpu --group dev ``` ### 复现并对话 GPT-2 最有乐趣的事情就是训练你自己的 GPT-2 并与之对话。整个流程都包含在单个文件 [runs/speedrun.sh](runs/speedrun.sh) 中,它专为 8 卡 XH100 GPU 节点设计。从你常用的供应商那里租一台新的 8 卡 XH100 GPU 机器(例如我使用并喜欢 [Lambda](https://lambda.ai/service/gpu-cloud)),然后启动训练脚本: ```bash bash runs/speedrun.sh ``` 你可能希望在 screen 会话中运行它,因为这大约需要 1.5 小时。完成后,你可以通过命令行与你的模型对话。请再次确保你本地的 uv 虚拟环境已激活(运行 `source .venv/bin/activate`),然后对话: ```bash python -m scripts.chat_cli ``` 让它写故事或诗歌。让它告诉你"你是谁"以观察幻觉。问它天空为什么是蓝色的,或者为什么是绿色的。speedrun 是一个 4e19 FLOPs 能力的模型,所以有点像和幼儿园小朋友对话 :)。以下是和一个 speedrun 模型的示例对话: > **用户:** 你好,怎么了? > > **助手:** 你好!今天我能帮你什么吗? > > **用户:** 天空为什么是蓝色的? > > **助手:** 天空之所以是蓝色的,是因为一种叫做"光的瑞利散射"的光学现象,它发生在阳光穿过空气中微小颗粒的时候。这些颗粒由微小的蓝色和紫色粒子组成,它们导致光线以特定方式发生弯曲。 > > **用户:** 太酷了。写一首关于它的诗。 > > **助手:** 在暮光的余晖中,天空是蓝色的,
> 一片闪烁的蓝色画布,天空在这里展开,
> 一个蓝色的世界,蓝与更多蓝,
> 编织成一幅如此精美的挂毯,
> 每一种色调似乎在吟唱一个故事。
> ... 更多说明: - 该代码在 Ampere 8 卡 A100 GPU 节点上也能正常运行,只是稍微慢一些。 - 所有代码在单张 GPU 上通过省略 `torchrun` 也能正常运行,并会产生几乎相同的结果(代码会自动切换为梯度累积),但你得等待 8 倍的时间。 - 如果你的 GPU 显存低于 80GB,你需要调整部分超参数,否则会 OOM / 耗尽显存。请在脚本中查找 `--device-batch-size`,并将其调低直到能放下。例如从默认的 32 降到 16、8、4、2,甚至 1。如果还更低,你就需要更懂行、更有创造力了。 - 大部分代码都是相当常规的 PyTorch,因此应该能在任何支持它的平台上运行——xpu、mps 等——但我没有亲自测试过所有这些代码路径,所以可能存在一些边缘问题。 ## 研究 如果你是希望帮助改进 nanochat 的研究者,有两个值得关注的脚本:[runs/scaling_laws.sh](runs/scaling_laws.sh) 和 [runs/miniseries.sh](runs/miniseries.sh)。相关文档见 [1月7日 miniseries v1](https://github.com/karpathy/nanochat/discussions/420)。对于快速实验(约 5 分钟的预训练运行),我最喜欢的是训练一个 12 层的模型(GPT-1 大小),例如这样: ``` OMP_NUM_THREADS=1 torchrun --standalone --nproc_per_node=8 -m scripts.base_train -- \ --depth=12 \ --run="d12" \ --model-tag="d12" \ --core-metric-every=999999 \ --sample-every=-1 \ --save-every=-1 \ ``` 这会使用 wandb(运行名 "d12"),只在最后一步运行 CORE 指标,并且不采样、不保存中间检查点。我喜欢改动一些代码,重新运行一个 d12(或 d16 等),看在迭代循环中是否有帮助。判断一次运行是否有帮助,我喜欢监控 wandb 图表中的: 1. `val_bpb`(以字节比特的词汇量不变单位衡量的验证损失),作为 `step`、`total_training_time` 和 `total_training_flops` 的函数。 2. `core_metric`(DCLM CORE 分数) 3. VRAM 利用率、`train/mfu`(模型 FLOPS 利用率)、`train/tok_per_sec`(训练吞吐量) 示例见 [这里](https://github.com/karpathy/nanochat/pull/498#issuecomment-3850720044)。 需要说明的重要一点是,nanochat 是围绕单一复杂度旋钮——转换器的深度——编写和配置的。这一个整数会自动确定所有其他超参数(转换器的宽度、注意力头数、学习率调整、训练时长、权重衰减……),从而使训练出的模型达到计算最优。其理念是用户无需考虑或设置任何这些参数,只需要通过 `--depth` 请求一个更小或更大的模型,一切"自动运转"。通过扫掠深度,你就能获得不同规模的 nanochat 计算最优模型系列。GPT-2 水平模型(目前最受关注)在当前代码下恰好落在 d24–d26 区间。不过,任何对仓库的候选改动都必须足够有原则,使其适用于所有 depth 设置。 ## 在 CPU / MPS 上运行 脚本 [runs/runcpu.sh](runs/runcpu.sh) 展示了在 CPU 或 Apple Silicon 上运行的非常简单的示例。它会大幅缩小正在训练的 LLM,以便在几十分钟内合理完成训练。这种方式不会得到很强壮的结果。 ## 精度 / dtype nanochat 不使用 `torch.amp.autocast`。相反,精度通过一个全局的 `COMPUTE_DTYPE`(定义在 `nanochat/common.py`)显式管理。默认情况下,它会根据你的硬件自动检测: | 硬件 | 默认 dtype | 原因 | |----------|--------------|-----| | CUDA SM 80+ (A100, H100, ...) | `bfloat16` | 原生的 bf16 张量核心 | | CUDA SM < 80 (V100, T4, ...) | `float32` | 无 bf16;可通过 `NANOCHAT_DTYPE=float16` 使用 fp16(使用 GradScaler) | | CPU / MPS | `float32` | 安全的默认值。在较新的 macOS 上,MPS 也能良好运行 `NANOCHAT_DTYPE=bfloat16`(约节省 25% 内存,速度相近) | 你可以用 `NANOCHAT_DTYPE` 环境变量覆盖默认值: ```bash NANOCHAT_DTYPE=float32 python -m scripts.chat_cli -p "hello" # 强制 fp32 NANOCHAT_DTYPE=bfloat16 torchrun --nproc_per_node=8 -m scripts.base_train # 强制 bf16 ``` 原理:模型权重以 fp32 存储(为了优化器精度),而我们自定义的 `Linear` 层在前向传播时将它们转换为 `COMPUTE_DTYPE`。Embedding 直接以 `COMPUTE_DTYPE` 存储以节省内存。这让我们获得与 autocast 相同的混合精度收益,同时完全显式控制每种精度运行的设置。 注意:`float16` 训练会自动在 `base_train.py` 中启用 `GradScaler` 以防止梯度下溢。SFT 也支持这一点,但 RL 目前不支持。fp16 的推理在所有地方都能正常工作。 ## 指南 我发布了一些可能含有有用信息的指南,从最新到最早: - [2026年2月1日:以 <<100 美元击败 GPT-2:nanochat 之旅](https://github.com/karpathy/nanochat/discussions/481) - [1月7日 miniseries v1](https://github.com/karpathy/nanochat/discussions/420) 记录了第一批 nanochat 模型系列。 - 要为 nanochat 添加新能力,请参阅 [指南:数 strawberry 里的 r(以及如何一般性地添加能力)](https://github.com/karpathy/nanochat/discussions/164)。 - [2025年10月13日:最初的 nanochat 帖子](https://github.com/karpathy/nanochat/discussions/1) 介绍了 nanochat,不过现在它包含一些过时的信息,且模型比当前 master 分支旧得多(结果也更差)。 ## 文件结构 ``` . ├── LICENSE ├── README.md ├── dev │ ├── nanochat.png │ └── repackage_data_reference.py # 预训练数据分片生成 ├── nanochat │ ├── __init__.py # 空文件 │ ├── checkpoint_manager.py # 保存/加载模型检查点 │ ├── common.py # 杂项小工具、生活质量优化 │ ├── core_eval.py # 评估基础模型的 CORE 分数(DCLM 论文) │ ├── dataloader.py # 分布式的 token 化数据加载器 │ ├── dataset.py # 下载/读取预训练数据的工具 │ ├── engine.py # 带 KV Cache 的高效模型推理 │ ├── execution.py # 让 LLM 以工具形式执行 Python 代码 │ ├── gpt.py # GPT nn.Module 转换器 │ ├── loss_eval.py # 评估字节比特(代替 loss) │ ├── optim.py # AdamW + Muon 优化器,单 GPU 及分布式 │ └── tokenizer.py # GPT-4 风格的 BPE 分词器封装 ├── pyproject.toml ├── runs │ ├── miniseries.sh # Miniseries 训练脚本 │ ├── runcpu.sh # 在 CPU/MPS 上运行的小示例 │ ├── scaling_laws.sh # 缩放法则实验 │ └── speedrun.sh # 训练约 100 美元的 nanochat d20 ├── scripts │ ├── base_eval.py # 基础模型:CORE 分数、字节比特、采样 │ ├── base_train.py # 基础模型:训练 │ ├── chat_cli.py # 对话模型:通过命令行对话 │ ├── chat_eval.py # 对话模型:评估任务 │ ├── chat_rl.py # 对话模型:强化学习 │ ├── chat_sft.py # 对话模型:训练 SFT │ ├── infer_bench.py # 推理:延迟/吞吐量/VRAM 基准 │ ├── tok_eval.py # 分词器:评估压缩率 │ └── tok_train.py # 分词器:训练它 ├── tasks │ ├── arc.py # 科学多选题 │ ├── common.py # TaskMixture | TaskSequence │ ├── gsm8k.py # 8K 道小学数学题 │ ├── humaneval.py # 名不副实;简单的 Python 编码任务 │ ├── mmlu.py # 多选题,主题广泛 │ └── smoltalk.py # 来自 HF 的 SmolTalk 数据聚合集 ├── tests │ ├── test_attention_fallback.py # FA3/SDPA 注意力回退 │ ├── test_engine.py # 推理引擎、KV cache │ ├── test_execution.py # 沙盒化代码执行 │ ├── test_optim.py # MuonAdamW 优化器(需要 GPU) │ ├── test_tasks.py # 任务切片、混合、HubDataset │ └── test_tokenizer.py # BPE 往返、对话渲染 └── uv.lock ``` ## 贡献 nanochat 的目标是改进微模型的最新水平,让它们在 1000 美元的预算内可以端到端地研究使用。可及性既关乎总成本,也关乎认知复杂度——nanochat 不是一个配置极其详尽的 LLM "框架";代码库中没有巨大的配置对象、模型工厂或一堆 if-then-else。它是一个单一、内聚、极简、可读、可修改、可最大程度分支的"强基线"代码库,旨在端到端运行并生成一个可以与之对话的 ChatGPT 模型。目前,我个人最感兴趣的是缩短达到 GPT-2 水平的耗时(即让 CORE 分数超过 0.256525)。目前这大约需要 1.5 小时(从前稳定 3 小时降下来),但通过改进预训练阶段,我们可以进一步缩短。 当前的 AI 政策:披露。在提交 PR 时,请声明任何有重大 LLM 贡献、并非你自己编写或你并不完全理解的部分。 ## 致谢 - 名称(nanochat)源自我之前只涵盖预训练的项目 [nanoGPT](https://github.com/karpathy/nanoGPT)。 - nanochat 也受到 [modded-nanoGPT](https://github.com/KellerJordan/modded-nanogpt) 的启发,它用清晰的指标和排行榜把 nanoGPT 仓库游戏化,并借鉴了大量思路以及部分预训练实现。 - 感谢 [HuggingFace](https://huggingface.co/) 提供 fineweb 和 smoltalk。 - 感谢 [Lambda](https://lambda.ai/service/gpu-cloud) 为开发本项目提供的算力。 - 感谢首席 LLM 通灵师 🧙‍♂️ Alec Radford 的建议和指导。 - 感谢仓库管理者 Sofie [@svlandeg](https://github.com/svlandeg) 帮助管理 nanochat 的 issue、PR 和讨论。 ## 引用 如果你在研究中觉得 nanochat 有用,请如下引用: ```bibtex @misc{nanochat, author = {Andrej Karpathy}, title = {nanochat: The best ChatGPT that \$100 can buy}, year = {2025}, publisher = {GitHub}, url = {https://github.com/karpathy/nanochat} } ``` ## 许可证 MIT