freeCodeCamp.org

How to Build an AI Agent That Runs its Own LLM Experiments with autoresearch

8.5内容质量
How to Build an AI Agent That Runs its Own LLM Experiments with autoresearch

TL;DR · AI 摘要

autoresearch是一个开源工具,允许AI代理自动优化LLM训练过程,通过实验找到模型改进点。

核心要点

  • autoresearch在700次实验中找到20个有效改进模型的变更
  • val_bpb指标是代理评估模型压缩效率的关键
  • 无需ML研究经验即可运行autoresearch进行LLM优化

结构提纲

按章节快速跳转。

  1. 介绍autoresearch工具及其在LLM训练中的应用潜力

  2. 代理通过修改代码、训练模型、读取损失值来评估变更效果

  3. val_bpb指标

    定义val_bpb指标及其在模型压缩效率评估中的作用

  4. 展示代理在nanochat基线模型上的改进效果

  5. 提供从准备环境到执行实验的完整操作步骤

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • autoresearch工具
    • 核心机制
      • 代码修改->训练->损失评估->决策循环
    • 关键指标
      • val_bpb(模型压缩效率)
    • 应用场景
      • LLM训练优化

金句 / Highlights

值得收藏与分享的关键句。

#AI代理#autoresearch#LLM训练#开源工具
打开原文

如何使用 autoresearch 构建一个能够自主运行 LLM 实验的 AI 代理

2026年6月29日

/

#ai-agent

ishaan gupta

几个月前,Andrej Karpathy 发布了 autoresearch。这是一个开源的 Python 工具,允许 AI 代理在单个 GPU 上运行实验,而你只需等待结果。

最近我仍在 Twitter 上看到有人争论 AI 代理是否能构建出自己的“百万美元创意”,或者讨论 Openclaw 的相关话题。但这里有一个仓库,它允许你将一个真实的 GPT 训练环境交给代理,并让它自行完成研究。

本质上,代理会编辑代码、进行训练、读取损失值、对结果做出判断,然后重复这一过程。而你只需在睡觉或处理其他事情时等待。令人惊讶的是,这种方法确实有效。

在深度为 12 的 nanochat 基准测试上(稍后会详细解释“深度”的含义),Karpathy 让它运行了大约两天。在约 700 次实验中,代理发现了约 20 项真正能提升模型性能的修改,这些改进相互叠加。

在本文中,我将逐步介绍 autoresearch 是什么,为什么它衡量成功的方式是关键,仓库中每个文件的实际作用,代理通常能发现什么内容,以及如何自行运行它的分步指南。到文章结束时,你应该能够将代理指向自己的 GPU 并让它自主运行。

目录

  • 前提条件
  • autoresearch 是什么?
  • 为什么这很重要
  • val_bpb 具体指什么?
  • 代理实际能发现什么
  • 最后思考

前提条件

本文是对该仓库的完整指南。目标是让你在阅读完后能够理解 autoresearch 是什么,以及如何在自己的机器上运行它。

无需任何机器学习研究经验,但如果你有相关背景,我撰写的更深入部分将更有意义。基本了解 GPU、VRAM 以及 H100/A100/4090 等 GPU 的知识就足够了,但不用担心,我已在下方引用了文本,解释了我认为初学者需要理解的每个术语。

autoresearch 是什么?

简单来说,autoresearch 只是清晰执行了一个特定想法。你将一个小型但真实的 LLM 训练环境放入单个 Python 文件中,然后让 AI 代理编辑该文件。

代理运行该文件并读取损失值。当你训练语言模型时,“损失”只是一个数字,用于衡量模型预测下一个文本块的准确性。数值越高表示预测越差,数值接近零则表示预测几乎完美。

训练过程就是通过调整模型内部数百万个权重,使这个数值下降。因此,当我说代理“读取损失”时,我的意思是它会查看这个分数,以判断刚刚做出的更改是有助于模型还是产生了负面影响。

根据这个分数,代理决定是否保留更改,然后选择保留或撤销更改。接着它会尝试其他方法。

流程从上到下如下:人类(你)编写规则(一个名为 program.md 的 Markdown 文件),该文件明确说明了规则。AI 代理读取该规则并启动实验循环。

在每次循环中,代理用新想法修改训练代码,训练五分钟,读取结果分数,决定是否保留或撤销更改,并将结果写入结果文件。然后它会循环回继续尝试下一个想法。

它每小时会自动执行大约十二次。因此,一整晚的睡眠可以为你带来大约一百次实验,如果运气不错,到早上时模型会有明显改进。

该仓库的结构设计使得代理只能调整一个参数。它无法安装新软件包,也无法更改数据加载方式或损失计算方式。所有这些功能都被刻意锁定。代理唯一能编辑的文件是train.py,其中包含模型架构、优化器、批量大小、学习率以及训练循环本身的结构。

这种设计之所以有效,原因与任何领域中受控实验的成功原因相同。如果数据、指标和预算都固定不变,那么结果的任何变化必然来自于代理所做的调整。代理以谨慎研究人员的方式进行科学探索,只是它不会感到疲倦,也不需要午休。

为什么这很重要

人们很容易将这解读为又一个代理演示。但事实并非如此,原因在于这个指标。该指标称为val_bpb(验证每字节比特数),它是衡量模型在训练期间从未见过的文本("验证集")预测效果的一种特定方式。

我将在下一节详细说明其计算方式,但简而言之,它衡量的是模型平均需要多少比特信息来编码每个字节的文本。数值越低越好:val_bpb值越低,说明模型对真实文本的惊讶程度越低,而这正是我们的目标。

Karpathy选择使用每字节比特数而非原始训练损失作为指标,是因为每字节比特数不会因为词汇表的变化而改变,因此即使是非常不同的两个模型也可以公平比较。"数值越低越好"和"与词汇表无关"是两个独立的特性,而该指标恰好同时具备这两个特性。

当我说这个仓库中的基线模型"大约达到1.00 bpb"时,我的意思是如果你运行默认的未修改训练脚本5分钟,该模型在验证文本上的指标得分约为1.00。这就是你的起跑线。

从那里开始,0.005 bpb的改进(即得分约0.995)是一个小但真实的提升,这是代理经常找到的改进。而0.05的改进(得分接近0.95)则会是巨大的飞跃,这种提升通常只能通过更大规模的模型或更长的训练时间才能实现。因此这些数值看起来很小,但在这种量级上,千分之一比特的改进确实具有重要意义。

这就是为什么优化这个特定数值如此重要。代理追求的不是研究人员耗费数年时间操纵的人工排行榜。它正在推动与自2019年GPT-2以来所有主要语言模型训练时相同的验证损失曲线下降。

"损失曲线"只是训练过程中该得分下降的图表,而"自GPT-2以来的LLM浪潮"则是指一个事实:从GPT-2到当今最先进的模型,几乎所有进步都来自于人们找到让这条曲线更快或更大幅度下降的方法。代理正在解决完全相同的问题,只是在小规模、快速且低成本的条件下进行。

这正是接下来令人惊讶的部分。当代理发现"这里的改进"时,我的意思是它在允许编辑的小型深度-12模型上找到的改进。"深度"指的是模型中堆叠的变换器层数。深度-12是一个小型模型,而深度-24是具有两倍层数的更大模型。

Karpathy 将代理在深度为 12 的小模型上发现的约 20 项调整应用到了更大的深度为 24 的模型上。这些改进能够堆叠得整齐意味着两件事同时成立:其一,这些改进是相加的(同时启用所有 20 项改进所带来的增益是各自增益的总和,而不是相互抵消);其二,这些改进具有迁移性(在小模型上获得的增益在大模型上同样有效)。

这表明代理发现的是关于训练的真正洞见,而非仅在特定规模下起作用的偶然性。这些改进叠加在一起,将 Karpathy 的 "Time to GPT-2" 基准测试时间从 2.02 小时缩短到了 1.80 小时,这相当于在已经手动调优了很长时间的代码上实现了约 11% 的加速。

另一个重要的因素是预算。每个实验的运行时间严格限定为 5 分钟的墙钟时间,不多不少。这使得每小时可以进行约 12 次实验,在典型的 8 小时睡眠周期内可以完成约 100 次实验。

探索仓库

现在如果你克隆这个仓库,你会得到少量文件。其中大部分是基础设施代码。有三个文件是系统的核心,它们之间的差异在于谁负责编辑哪些内容。

只有三个文件是关键,它们的区别在于谁进行编辑。

  • train.py 是代理进行编辑的文件。它包含 GPT 模型、优化器和训练循环,其中所有内容都可以被修改。
  • prepare.py 是固定的基础文件,在运行过程中无人进行编辑:它负责下载数据、训练分词器并定义评估指标。
  • program.md 是你(人类)进行编辑的文件:它是代理遵循的规则手册。

其余文件(README.mdpyproject.tomluv.lock.gitignore.python-version、分析用的 analysis.ipynb 笔记本以及 progress.png 图像)属于基础设施和文档,运行过程中你和代理都不需要触碰。

仓库中还有一些其他文件,在运行过程中不需要你或代理特别关注。

val_bpb 究竟是什么?

在继续深入之前,理解 val_bpb 的含义会有所帮助。如果你阅读过其他关于大语言模型的文章,可能已经见过诸如“困惑度(perplexity)”或“交叉熵损失(cross-entropy loss)”这样的术语。

每字比特数(bits per byte)可以看作是它们的近亲。当语言模型预测文本时,它会为接下来可能出现的内容分配概率。如果模型自信且正确,它会获得较低的损失值;如果自信但错误,它会获得较高的损失值和较大的惩罚。将所有文本的惩罚值相加,就得到了模型的总损失值。较低的总损失值更好,因为这意味着模型为实际出现的词语分配了较高的概率。

交叉熵损失是训练语言模型的标准评分函数。对于每个 token,模型会为所有可能的下一个 token 分配概率,损失值是实际出现 token 的概率的负对数。如果模型自信地预测了正确的 token,损失值接近于零;如果为正确 token 分配了低概率,损失值就会很大。模型的总损失值是所有 token 上该损失值的平均值。

交叉熵损失以纳特(nats)为单位衡量这一指标。纳特是当你使用自然对数(以 e 为底)而不是以 2 为底的对数时得到的单位。它衡量的是相同量的“意外性”,但使用了不同的尺度(1 纳特大约等于 1.44 比特)。将损失值除以自然对数的底数 2,就能将纳特重新缩放为比特,这就是每字比特数(bits per byte)所执行的转换。

每字节比特数(bits per byte)将这种损失除以文本实际包含的字节数,然后转换为以2为底的对数。结果是一个数字,它告诉你,平均而言,模型需要多少比特的信息来编码每个字节的文本。

一个完美的模型需要接近零,而一个随机模型则需要大约每字节8比特(因为一个字节有8比特)。

Karpathy选择使用每字节比特数(bpb)而非单纯的交叉熵损失,是因为bpb与词汇表大小无关。如果代理决定更改分词器或词汇表,即使模型质量相同,交叉熵损失也会完全不同。每字节比特数消除了这种差异,因此一个词汇量为8192的8层模型和一个词汇量为16384的12层模型可以直接比较。

计算这个指标的函数evaluate_bpb位于prepare.py中,这是代理永远不允许编辑的文件。它只能修改train.py。由于指标定义位于代理无法修改的文件中,它无法通过悄悄改变评分计算方式来降低分数。所有实验的评分规则保持完全一致,这正是使比较诚实的关键。

5分钟规则

在autoresearch中有一个设计选择值得单独成节,因为它决定了整个系统在实践中能否正常运作。无论代理正在做什么,每个实验都严格运行恰好5分钟的墙钟训练时间。

墙钟时间指的是实际经过的时间:即墙上时钟显示的时间,而不是训练步数或处理的token数量。5分钟的墙钟时间就是5个字面意义上的分钟,无论模型在这段时间内完成多少工作。

如果你训练固定步数,代理可以通过让模型变得如此小以至于比基线更快完成更多步数来“获胜”。如果你训练固定token数量,代理可以通过降低序列长度来获胜。

代理并不是像我们通常认为的那样与其他代理竞争。它的唯一目标是将val_bpb降低到这个确切设置下的历史最佳分数以下。“获胜”意味着产生更低的分数,而风险在于它可能通过某种退化捷径降低分数,而不是实现真正的效率提升。如果你训练到收敛,代理的运行时间会差异巨大,你永远无法在一个晚上完成100次实验。

固定的墙钟预算解决了所有这些问题。代理被迫在它面前的实际硬件上优化实际训练效率。如果它让模型稍微大一些,但因为更智能的注意力模式使每步计算量下降,这就是真正的胜利。如果它加快了每步计算,但模型现在每步学习更少,这会表现为更差的val_bpb。这两种效应最终会自动抵消。

H100和A100是NVIDIA数据中心GPU,而RTX 4090是高端消费级显卡。它们在速度和内存方面存在显著差异,这正是重点:在固定的5分钟预算下,更快的显卡能处理更多数据并达到更低的val_bpb。因此,一个GPU的得分无法与另一个GPU的得分直接比较。

不过存在权衡。由于预算是墙钟时间,H100上的val_bpb与4090或A100上的val_bpb并不直接可比。该系统的设计目标是在5分钟内找到最适合你特定计算平台的最佳模型,而不是作为全球基准。

如果你想要跨硬件进行比较,就需要设定不同的预算。对于自主研究的使用场景,这正是正确的做法。

现在我们深入探讨每个文件的细节。

1. prepare.py

没有人会触碰这个文件,但所有其他内容都依赖于它。它主要执行三项任务。

第一项任务是下载数据。训练语料库是ClimbMix-400B,这是一个托管在HuggingFace上的高质量网络数据集,被打乱成6,543个parquet碎片。默认情况下,prepare.py只会下载其中的10个(大约几GB),这对于运行数千个5分钟实验已经绰绰有余。

最后一个碎片始终会被下载并固定为验证集。这种固定非常重要,因为每个实验(无论做出什么改动)都会在完全相同的数据集上进行评估。

第二项任务是训练分词器。该仓库使用rustbpe,这是一个快速的Rust实现的字节对编码,从训练数据的样本中学习8,192个词元的词汇表。结果以tiktoken兼容的编码形式导出,以便与PyTorch下游流程无缝集成。还有一个名为token_bytes.pt的小型预计算查找表,将每个词元ID映射到其UTF-8字节长度。正是这个特性使得bpb计算保持诚实。

第三项任务是提供train.py在运行时导入的实用工具。其中最有趣的是数据加载器。它执行所谓的最佳适配填充:批次中的每一行都以特殊的BOS(序列开始)标记开头,加载器通过贪婪选择适合剩余空间的文档来填充该行。只有当没有文档适合时,才会截断最短的可用文档来填补空白。

结果是100%的利用率且无需填充。与简单地截断长文档并填充短文档的原始方法相比,这种方法明显更快。prepare.py顶部的常量被刻意设计得非常简单。三个数字和一个序列长度就定义了整个实验协议。

如果你在不同硬件上运行autoresearch并想与朋友比较结果,你们唯一需要共享的就是这些常量。这就是为什么要把它们放在这里而不是其他任何地方的全部原因。

2. train.py

这是代理程序所在的文件。它自然地分为四个部分:模型、优化器(矩阵权重使用Muon,嵌入和标量参数使用AdamW)、超参数和训练循环。我们将逐一分析每个部分,以理解每个组件存在的原因。

该模型是一个现代的GPT实现,完全从零开始编写,除了PyTorch和Flash Attention 3内核外,没有其他库依赖。如果你读过其他GPT实现,其高层结构会很熟悉:词元嵌入、堆叠的Transformer块、归一化层,以及将输出映射回词汇表logits的线性头部。

有趣的部分在于细节。我认为对于这个仓库来说,解释架构或代码并不是必要的,所以我只为那些想可视化它的读者绘制了一个小型架构图。然后我会解释训练循环是如何编写的。

循环本身简短且几乎令人愉悦。骨架代码如下:

code
while True:
    # 通过微批次累积梯度以达到TOTAL_BATCH_SIZE
    for micro_step in range(grad_accum_steps):
        with autocast_ctx:
            loss = model(x, y)
        loss = loss / grad_accum_steps
        loss.backward()
        x, y, epoch = next(train_loader)
code
# 根据经过的时间更新学习率 / 动量 / 权重衰减
progress = min(total_training_time / TIME_BUDGET, 1.0)
# ... 设置 group["lr"], group["momentum"], group["weight_decay"] ...

optimizer.step()
model.zero_grad(set_to_none=True)

# 记录步骤指标
# ...

if step > 10 and total_training_time >= TIME_BUDGET:
    break

这里有几个值得注意的点。首先,时间预算是在前10个步骤之后进行检查的。这样做的原因是避免将初始PyTorch编译时间(可能需要30秒或更久)计入预算。如果没有这个设计,快速实验会因为将一半预算用在预热阶段而受到惩罚。

其次,循环中包含快速失败检查。如果损失爆炸或出现NaN,会打印“FAIL”并退出。此时代理会看到崩溃并记录日志。这是防止代理执行导致显著发散操作的防御机制。

第三,循环结束后,会进行一次最终的evaluate_bpb调用,然后向标准输出打印结构化摘要。

该摘要就是训练脚本与代理之间的完整API:

code
---
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

这是grep提取的内容,代理会读取这些信息。整个实验合同就是这七行纯文本。

#### 超参数

超参数位于train.py文件底部的明确标记部分,注释中写着“直接编辑这些参数,不需要CLI标志”。它们的结构如下:

code
# 模型架构
ASPECT_RATIO = 64       # model_dim = depth * ASPECT_RATIO
HEAD_DIM = 128          # 注意力的目标头维度
WINDOW_PATTERN = "SSSL" # 滑动窗口模式:L=完整上下文,S=半上下文

# 优化
TOTAL_BATCH_SIZE = 2**19 # 每个优化器步骤约524K tokens
EMBEDDING_LR = 0.6
UNEMBEDDING_LR = 0.004
MATRIX_LR = 0.04
SCALAR_LR = 0.5
WEIGHT_DECAY = 0.2
ADAM_BETAS = (0.8, 0.95)
WARMUP_RATIO = 0.0
WARMDOWN_RATIO = 0.5
FINAL_LR_FRAC = 0.0

# 模型规模
DEPTH = 8
DEVICE_BATCH_SIZE = 128

此处的所有参数都是明确的单一事实来源。模型维度由深度计算得出(depth × 64,四舍五入到头维度)。头的数量由模型维度计算得出。这意味着代理只需更改DEPTH这个数字,模型就能自洽地进行缩放。

这种“通过一个旋钮调整模型规模”的参数化方式,正是使搜索空间可处理的关键所在。

3. program.md

program.md是三个文件中最短的,可以说是最重要的文件。这是我们编辑的文件,其中包含了代理在运行过程中需要知道的所有行为规则。

program.md的结构反映了研究会话的生命周期。它以设置开始,协商运行标签,创建名为autoresearch/<tag>的Git分支,读取范围内的文件,验证数据存在性,并初始化结果文件。然后它描述实验规则,比如代理可以和不能修改的内容,显存是软约束,关键的简洁性标准(在其他条件相同的情况下,更简单的方案更好)。

增加20行hacky代码带来0.001 bpb的改进不值得保留。删除20行代码带来0.001 bpb的改进则绝对值得保留。

然后进入实际的循环。代理被指示使用 uv run train.py > run.log 2>&1 运行训练,且不得使用 tee 或输出流,因为这会淹没代理的上下文窗口。同时被要求使用 grep "^val_bpb:\|^peak_vram_mb:" run.log 提取指标,这只会输出一两行关键信息。

如果 grep 没有输出,说明运行崩溃了,代理需要读取日志最后 50 行并尝试修复问题(但尝试几次失败后应放弃并继续)。每次实验的结果都会记录到 results.tsv 中。

决策规则很简单:如果 val_bpb 改善(数值降低),代理会保留该提交以推进分支。如果没有改善,代理会执行 git reset 撤销提交。如果崩溃,代理会记录错误并尝试其他方法。

program.md 的最后一段定义了 autoresearch 的核心特性,标题为 NEVER STOP。代理被明确指示:无需向你(人类)确认是否继续,无需任何权限,也不需要等待确认。如果代理没有思路了,应该更深入思考,分析失败案例,结合接近成功的尝试,尝试更激进的改动。

循环会一直运行直到我们手动中断。这条指令比仓库中任何一行 Python 代码都更重要。它决定了代理是进行几次实验后询问你是否继续,还是真正实现整夜自主研究。

这与 5 分钟预算没有矛盾。5 分钟预算仅适用于单次实验,一次训练运行。"永不放弃" 指令控制的是外层循环。当一次运行结束后代理记录结果时,会立即启动下一次实验。它会持续不断地启动新的 5 分钟实验,直到你手动中断。

没有任何训练会持续超过 5 分钟。代理只是不断启动新的 5 分钟训练。

现在你已经了解了它的运作原理,让我们开始使用它吧。

设置指南

假设你拥有一块单卡 NVIDIA GPU,且显存足够运行这些实验。默认设置下,24GB 或更高显存的设备都可以正常工作。显存较小的 GPU 需要一些调整,我会在后面详细说明。

步骤 1:安装 uv(仓库使用的 Python 项目管理工具)

uv 比 pip 快得多,且能透明处理虚拟环境。安装完成后,克隆仓库并安装依赖:

code
curl -LsSf https://astral.sh/uv/install.sh | sh

git clone https://github.com/karpathy/autoresearch.git
cd autoresearch
uv sync

这会创建一个 .venv 环境,并安装 pyTorch、Flash Attention、rustbpe、tiktoken、pyarrow 等几个其他包。它会从 CUDA 12.8 的 wheel 源拉取 PyTorch,请确保你的驱动支持该版本。

步骤 2:运行数据准备

这会下载 10 个 ClimbMix 数据块和验证数据块,然后训练我们的 tokenizer。

code
uv run prepare.py

在良好网络环境下大约需要 2 分钟。如果磁盘空间有限,可以通过 --num-shards 4 参数下载更小的数据集。数据和 tokenizer 会被缓存到 ~/.cache/autoresearch/ 目录中。

步骤 3:手动运行一次训练实验

现在你将手动运行一次训练实验,以验证整个流程是否能端到端正常工作。

code
uv run train.py

你将看到模型开始编译(首次编译大约需要30秒),然后出现类似这样的训练输出:step 00050 (8.3%) | loss: 5.123456 | lrm: 1.00 | dt: 240ms | tok/sec: 2,184,533 | mfu: 39.8% | epoch: 1 | remaining: 275s 。

经过大约5分钟的训练,加上最后的评估阶段,你将看到包含val_bpb值的摘要块。这就是你的基准线。

步骤4:将仓库交给代理

实际上这意味着在仓库目录中打开Claude Code或你选择的工具,最好在禁用权限或严格限定仓库访问范围的情况下,用类似以下的提示语引导代理:

code
查看program.md,让我们启动一个新实验。
我们先进行设置。
``

代理将读取program.md,执行设置步骤(创建autoresearch分支和初始化results.tsv),向你确认后开始运行。从这一刻起,你可以让它自行运行。当你返回时,检查results.tsv和autoresearch分支的Git日志。

为较小GPU调整autoresearch

默认配置假设使用H100显卡。如果你使用4090、3090或VRAM小于80GB的设备,需要进行以下调整:

  • 首先降低序列长度:prepare.py中的MAX_SEQ_LEN = 2048是影响VRAM使用的主要参数(因为注意力机制与序列长度呈二次方关系)。在小GPU上尝试设置为512甚至256,并适当增加train.py中的DEVICE_BATCH_SIZE以补偿。这两个参数的乘积决定了每个前向传递的token数量。
  • 降低深度:train.py中的DEPTH = 8是控制模型规模的主要参数。在小GPU上将其降低到4时,模型维度会自动相应减少。
  • 更改窗口模式:WINDOW_PATTERN = "SSSL"使用带状注意力机制,在H100上运行很快,但在消费级GPU上可能较慢(取决于内核实现)。简单使用"L"(始终使用全注意力)通常在小显卡上更快。
  • 降低总批处理大小:TOTAL_BATCH_SIZE = 2**19大约是每个优化器步骤524K tokens。在小GPU上将其降低到2^14(约16K)作为起点。
  • 考虑更换数据集:climbMix是一个涵盖范围广泛的网络语料库。在小模型上,损失曲线会显得嘈杂,bpb数值也难以解释。Karpathy特别推荐使用他自己的TinyStories-GPT4-Clean数据集进行小规模实验。该数据集涵盖范围更窄(儿童故事),因此小模型实际上可以在5分钟内学习生成连贯的内容。

仓库的readme.md文件中已经列出了多个社区分支,这些分支已经完成了消费级GPU的调优工作,你可以查看这些分支。

代理实际发现的内容

描述这个循环的工作原理是一回事,看到它实际产出的内容是另一回事。Karpathy在Twitter上公开了他的深度-12训练结果:代理发现了大约20项改进验证损失的变更,所有变更都适用于深度-24模型。

他事后分析的具体例子包括:向无参数的QK-norm添加可学习标量以增强注意力、对值嵌入应用正则化、扩大带状注意力窗口、修正某些参数组的AdamW beta值、调整权重衰减计划以及修改初始化设置。

这些改进可能不会成为研究论文的亮点,但所有改进都带来了0.001到0.005 bpb的累积提升。

因此,这并不是说AI代理发明了一种全新的架构。而是说,真正研究人员花费数月时间进行的缓慢而耐心的爬坡优化,AI代理可以在几天内完成。结果仍然是那种令人乏味的细节调整,这一直是机器学习领域取得实际进展的主要来源。

最后思考

autoresearch 并没有引入新的模型、新的优化器或新的数据集。它只是在人类研究人员与AI代理之间定义了一种契约关系,并证明这种契约本身已经足够。这种契约类似于:“这里是你无法改变的现实部分、用于评判你的指标、以及预算,在这些规则下,你可以做任何你想做的事情,并告诉我什么方法有效。”

我仍然在思考两个值得深思的问题。第一个是验证集的过拟合问题。如果你对同一固定的验证数据集运行数百次实验,最终代理会开始找到在该数据集上看似有效的调整,但这些调整无法泛化到其他数据。Karpathy 本人在某些会议中将这些结果称为“脆弱”的。

目前除了轮换验证数据(这会破坏可比性)之外,还没有明显的解决方案。

另一个问题是人类角色的转变。如果代理执行实验,人类的贡献将转向塑造搜索空间和规则。这就是 program.md 的内容。它很好地预览了当循环被自动化时,研究工作会是什么样子。

好了,今天就到这里。期待在下一篇文章中再次见到大家!

AI 构建者和研究者

如果这篇文章对你有帮助,请分享它。

免费学习编程。freeCodeCamp 的开源课程已帮助超过 40,000 人成为开发者。立即开始学习

ADVERTISEMENT