logo
0
0
WeChat Login
添加中文版README文档

nanochat

nanochat logo

$100 能买到的最好的 ChatGPT。

这个仓库是一个完整实现的 ChatGPT 类似 LLM,它采用单一、简洁、最小化、可修改、依赖轻量级的代码库。nanochat 设计为在单个 8XH100 节点上通过像 speedrun.sh 这样的脚本运行,从头到尾执行整个流程。这包括分词、预训练、微调、评估、推理和通过简单 UI 进行网页服务,让您可以像与 ChatGPT 一样与您自己的 LLM 对话。nanochat 将成为 Eureka Labs 正在开发的课程 LLM101n 的顶点项目。

与它对话

为了感受这个仓库的最终成果,您目前可以在 nanochat.karpathy.ai 上找到托管的 nanochat d32。"d32" 意味着该模型在 Transformer 神经网络中有 32 层。该模型有 19 亿参数,它通过运行单个脚本 run1000.sh 在 380 亿个 token 上训练,总训练成本约为 800 美元(在 8XH100 GPU 节点上训练约 33 小时)。虽然现在这足以超越 2019 年的 GPT-2,但它与现代大型语言模型(如 GPT-5)相比差距巨大。当与这些微型模型对话时,您会发现它们会犯很多错误,有些天真和愚蠢,并且会大量产生幻觉,有点像孩子。这有点有趣。但使 nanochat 独特的是它完全属于您 - 完全可配置、可调整、可修改,并且从头到尾由您自己训练。要训练和与您自己的模型对话,我们转向...

快速开始

感受魔法的最快方法是运行 speedrun 脚本 speedrun.sh,该脚本训练并推理 $100 级别的 nanochat。在 $24/小时的 8XH100 节点上,总运行时间约为 4 小时。从您喜欢的提供商启动一个新的 8XH100 GPU 盒子(例如,我喜欢使用 Lambda),然后启动训练脚本:

bash speedrun.sh

或者,由于脚本运行 4 小时,我喜欢这样在新的 screen 会话 speedrun 中启动它(并将输出记录到 speedrun.log):

screen -L -Logfile speedrun.log -S speedrun bash speedrun.sh

如果您不太熟悉,请参阅 screen cheatsheet。您可以在 screen 会话中观察它运行,或者使用 Ctrl-a d 分离并使用 tail speedrun.log 查看进度。现在等待 4 小时。完成后,您可以通过类似 ChatGPT 的网页 UI 与您的 LLM 对话。确保再次激活您的本地 uv 虚拟环境(运行 source .venv/bin/activate),然后提供服务:

python -m scripts.chat_web

然后访问显示的 URL。确保正确访问,例如在 Lambda 上使用您所在节点的公共 IP,后跟端口,例如 http://209.20.xxx.xxx:8000/ 等。然后像平常与 ChatGPT 对话一样与您的 LLM 对话!让它写故事或诗歌。让它告诉您您是谁,看看幻觉。问它为什么天空是蓝色的。或者为什么是绿色的。speedrun 是一个 4e19 FLOPs 能力的模型,所以有点像和幼儿园小朋友对话:)。


image

您也可以 cat report.md 文件,该文件出现在项目目录中,包含运行的"成绩单",即一堆评估和指标。在最末端,您会看到一个摘要表,例如:


  • 字符数: 333,989
  • 行数: 8,304
  • 文件数: 44
  • Token 数 (约): 83,497
  • 依赖 (uv.lock 行数): 2,004
指标BASEMIDSFTRL
CORE0.2219---
ARC-Challenge-0.28750.2807-
ARC-Easy-0.35610.3876-
GSM8K-0.02500.04550.0758
HumanEval-0.06710.0854-
MMLU-0.31110.3151-
ChatCORE-0.07300.0884-

总挂钟时间: 3小时51分钟


(默认情况下,您的表格可能缺少 RL 数字)。有关 speedrun 脚本以及需要注意和期待的更多详细信息,请参考我在仓库讨论中发布的 walkthrough:"Introducing nanochat: The best ChatGPT that $100 can buy"

更大的模型

不出所料,$100 不足以训练出高性能的 ChatGPT 克隆版。事实上,LLM 以其数百万美元的资本支出而闻名。对于我们的目的,我认为还有两个感兴趣的规模。首先是约 $300 级别的 d26 模型(即深度=26),训练时间约 12 小时,略优于 GPT-2 CORE 分数。其次是 $1000 级别(约 41.6 小时),只是因为这是一个不错的整数。但是这两个都还没有完全支持,因此没有在 master 分支中附加上。

话虽如此,为了给个概念,speedrun.sh 文件训练 GPT-2 级别的 d26 模型所需的示例更改只涉及三个更改:

... # 您需要下载更多数据分片进行预训练 # 获取参数数量,乘以 20 得到 token 数,乘以 4.8 得到字符数, # 除以 2.5 亿得到分片数量。待办需要改进这个... python -m nanochat.dataset -n 450 & ... # 使用 --depth 增加模型大小。为了不出现内存不足,将设备批次大小减半 32 -> 16: torchrun --standalone --nproc_per_node=8 -m scripts.base_train -- --depth=26 --device_batch_size=16 ... # 确保在随后的中期训练中使用相同设置: torchrun --standalone --nproc_per_node=8 -m scripts.mid_train -- --device_batch_size=16

就是这样!最需要注意的大事是确保您有足够的数据分片进行训练(否则代码会循环并在同一训练集上进行更多 epochs,稍微降低学习速度),以及管理您的内存/VRAM,主要通过减少 device_batch_size 直到合适为止(脚本会通过增加梯度累积循环次数自动补偿,简单地将并行计算转换为顺序计算)。

关于运行 nanochat 的计算环境的更多信息:

  • 代码在 Ampere 8XA100 GPU 节点上也能很好地运行,但会慢一些。
  • 所有代码在单个 GPU 上也能很好地运行,只需省略 torchrun,并且会产生几乎相同的结果(代码会自动切换到梯度累积),但您将需要等待 8 倍长的时间。
  • 如果您的 GPU 少于 80GB,您将不得不调整一些超参数,否则会出现内存不足 / VRAM 耗尽的情况。在脚本中查找 --device_batch_size 并减少它直到合适为止。例如从 32(默认)到 16、8、4、2 甚至 1。低于此值您将需要更多地了解您在做什么并更有创意。
  • 大部分代码是相当标准的 PyTorch,因此它应该可以在任何支持 PyTorch 的平台上运行 - xpu、mps 等,但我还没有开箱即用地实现这一点,所以可能需要一些调整。

在 CPU / MPS 上运行

nanochat 可以在 CPU 或 MPS(如果您使用 Macbook)上运行,并且会自动尝试检测最适合运行的设备。没有 GPU 您不会走得太远,但至少您能够运行代码路径,也许可以耐心地训练一个小型 LLM。关于如何使所有运行命令更小(请随意调整!)的示例,您可以参考 dev/runcpu.sh 文件。您会发现我基本上限制了所有脚本训练较小的模型,运行较少的迭代次数等。这个功能是新的,有点复杂(涉及大量代码),并在 2025 年 10 月 21 日的这个 CPU|MPS PR 中合并。

自定义

要自定义您的 nanochat,请参阅讨论中的 Guide: infusing identity to your nanochat,其中描述了如何通过合成数据生成并将该数据混合到中期训练和 SFT 阶段来调整您的 nanochat 的个性。

此外,要为 nanochat 添加新功能,请参阅 Guide: counting r in strawberry (and how to add abilities generally)

问题

nanochat 被设计为简短而精炼。一个很大的优势是我们可以将所有文件打包在一起,并复制粘贴到您最喜欢的 LLM 中以询问任意问题。例如,我喜欢使用 files-to-prompt 实用程序打包仓库,如下所示:

files-to-prompt . -e py -e md -e rs -e html -e toml -e sh --ignore "*target*" --cxml > packaged.txt

这包括所有 py、rs、html、toml、sh 文件,排除 rustbpe/target 文件夹,并选择 cxml 输出格式。所有内容都写入 packaged.txt 文件,目前大小约 330KB(即远低于最先进 LLM 的约 100K token),以及 45 个文件中约 8K 行代码。

或者,我推荐使用来自 Devin/Cognition 的 DeepWiki 来询问这个仓库的问题。在这个仓库的 URL 中,只需将 github.com 更改为 deepwiki.com,然后您就可以开始了。

测试

我在这里投入得不多,但存在一些测试,特别是针对分词器的测试。例如运行:

python -m pytest tests/test_rustbpe.py -v -s

文件结构

. ├── LICENSE ├── README.md ├── dev │ ├── gen_synthetic_data.py # 身份识别的示例合成数据 │ ├── generate_logo.html │ ├── nanochat.png │ ├── repackage_data_reference.py # 预训练数据分片生成 │ └── runcpu.sh # 在 CPU/MPS 上运行的小示例 ├── nanochat │ ├── __init__.py # 空 │ ├── adamw.py # 分布式 AdamW 优化器 │ ├── checkpoint_manager.py # 保存/加载模型检查点 │ ├── common.py # 杂项小工具,生活质量 │ ├── configurator.py # argparse 的优越替代品 │ ├── core_eval.py # 评估基础模型 CORE 分数 (DCLM 论文) │ ├── dataloader.py # 分词分布式数据加载器 │ ├── dataset.py # 预训练数据的下载/读取工具 │ ├── engine.py # 带有 KV 缓存的高效模型推理 │ ├── execution.py # 允许 LLM 执行 Python 代码作为工具 │ ├── gpt.py # GPT nn.Module Transformer │ ├── logo.svg │ ├── loss_eval.py # 评估每字节比特数(而不是损失) │ ├── muon.py # 分布式 Muon 优化器 │ ├── report.py # 编写 nanochat 报告的工具 │ ├── tokenizer.py # 风格类似 GPT-4 的 BPE 分词器包装器 │ └── ui.html # nanochat 前端的 HTML/CSS/JS ├── pyproject.toml ├── run1000.sh # 训练约 $800 的 nanochat d32 ├── rustbpe # 自定义 Rust BPE 分词器训练器 │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md # 查看为什么存在这个 │ └── src │ └── lib.rs ├── scripts │ ├── base_eval.py # 基础模型:计算 CORE 分数 │ ├── base_loss.py # 基础模型:计算每字节比特数,采样 │ ├── base_train.py # 基础模型:训练 │ ├── chat_cli.py # 聊天模型 (SFT/Mid):通过 CLI 对话 │ ├── chat_eval.py # 聊天模型 (SFT/Mid):评估任务 │ ├── chat_rl.py # 聊天模型 (SFT/Mid):强化学习 │ ├── chat_sft.py # 聊天模型:训练 SFT │ ├── chat_web.py # 聊天模型 (SFT/Mid):通过 WebUI 对话 │ ├── mid_train.py # 聊天模型:中期训练 │ ├── tok_eval.py # 分词器:评估压缩率 │ └── tok_train.py # 分词器:训练它 ├── speedrun.sh # 训练约 $100 的 nanochat d20 ├── tasks │ ├── arc.py # 多选题科学问题 │ ├── common.py # TaskMixture | TaskSequence │ ├── customjson.py # 从任意 jsonl 对话创建任务 │ ├── gsm8k.py # 8K 小学数学问题 │ ├── humaneval.py # 误称;简单的 Python 编程任务 │ ├── mmlu.py # 多选题,广泛主题 │ ├── smoltalk.py # 来自 HF 的 SmolTalk 综合数据集 │ └── spellingbee.py # 教模型拼写/计数字母的任务 ├── tests │ ├── test_engine.py │ └── test_rustbpe.py └── uv.lock

贡献

nanochat 远未完成。目标是在 < $1000 预算范围内提高微模型的最先进水平,这些微模型可以从头到尾访问和工作。可访问性是关于总成本,也是关于认知复杂性 - nanochat 不是一个详尽可配置的 LLM "框架";代码库中没有巨大的配置对象、模型工厂或 if-then-else 怪物。它是一个单一、连贯、最小化、可读、可修改、最大可分叉的"强基线"代码库,设计为从头到尾运行并产生具体的 ChatGPT 克隆及其成绩单。

当前 LLM 政策:披露。提交 PR 时,请声明有任何重大 LLM 贡献的部分,并且您没有编写或您不完全理解的部分。

致谢

  • 名称 (nanochat) 源于我之前的项目 nanoGPT,该项目仅涵盖预训练。
  • nanochat 也受到 modded-nanoGPT 的启发,后者通过清晰的指标和排行榜将 nanoGPT 仓库游戏化,并借鉴了许多想法和预训练的一些实现。
  • 感谢 HuggingFace 提供的 fineweb 和 smoltalk。
  • 感谢 Lambda 提供用于开发此项目的计算资源。
  • 感谢首席 LLM 耳语者 🧙‍♂️ Alec Radford 的建议/指导。
  • 感谢仓库沙皇 Sofie @svlandeg 帮助管理 nanochat 的问题、拉取请求和讨论。

引用

如果您发现 nanochat 对您的研究有帮助,请简单引用为:

@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