MLE-STAR: 机器之心,代码之星

通过搜索与定向优化的机器学习工程智能体

作者:Jaehyun Nam (KAIST), Jinsung Yoon (Google Cloud), 等

机构:Google Cloud & KAIST

本文由第一作者视角进行解读 | 访问作者主页

论文摘要 (Abstract)

用于机器学习工程(MLE)的、基于大型语言模型(LLM)的智能体,能够通过代码生成自动实现机器学习模型。然而,构建此类智能体的现有方法往往严重依赖LLM的固有知识,并采用一次性修改整个代码结构的粗略探索策略。这限制了它们选择有效的任务特定模型以及在特定组件内进行深度探索的能力,例如对特征工程选项进行广泛实验。为了克服这些问题,我们提出了MLE-STAR,一种构建MLE智能体的新方法。MLE-STAR首先利用外部知识,通过搜索引擎从网络上检索有效模型,形成初始解决方案;然后,通过探索针对特定ML组件的各种策略来迭代地优化它。这种探索由分析单个代码块影响的消融研究引导。此外,我们引入了一种新颖的集成方法,该方法使用MLE-STAR建议的有效策略。我们的实验结果表明,MLE-STAR在MLE-bench Lite的Kaggle竞赛中获得了64%的奖牌,显著优于最佳替代方案。

引言:当AI开始为自己打造“利器”

大家好,我是Jaehyun Nam。在数据科学的星辰大海中航行多年,我深知从一个想法到一个高性能的机器学习模型,中间隔着多少不眠不休的夜晚和无数次的试错。这个过程,我们称之为机器学习工程(MLE),它既是科学,也是一门艺术,充满了繁琐的实验、数据处理和模型调优。

近年来,大型语言模型(LLM)的崛起像一道曙光,照亮了自动化这片领域。我们开始思考:能不能让一个“AI导师”来指导我们,甚至代替我们完成这些复杂的工程任务?这就是MLE智能体的雏形——一个能理解任务、分析数据、并最终编写出完整Python代码来解决问题的“AI程序员”。

生活化类比: 想象一下,你是一位想学做菜的新手,但你拥有的不是一本固定的菜谱,而是一位无所不知但有点“固执”的美食家(传统的LLM)。他可能会反复推荐他最熟悉的番茄炒蛋,即使你想做的是法式大餐。而我们想要的,是一个能上网搜寻最新米其林菜单、懂得分析每道菜的关键步骤、并能创造性地融合不同菜系优点的“AI厨神”。

现有的MLE智能体,就像那位固执的美食家。它们严重依赖自身“记忆”中的知识,导致模型选择上偏向于那些常见、通用的方法(比如用`scikit-learn`处理一切表格数据),而忽略了针对特定任务的“独门秘籍”。更重要的是,它们的优化方式很“粗暴”,往往是“推倒重来”,一次性修改整个代码,而不是像真正的专家那样,精准地找到瓶颈,然后“对症下药”。

正是基于这些痛点,我和Google Cloud的同事们一起构想并创造了 **MLE-STAR**。这个名字背后蕴含着我们的核心理念:**S**earch(搜索)和 **TA**rgeted **R**efinement(定向优化)。我们希望它能像一颗冉冉升起的新星,照亮自动化机器学习工程的未来。它不仅会“上网冲浪”寻找灵感,更懂得如何像一位经验丰富的工程师一样,进行细致入微的“代码手术”。

第一乐章:搜索 (Search) - 站在巨人的肩膀上

一个项目的成败,往往在最初的模型选择阶段就已初见端倪。如果选错了方向,后续再多的努力也可能事倍功半。传统LLM在这一步上常常“翻车”,比如在需要复杂深度学习模型的文本分类任务中,它可能会推荐一个简单的逻辑回归模型。这并非因为它“笨”,而是因为它的知识库是静态的,无法跟上日新月异的技术发展。

MLE-STAR的第一步,就是打破这种信息壁垒。我们赋予它一项关键能力:**使用搜索引擎作为工具**。当接到一个新任务时,它不会立刻埋头写代码,而是先去网上“搜一搜”:对于这个特定的任务(比如,图像去噪),当前最先进(SOTA)、最有效的模型是什么?

动画1:模型搜索与初始方案构建

这个动画模拟了MLE-STAR的“搜索”阶段。它首先通过“搜索”找到多个备选模型,然后对它们进行评估,并尝试将表现好的模型融合成一个更强大的初始解决方案。

当前最佳方案: | 性能分: 0

这个过程可以形式化地表示为: \[ \{\mathcal{T}_{\text{model}}^{i}, \mathcal{T}_{\text{code}}^{i}\}_{i=1}^{M} = \mathcal{A}_{\text{retriever}}(\mathcal{T}_{\text{task}}) \] 这里,\(\mathcal{A}_{\text{retriever}}\) 是我们的“检索智能体”,它会返回 \(M\) 个候选模型的信息,每个都包含模型描述 \(\mathcal{T}_{\text{model}}\) 和一个简单的示例代码 \(\mathcal{T}_{\text{code}}\)。这个示例代码至关重要,因为它能帮助LLM快速上手一个它可能从未“见过”的新模型。

拿到这些“武功秘籍”后,MLE-STAR会逐一进行快速验证,生成初步的解决方案脚本 \(s_{\text{init}}^{i}\),并在验证集上跑分。但我们不止于此。我们认为,即使是排名第二、第三的方案,也可能藏有“闪光点”。因此,我们设计了一个**迭代式合并**的流程。

生活化类比: 这就像你找到了几份顶级的牛排食谱。A食谱的腌料配方绝妙,B食谱的煎烤火候控制精准。一个聪明的厨师不会只选其一,而是会尝试将A的腌料用到B的流程中,创造出一份“1+1>2”的完美牛排。

MLE-STAR会从得分最高的脚本 \(s_{\text{init}}^{\pi(1)}\) 开始,然后依次尝试将次优的脚本 \(s_{\text{init}}^{\pi(k)}\) 融合进来,通常是以简单的平均集成(Averaging Ensemble)方式。如果融合后的新方案性能更好,就保留;否则,就放弃。通过这个精巧的设计,我们确保了MLE-STAR的起点,就已经是一个经过深思熟虑、博采众长的强大基线。

第二乐章:定向优化 (Targeted Refinement) - 精准的“代码手术”

有了一个好的开端,接下来就是精益求精的优化过程。传统方法像是在一个黑箱上乱敲,期待好运降临。而MLE-STAR则像一位拿着高精度仪器的外科医生,它需要准确地知道“病灶”在哪里,然后进行精准切除和修复。这个过程分为两步:**目标代码块提取** 和 **代码块优化**。

2.1 找到关键:影响最大的那个“零件”

为了找到影响性能最关键的代码部分,我们引入了经典的**消融研究(Ablation Study)**。MLE-STAR会自动生成一个特殊的脚本,这个脚本会依次“屏蔽”掉解决方案中的不同组件——比如,暂时去掉特征工程、禁用某种数据增强、或者换掉标准化器——然后观察模型性能会下降多少。

动画2:消融研究与目标定位

模拟通过“消融”(暂时移除)不同代码组件来评估其重要性。性能下降最多的组件,就是我们下一步要重点优化的目标。

分析结果: 等待分析...

哪个组件被拿掉后,性能下降得最厉害,就说明它最重要,也最有可能存在优化空间。这个过程由 \(\mathcal{A}_{\text{extractor}}\) 智能体完成,它会分析消融研究的总结报告 \(\mathcal{T}_{\text{ab1}}^{t}\),并从中提取出那个最关键的代码块 \(c_t\)。为了避免重复劳动,它还会参考之前已经优化过的代码块历史记录 \(\{c_i\}_{i=0}^{t-1}\),确保每次都探索新的可能性。

示意图1:MLE-STAR 整体工作流程

此图展示了从初始搜索到循环优化的完整架构,灵感源于论文中的Figure 2。

a) 初始化 任务 -> 搜索 -> 初始方案 b) 目标提取 消融研究 -> 提取代码块 c) 代码块优化 (内循环) 提出计划 Plan k 实施并评估 反馈并更新 外循环:迭代优化不同组件 改进后的方案成为下一次迭代的输入

2.2 循环优化:在“思想实验”中进化

一旦锁定了目标代码块 \(c_t\),真正的“魔法”就开始了。我们启动一个内部循环,让 \(\mathcal{A}_{\text{planner}}\) 智能体针对这个代码块提出一系列的改进计划 \(p_k\)。

它会像一个真正的研究员一样,进行“思想实验”。比如,如果目标是特征工程,它可能会提出:

  • 计划1:“我们试试用k-NN来填充缺失值,而不是简单的中位数。”
  • 计划2:“或者,我们可以创建一些交互特征,比如把‘年龄’和‘消费等级’结合起来。”
  • 计划3:“要不我们对数值特征进行分箱处理,把它变成类别特征?”

对于每个计划 \(p_k\),\(\mathcal{A}_{\text{coder}}\) 会将其实现为新的代码块 \(c_t^k\),替换掉旧的,然后运行评估。这个过程是带有记忆的,\(\mathcal{A}_{\text{planner}}\) 在提出新计划时,会参考之前所有计划的得分: \[ p_k = \mathcal{A}_{\text{planner}}(c_t, \{(p_j, h(s_t^j))\}_{j=0}^{k-1}) \] 这使得探索过程非常高效,它会避免重复失败的尝试,并倾向于在有希望的方向上深挖。经过 \(K\) 次内部迭代后,我们选出其中表现最好的方案,作为本次“代码手术”的最终成果,进入下一次外循环,去寻找下一个可以优化的目标。

动画3:定向优化循环

这个动画展示了针对一个特定代码块(例如特征工程)的迭代优化过程。智能体不断提出新计划,实施并评估,最终保留得分最高的版本。

当前计划: | 性能分: 0.82

最佳性能分: 0.82

第三乐章:集成 (Ensemble) - 众智成城的力量

在机器学习竞赛中,最后的冲刺阶段,高手们往往会使用“集成学习”这一大杀器。单个模型再强,也难免有其偏好和盲点。将多个不同但表现都很好的模型组合起来,往往能取得惊人的效果。

我们想,既然可以集成模型,为什么不能集成“解决方案”呢?于是,我们设计了一个独特的集成流程。MLE-STAR可以并行运行多次,产生多个独立的、经过完整优化的最终解决方案 \(\{s_l\}_{l=1}^{L}\)。然后,我们再次请出 \(\mathcal{A}_{\text{ens_planner}}\) 智能体,它的任务不再是修改代码细节,而是提出宏观的**集成策略**。

动画4:解决方案集成

展示了两个独立的解决方案如何通过一个由智能体提出的集成策略(如加权平均)合并,从而产生一个性能更优的最终方案。

集成策略: 等待中...

最终性能分: ?

它可能会提出这样的策略:

  • “我们对两个方案的预测结果进行简单的投票或平均。”(最基础)
  • “我们进行加权平均,在验证集上搜索最优的权重组合。”(更进一步)
  • “我们把一个模型的输出作为另一个模型的输入特征,进行堆叠(Stacking)。”(更复杂)

和代码块优化一样,这个过程也是迭代的。智能体会根据上一个集成策略的表现,提出新的、可能更好的策略。最终,我们选择表现最佳的集成策略,生成终极版的解决方案。实验证明,这一步能带来显著的性能提升,是MLE-STAR能够频频摘金夺银的关键之一。

守护与展望:那些“看不见”的细节

一个强大的系统,不仅要有锐利的矛,也要有坚固的盾。在开发MLE-STAR的过程中,我们加入了一些重要的“守护模块”,以确保它的行为既稳健又合乎规范。

数据泄漏检查器

我们发现LLM在生成代码时,有时会犯一个致命的错误:**数据泄漏**。比如,它可能会用包含测试集数据的统计量(如均值、方差)来对训练集进行预处理。这在现实中是不可能的,会导致模型在本地验证时看起来很美,一提交到真实测试集上就原形毕露。

示意图2:数据泄漏与修复

展示了错误的数据流(测试集信息污染训练集)和正确的数据流(仅用训练集信息处理测试集)。

之前 (数据泄漏) 训练集 测试集 统计数据 处理后数据 之后 (已修复) 训练集 测试集 统计数据 处理后训练集 处理后测试集

我们的 \(\mathcal{A}_{\text{leakage}}\) 检查器会在每次执行前扫描代码,一旦发现这种不当操作,就会自动修正它,确保所有预处理都遵循正确的流程。

数据使用检查器

另一个常见问题是,LLM可能会忽略掉一些不那么“主流”的数据文件。比如,任务数据除了`train.csv`,可能还有一个包含重要几何信息的`geometry.xyz`文件。LLM可能会图省事,只读取CSV文件。我们的 \(\mathcal{A}_{\text{data}}\) 检查器会核对任务描述和代码,确保所有提供的数据源都得到了充分利用。

结论与展望

通过将外部世界的广阔知识(搜索)与内在的深度反思(定向优化)相结合,MLE-STAR 在自动化机器学习工程领域取得了令人振奋的成果。在严格的MLE-bench Lite基准测试中,它在64%的Kaggle竞赛中赢得奖牌,其中36%是金牌,这远远超过了之前的SOTA方法。

这不仅仅是一个工具的胜利,更是一种理念的胜利。它证明了,未来的AI系统不应是封闭的、自说自话的“黑箱”,而应是开放的、懂得学习和迭代的“工程师”。随着LLM能力的不断飞跃,我们有理由相信,像MLE-STAR这样的智能体,将能自动跟上技术的浪潮,持续地为我们带来更优、更强的解决方案。

我们正处在一个激动人心的时代。或许在不远的将来,数据科学家们能从繁重的工程任务中解放出来,将更多精力投入到更具创造性的思考中——而那些复杂的代码实现,就放心地交给像MLE-STAR这样可靠的“AI伙伴”吧。

动画5:探索解决方案空间

生活化类比:想象无数微小的尘埃,在空中随一阵看不见却又和谐有序的风飘动,形成了优雅的涡流和线条。这代表了MLE-STAR在广阔而复杂的解决方案空间中进行高效、有序探索的过程。

技术附录:核心算法与公式

本部分为希望深入了解MLE-STAR技术细节的读者提供更形式化的描述。

1. 问题定义

我们的目标是找到一个最优的解决方案脚本 \(s^*\),使其在给定的评分函数 \(h\) 下得分最高。形式化地,\(s^* = \arg\max_{s \in \mathcal{S}} h(s)\),其中 \(\mathcal{S}\) 是所有可能的Python脚本构成的空间。

2. 初始解生成 (Algorithm 1)

此阶段的核心是搜索与合并。

  1. 搜索: 使用 \(\mathcal{A}_{\text{retriever}}\) 获取 \(M\) 个候选模型及其代码:\(\{\mathcal{T}_{\text{model}}^{i}, \mathcal{T}_{\text{code}}^{i}\}_{i=1}^{M} = \mathcal{A}_{\text{retriever}}(\mathcal{T}_{\text{task}})\)。
  2. 评估: 对每个候选模型生成脚本 \(s_{\text{init}}^{i}\) 并计算其性能 \(h(s_{\text{init}}^{i})\)。
  3. 合并: 将脚本按性能降序排列。以最佳脚本 \(s_{\text{init}}^{\pi(1)}\) 为基础 \(s_0\),依次尝试用 \(\mathcal{A}_{\text{merger}}\) 智能体融入次优脚本 \(s_{\text{init}}^{\pi(k)}\)。合并操作 \(s_0 \leftarrow \mathcal{A}_{\text{merger}}(s_0, s_{\text{init}}^{\pi(k)})\) 只有在性能提升时(即 \(h(s_{\text{new}}) > h(s_0)\))才被接受。

3. 定向优化 (Algorithm 2)

这是一个嵌套循环结构。

  • 外循环 (T步):
    1. 消融研究: \(\mathcal{A}_{\text{abl}}\) 生成并执行消融脚本 \(a_t\),得到结果 \(r_t\)。
    2. 目标提取: \(\mathcal{A}_{\text{extractor}}\) 分析总结后的消融报告 \(\mathcal{T}_{\text{ab1}}^{t}\),并考虑历史记录 \(\{c_i\}_{i=0}^{t-1}\),提取出影响最大的代码块 \(c_t\) 和初始改进计划 \(p_0\)。 \[ c_t, p_0 = \mathcal{A}_{\text{extractor}}(\mathcal{T}_{\text{ab1}}^{t}, s_t, \{c_i\}_{i=0}^{t-1}) \]
  • 内循环 (K步):
    1. 计划生成: \(\mathcal{A}_{\text{planner}}\) 根据历史尝试 \(\{(p_j, h(s_t^j))\}_{j=0}^{k-1}\) 提出新计划 \(p_k\)。
    2. 代码实现与评估: \(\mathcal{A}_{\text{coder}}\) 将计划 \(p_k\) 应用于 \(c_t\) 生成 \(c_t^k\),替换后形成新脚本 \(s_t^k = s_t.\text{replace}(c_t, c_t^k)\),并评估其性能 \(h(s_t^k)\)。
    3. 更新: 内循环结束后,将 \(K\) 个尝试中表现最好的脚本作为外循环的输出 \(s_{t+1}\)。

4. 最终集成 (Algorithm 3)

对 \(L\) 个并行生成的最终解 \(\{s_{\text{final}}^l\}_{l=1}^L\) 进行集成。

  1. 策略规划: \(\mathcal{A}_{\text{ens_planner}}\) 提出一系列集成策略 \(e_r\),同样利用历史表现 \(\{(e_j, h(s_{\text{ens}}^j))\}_{j=0}^{r-1}\) 作为反馈。
  2. 集成实现: \(\mathcal{A}_{\text{ensembler}}\) 根据策略 \(e_r\) 将 \(L\) 个解合并成一个脚本 \(s_{\text{ens}}^r\)。
  3. 选择最优: 最终输出在所有集成策略中表现最好的脚本 \(s_{\text{ens}}^*\)。

示意图3:模型选择对比 (AIDE vs. MLE-STAR)

此图基于论文Figure 4,直观展示了MLE-STAR通过搜索能力,倾向于使用更现代、更强大的模型架构。

80% 0% ResNet EfficientNet ViT AIDE MLE-STAR