Karpathy 的新项目:autoresearch 解析

项目信息:作者 Andrej Karpathy,GitHub 地址 https://github.com/karpathy/autoresearch,2026年3月发布。核心思想是让 AI Agent 自主进行 LLM 训练实验。


这是个什么项目?

2026 年 3 月 6 日,Karpathy 在 X 上发了一条推文:

“谁知道早期奇点可以这么有趣?目标是设计你的 Agent,让它能够无限期地、无需你任何干预地以最快速度进行研究。”

配图里是 Agent 在 git feature branch 上自己跑 LLM 实验——发现更好的配置就提交 commit,不行就丢掉重来。

Karpathy 用他标志性的黑色幽默,说以前 AI 研究是"肉计算机"干的——吃饭睡觉之余,偶尔通过"声波互联"在一种叫"组会"的仪式里同步一下。现在不一样了,研究完全由自主 Agent 群体完成,在云端的计算集群上跑。Agent 们声称代码库已经到了第 10,205 代,反正也没人能判断对错,因为"代码"已经是自我修改的二进制,超出人类理解范围了。

项目的核心思想是:给 AI Agent 一个小型但真实的 LLM 训练环境,让它在你睡觉时自己折腾。它会改代码、训练 5 分钟、看结果有没有变好、保留或丢弃、然后继续。你早上醒来,看到的是一晚上的实验日志,运气好的话还有一个更好的模型。


先看看项目 README

autoresearch 是个极简的自主 AI 研究框架,基于 nanochat 的单 GPU 实现简化而来。设计是:人写 program.md 策略文件,Agent 自己改 train.py 做实验,目标是在固定 5 分钟里拿到最低的 val_bpb。

几个设计原则:

运行要求:单张 NVIDIA GPU(Karpathy 在 H100 上测的)、Python 3.10+、uv 包管理器。


三个核心文件

仓库只有三个核心文件,职责分得很清楚。

prepare.py — 固定基础设施,只读

定义了几个不可改的核心常量:

MAX_SEQ_LEN = 2048       # 上下文长度
TIME_BUDGET = 300        # 训练时间预算(秒)
EVAL_TOKENS = 40 * 524288  # 验证评估 token 数
VOCAB_SIZE = 8192        # 词表大小

职责是:下载训练数据(climbmix-400b-shuffle 数据集)、训练 BPE tokenizer(用 rustbpe)、提供 dataloader 和评估函数。evaluate_bpb() 是基准指标,绝对不能改。

运行方式:

uv run prepare.py  # 一次性准备,大约2分钟

train.py — Agent 的实验场,随便改

这是 Agent 唯一能改的文件。默认配置:

DEPTH = 8                    # 模型层数
DEVICE_BATCH_SIZE = 16       # 设备 batch size
TOTAL_BATCH_SIZE = 2**17     # 总 batch size (131072 tokens)
WINDOW_PATTERN = "SSSL"      # 注意力窗口模式

里面包含:GPT 模型定义(RMSNorm、RoPE、GQA)、Muon + AdamW 混合优化器、训练循环(固定 5 分钟)、Flash Attention 3 集成。

Agent 能改的东西很广:模型架构、优化器、超参数、训练循环、batch size、学习率,几乎什么都能动。

program.md — Agent 指令,人来写

这是 Agent 的"技能描述",定义了实验怎么设置、能做什么不能做什么、结果怎么记、实验循环怎么跑,还有一个重要的"简洁原则"。

以下是 program.md 的完整中文翻译:


这是一个让 LLM 自主进行研究的实验。

设置

要设置一个新实验,需要和用户协作完成以下步骤:

  1. 确定运行标签:基于今天日期提议一个标签(比如 mar5)。分支 autoresearch/<tag> 必须不存在——这是一个全新的运行。
  2. 创建分支:从当前 master 执行 git checkout -b autoresearch/<tag>
  3. 阅读范围内的文件:仓库很小,请阅读这些文件获取完整上下文:
    • README.md — 仓库上下文
    • prepare.py — 固定常量、数据准备、tokenizer、dataloader、评估。不要修改
    • train.py — 你要修改的文件。模型架构、优化器、训练循环
  4. 验证数据存在:检查 ~/.cache/autoresearch/ 是否包含数据分片和 tokenizer。如果没有,告诉人类运行 uv run prepare.py
  5. 初始化 results.tsv:创建只有表头的 results.tsv。基线将在第一次运行后记录。
  6. 确认并开始:确认设置没问题。

获得确认后,开始实验。

实验

每个实验在单张 GPU 上运行。训练脚本运行固定 5 分钟时间预算(墙上时钟训练时间,不含启动/编译)。启动方式:uv run train.py

你可以做的:

你不能做的:

目标很简单:获得最低的 val_bpb。 由于时间预算固定,你不需要担心训练时间——总是 5 分钟。一切都可以改:架构、优化器、超参数、batch size、模型大小。唯一约束是代码不崩溃并在时间预算内完成。

VRAM 是软约束。 为了有意义的 val_bpb 提升,适当增加可以接受,但不应该爆炸式增长。

简洁原则:其他条件相同时,越简单越好。一个增加丑陋复杂度的小改进不值得。反过来,删除代码并获得相同或更好的结果是很棒的结果——那是简化胜利。评估是否保留改动时,权衡复杂度成本与改进幅度。0.001 val_bpb 的提升但增加 20 行 hacky 代码?可能不值得。0.001 val_bpb 的提升来自删除代码?绝对保留。~0 的提升但代码简单很多?保留。

第一次运行:第一次运行应该总是建立基线,所以你要原样运行训练脚本。

输出格式

脚本完成后会打印这样的摘要:

---
val_bpb:          0.997900
training_seconds: 300.1
total_seconds:    325.9
peak_vram_mb:     45060.2
mfu_percent:      39.80
total_tokens_M:   499.6
num_steps:        953
num_params_M:     50.3
depth:            8

注意脚本配置为总是在 5 分钟后停止,所以根据这台电脑的计算平台,数字可能不同。可以从日志文件提取关键指标:

grep "^val_bpb:" run.log

记录结果

实验完成后,记录到 results.tsv(制表符分隔,不是逗号——逗号会破坏描述字段)。

TSV 有表头和 5 列:

commit	val_bpb	memory_gb	status	description
  1. git commit hash(短,7 字符)
  2. 达到的 val_bpb(如 1.234567)——崩溃用 0.000000
  3. 峰值内存 GB,四舍五入到 .1f(如 12.3 —— peak_vram_mb 除以 1024)——崩溃用 0.0
  4. 状态:keepdiscardcrash
  5. 简短描述这个实验尝试了什么

示例:

commit	val_bpb	memory_gb	status	description
a1b2c3d	0.997900	44.0	keep	baseline
b2c3d4e	0.993200	44.2	keep	increase LR to 0.04
c3d4e5f	1.005000	44.0	discard	switch to GeLU activation
d4e5f6g	0.000000	0.0	crash	double model width (OOM)

实验循环

实验在专用分支上运行(如 autoresearch/mar5autoresearch/mar5-gpu0)。

永远循环

  1. 查看 git 状态:当前分支/commit
  2. 用实验想法调整 train.py,直接修改代码
  3. git commit
  4. 运行实验:uv run train.py > run.log 2>&1(重定向所有输出——不要用 tee 或让输出淹没你的上下文)
  5. 读取结果:grep "^val_bpb:\|^peak_vram_mb:" run.log
  6. 如果 grep 输出为空,说明运行崩溃了。运行 tail -n 50 run.log 读取 Python 堆栈跟踪并尝试修复。如果多次尝试后仍无法工作,放弃
  7. 在 tsv 中记录结果(注意:不要 commit results.tsv 文件,让它不被 git 跟踪
  8. 如果 val_bpb 改进了(更低),你"推进"分支,保留 git commit
  9. 如果 val_bpb 相等或更差,git reset 回到起点

这个想法是你是一个完全自主的研究者,尝试各种想法。如果有效,保留。如果无效,丢弃。你推进分支以便迭代。如果你感觉陷入某种困境,可以回退,但应该非常非常少这样做(如果有的话)。

超时:每个实验应该总共约 5 分钟(+ 几秒启动和评估开销)。如果运行超过 10 分钟,杀掉它并视为失败(丢弃并回退)。

崩溃:如果运行崩溃(OOM、bug 等),用你的判断:如果是愚蠢且容易修复的(如拼写错误、缺少 import),修复并重跑。如果想法本身根本性错误,直接跳过,在 tsv 中记录 “crash” 状态,继续下一个。

永不停止:一旦实验循环开始(初始设置后),不要暂停问人类是否应该继续。不要问"我应该继续吗?“或"这是一个好的停止点吗?"。人类可能睡着了,或离开了电脑,期望你无限期继续工作直到被手动停止。你是自主的。如果你用完了想法,更努力地思考——阅读代码中引用的论文,重新阅读范围内的文件寻找新角度,尝试组合之前的"差点成功”,尝试更激进的架构改动。循环运行直到人类打断你,就这样。

举个例子,用户可能在你运行时睡觉。如果每个实验约 5 分钟,你可以每小时约 12 次,普通人类睡眠期间总共约 100 次。用户醒来看到实验结果,全部由你在他们睡觉时完成!


这个 program.md 有几个有意思的地方:


怎么跑起来

环境准备

# 克隆仓库
git clone https://github.com/karpathy/autoresearch.git
cd autoresearch

# 安装依赖
uv sync

# 准备数据(一次性,约2分钟)
uv run prepare.py

跑一次基线

# 手动跑一次,确认环境正常
uv run train.py

预期输出:

---
val_bpb:          0.997900
training_seconds: 300.1
total_seconds:    325.9
peak_vram_mb:     45060.2
mfu_percent:      39.80
total_tokens_M:   499.6
num_steps:        953
num_params_M:     50.3
depth:            8

让 Agent 自己跑

对 Agent(比如 Claude 或 Codex)说:

Hi have a look at program.md and let's kick off a new experiment! let's do the setup first.

Agent 会自己创建分支、读文件、初始化结果文件,然后开始无限循环。

Mac 用户

Mac 没有 NVIDIA GPU,社区有 MLX 版本:

git clone https://github.com/trevin-creator/autoresearch-mlx.git
cd autoresearch-mlx
uv sync
uv run prepare.py

Karpathy 跑出了什么结果

一夜的成果

根据 VentureBeat 报道,Karpathy 的 Agent 一夜跑了 126 次实验,把 val_bpb 从 0.9979 降到 0.9697,改进了大约 2.8%,跑了约 10 小时。

两天的成果

还有一个"depth=12"模型的两天运行:大约 700 次实验,val_bpb 持续下降。

有意思的一点

报道里说,在仅仅 17 小时内,这些 Agent 独立重新发现了 RMSNorm 和 tied embeddings 这些东西——而 Google Brain 和 OpenAI 的人类研究员花了近八年才把它们形式化。


autoresearch-ascend:华为昇腾的适配

如果想在国产昇腾卡上做实验,可以了解下这个适配项目

项目信息

主要改动

从 CUDA 到昇腾 NPU,主要做了这些:

原版 (CUDA) 昇腾版 (NPU)
torch.cuda → CUDA 设备 torch.npu → 昇腾设备
Flash Attention 3 内核 SDPA(Scaled Dot Product Attention)
torch.compile 启用 torch.compile 禁用
BF16 autocast on CUDA BF16 autocast on NPU

关键代码改动

设备初始化

# 原 CUDA 版本
device = torch.device("cuda")

# 昇腾版本
import torch_npu
device = torch.device("npu")
torch.npu.set_device(0)

注意力机制

原版用 Flash Attention 3:

from kernels import get_kernel
fa3 = get_kernel("varunneal/flash-attention-3").flash_attn_interface
y = fa3.flash_attn_func(q, k, v, causal=True, window_size=window_size)

昇腾版改用 PyTorch 原生的 scaled_dot_product_attention,配合自定义窗口因果掩码。

数据下载镜像

国内网络可以这样配置:

export HF_ENDPOINT=https://hf-mirror.com
export AUTORESEARCH_DATA_BASE_URL=https://hf-mirror.com/datasets/karpathy/climbmix-400b-shuffle/resolve/main
export AUTORESEARCH_CACHE_DIR=/path/to/cache

运行方式

# 1. 准备数据集 + tokenizer
python prepare.py

# 2. 跑 5 分钟训练实验
python train.py

NPU 调优参数

train.py 里可以直接改这些:

DEVICE_BATCH_SIZE = 16     # OOM 时先降这个
WINDOW_PATTERN = "L"       # "L" 在昇腾上更安全更快
DEPTH = 8                  # 模型深度
TOTAL_BATCH_SIZE = 2**17   # 必须能被 DEVICE_BATCH_SIZE * MAX_SEQ_LEN 整除

依赖

需要 Python >= 3.10、昇腾环境(torch_npu + CANN 已配置),以及这些依赖:

pip install matplotlib numpy pandas pyarrow requests rustbpe tiktoken

参考链接