固定 5 分钟训练时限对实验可比性与资源利用的折中
在 autoresearch 项目中,所有实验都被强制限制在 5 分钟 的墙钟时间内(不计启动与编译)。这种设计的初衷是让不同实验在同一时间预算下直接可比,进而得到 val_bpb(validation bits per byte)的统一度量。然而,这一硬性上限也带来了两个显著的局限:
- 资源浪费:当模型规模或 batch size 较大时,GPU 可能在 5 分钟内未能完成完整的前向‑反向循环,导致算力利用率下降。
- 探索深度受限:一些需要多轮微调才能显现优势的架构(如稀疏注意力)在如此短暂的窗口内难以评估,导致代理可能过早放弃潜在改进。
理解这两点是后续设计的基石。
train.py 单文件可编辑设计限定范围与差分审查
train.py 是 autoresearch 唯一允许 AI 代理 修改的文件。它包含:
- 完整的 GPT 模型定义(层数、宽度、注意力头数)
- Muon + AdamW 混合优化器实例化
- 训练循环(前向、损失计算、反向、梯度更新)
单文件策略的优势在于 diff 易于审查:每一次代理提交的改动都可以通过 Git 差分快速定位,防止代码膨胀。实现上,文件顶部使用 Python dataclasses 定义超参数块,代理只需修改对应字段即可:
# train.py
from dataclasses import dataclass
@dataclass
class HyperParams:
n_layers: int = 12
d_model: int = 768
n_heads: int = 12
batch_size: int = 32
lr: float = 1e-4
代理通过编辑 HyperParams,或者直接在模型构造函数中插入新层,实现 结构级别的实验。由于文件保持 函数式(无全局副作用),即使在 5 分钟内多次重启,也能保证实验的 可重复性。
Muon 与 AdamW 混合优化器的实现细节与数值稳定性
项目选用了 Muon(一种自研的轻量级自适应学习率调度器)与 AdamW 的组合,以兼顾 收敛速度 与 正则化。关键实现如下:
# train.py (excerpt)
import torch
from muon import MuonScheduler
optimizer = torch.optim.AdamW(model.parameters(), lr=hp.lr, weight_decay=0.01)
scheduler = MuonScheduler(optimizer, warmup_steps=100, total_steps=5000)
for step, batch in enumerate(dataloader):
loss = model(batch).loss
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
scheduler.step()
optimizer.zero_grad()
- MuonScheduler 在前 100 步进行线性 warm‑up,随后基于实际梯度噪声自适应衰减学习率;
- AdamW 负责 weight decay,防止模型过拟合。
数值实验表明,在相同的 5 分钟窗口内,混合方案比单纯 AdamW 提升约 12% 的 val_bpb 改进幅度,且对 学习率 的敏感度降低,使得代理在搜索超参数空间时更稳健。
BPE 分词器与数据加载器的一次性准备步骤
prepare.py 负责 一次性 完成数据下载、BPE(Byte‑Pair Encoding)分词器训练以及 DataLoader 的构造。该文件被声明为 不可修改,以保持实验基线的一致性。关键流程:
# prepare.py
import datasets
from tokenizers import Tokenizer, models, trainers
# 1. 下载 nanochat 训练数据
dataset = datasets.load_dataset("karpathy/nanochat")
# 2. 训练 BPE 分词器(vocab_size=32k)
tokenizer = Tokenizer(models.BPE())
trainer = trainers.BpeTrainer(vocab_size=32_000, min_frequency=2)
tokenizer.train_from_iterator(dataset["train"]["text"], trainer)
# 3. 保存 tokenizer 供 train.py 使用
tokenizer.save("tokenizer.json")
完成后,train.py 通过 Tokenizer.from_file("tokenizer.json") 加载,同步的 DataLoader 使用 torch.utils.data.DataLoader,batch_size 由 HyperParams 控制。由于所有预处理步骤只执行一次,后续的 5 分钟实验几乎不受 I/O 影响,确保 GPU 利用率 最大化。

单 GPU 5 分钟预算对模型规模与吞吐量的折中分析
在固定时长约束下,模型规模(层数、宽度)与 吞吐量(tokens/秒)形成直接的 折中:
| 模型规模 |
5 分钟内完成的前向‑反向次数 |
平均 token 处理速率 |
| 6‑层, d=512 |
~1500 步 |
2.1k tokens/s |
| 12‑层, d=768 |
~800 步 |
1.4k tokens/s |
| 24‑层, d=1024 |
~350 步 |
0.9k tokens/s |
较大模型在 val_bpb 上可能拥有更好的表达能力,但因 step 数 较少,噪声更大,导致 收敛不稳定。因此,代理在搜索空间时往往倾向于 中等规模(12‑层左右),在 5 分钟预算内取得 最优的性能‑成本比。
高 QPS 环境下的参数调优清单与安全执行建议
当 queries per second (QPS) > 10k 时,单 GPU 的 autoresearch 仍可运行,但需做以下几项调优:
- batch_size 上调至 GPU 内存上限(通常 64–96),以提升吞吐。
- 梯度累积(gradient accumulation)开启 2–4 步,以维持有效 batch 大小而不超显存。
- 混合精度(torch.cuda.amp)强制开启,降低显存占用并提升算子吞吐。
- 安全 sandbox:在
train.py 开头加入 torch.cuda.set_device(0); torch.backends.cudnn.benchmark = True,并在容器层面限制文件系统写入,仅允许日志输出。
遵循上述清单,可在保持 5 分钟实验窗口 的前提下,确保在高 QPS 场景中仍然获得 可比且安全 的模型迭代结果。
项目地址: https://github.com/karpathy/autoresearch