Aleph Alpha推出Savanna:以代码训练模型,提升效率与可追溯性!
研究
作者:Michael Barlow
发布时间:2026年5月22日
引言
模型训练发展迅速,新的阶段不断加入训练流程,现有阶段也变得更加复杂,这使得模型训练成为一项工程挑战,主要有以下三个关键原因。其一,复杂度增加意味着出错的可能性增大。数据、代码或配置中的错误或不一致可能导致整个训练运行失败或偏离预期。其二,失败的成本不断上升。模型规模越来越大,GPU价格上涨,每次运行处理的数据也越来越多。当消耗数千个GPU小时时,失误的代价可不小。其三,也是最具挑战性的问题是组织协调。这种复杂度早已超出了个人的能力范围,因此像我们这样的实验室组建了大型的专业团队。随之而来的问题是如何协调这些团队。团队成员如何在自主探索其专业领域最新研究的同时,将他们的更改集成到生产流程中,而不破坏流程或干扰彼此的工作?他们又如何确保各个阶段的改进最终能转化为更优秀的模型?传统的手动模型训练流程无法很好地解决这些问题。
手动模型训练的隐性成本
从宏观层面看,模型训练似乎很简单:先进行预训练以学习互联网上的知识,然后进行后训练以学习遵循指令。但实际上,第一次尝试很难训练出优秀的模型。找到合适的数据组合、架构和训练方案是一个迭代的、计算密集型的过程,需要通过评估来指导,以下每个步骤的成本都与相对的GPU消耗相关。这些组件中的每一个都足够复杂,需要多个专门的团队来负责。例如,现代的后训练包括监督微调(SFT)阶段和强化学习(RL)阶段。SFT和RL需要不同的技能和工具,但必须集成起来才能训练出模型。在手动实验室中,单个模型在训练流程中的经历如下:数据团队完成了新的数据组合,并通过Slack将数据库路径发送给预训练团队,预训练团队随即启动为期数周的训练。两周后,存储配额已满,训练运行崩溃。由于文件系统是手动管理的,没人确定是否可以删除那个文件名中带有 `do_not_delete` 的30TB数据集,预训练团队在解决这个问题时,GPU只能闲置。最终重新启动时,他们凭借记忆和Slack聊天记录重建原始设置,祈祷没有忘记设置某个标志。这就是第一个隐性成本:每一个手动步骤都可能导致人为错误。预训练最终完成后,预训练团队将检查点交给SFT团队。为了找到合适的方案,SFT团队手动启动一系列不同配置和数据组合的并行训练。随着检查点不断生成,团队对每个检查点运行评估脚本,并在Slack上分享结果和分析。有些方案看起来很有前景,有些则不然,他们会重复这个过程几周,直到确定一个合适的方案。不知不觉中,团队重复了几个月前为上一个预训练检查点做过的一些实验。这就是第二个隐性成本:团队会遗忘之前的经验教训。对于超参数的当前值,没有持久的记录说明其背后的原因;数据组合与其组成数据集之间没有正式的关联;模型与生成它的训练方案之间也没有明确的归属关系。在手动实验室中,这些信息分散在Slack、文件系统、实验管理器和各种维基页面中,随着时间的推移很容易丢失。SFT团队将检查点交给RL团队,RL团队以此为基础启动训练。最终模型的表现不佳。是RL方案对上一个月的SFT检查点过拟合,还是SFT检查点本身有问题?经过两周的调试,RL团队确定是后者的问题。由于两个团队都无法执行对方的阶段,每个团队都只针对自己负责的流程部分进行优化,而不是考虑最终的模型。而且由于集成是手动交接,这种交接很少进行,每次都需要花费一个月的时间来解决差异。这就是第三个隐性成本:手动、不频繁的交接会分散团队的所有权。显然,手动模型训练无法应对规模的增长,而自动化并不是唯一缺失的环节。这些隐性成本都源于同一个根本问题:训练流程只存在于团队成员的脑海中,而没有形成一个共享的、持久的产物。为了实现规模化,训练流程本身需要成为一个可处理的、团队可以协作的对象。
介绍:以代码形式进行模型训练
我们的模型工厂代号为Savanna,它以命令式代码实现了整个模型训练流程和处理过程。我们将其称为“以代码形式进行模型训练”(Model Training as Code,MTaC)。以下是一个简单的Savanna后训练流程的伪代码示例:
async post_train(config: PostTrainConfig) -> PostTrainEvaluation: sft_checkpoint = await sft(config.sft) sft_eval = spawn evaluate(config.eval, sft_checkpoint) rl_checkpoint = await rl(config.rl, sft_checkpoint) rl_eval = spawn evaluate(config.eval, rl_checkpoint) return PostTrainEvaluation(await sft_eval, await rl_eval)将训练流程转化为代码有三个好处:可组合性、共识和可追溯性。1. **可组合性**:可组合性源于将手动步骤表示为具有类型化输入和输出的函数,这样就可以围绕这些函数构建抽象,并将它们组合成一个端到端的流程,只需一键即可运行。修改流程就像编辑一个函数一样简单,像评估中间检查点这样的重复性工作可以通过for循环自动化,测试也很直接,因为可以使用不同的参数运行流程的子集或缩小版本。2. **共识**:共识来自版本控制。主分支代表了团队对如何训练模型的集体最佳理解。代码包含了完整的训练方案,因此在启动训练运行时,无需重建设置或担心忘记设置标志。3. **可追溯性**:可追溯性来自代码注释和提交历史。这些记录了导致主分支的经验教训和决策。过去的训练运行仍然可以重现,因为生成它们的代码被固定在一个提交中,可以检出并重新运行。当任何团队都可以自行启动完整的训练流程时,他们就可以运行其他团队负责的阶段,并对整个模型进行迭代,而不仅仅是自己负责的部分。实验室在扩大规模时通常会按时间顺序分解模型训练,每个团队负责流程的一个阶段。MTaC开启了基于能力分解的可能性,即团队可以从头到尾负责模型的一种行为,如多语言能力。小步集成,频繁集成
将训练流程转化为代码后,标准的代码协作最佳实践就可以应用了。要充分发挥MTaC的优势,就需要遵循这些实践。其中最重要的是基于主干的开发,即更改尽快以小增量合并到 `main` 分支,这样团队就可以尽早在彼此的工作基础上进行构建,如果方法错误也能快速失败。如果将更改累积在长期分支中,就会像以前一样产生集成成本。
使用Savanna
Savanna托管在GitHub上,其持续集成(CI)是模型训练的入口。你可以通过推送到分支或从GitHub UI手动启动运行来触发CI。训练我们的最佳模型就像在 `main` 分支上触发CI一样简单。我们还在拉取请求上使用CI,通过小规模的端到端训练运行快速验证流程。这个过程在5分钟内完成,因此为Savanna做贡献不会感觉很慢,这也让我们对更改有信心。为了检测流程中的语义回归,我们每晚运行一次大规模的端到端训练测试,通过确保生成的模型在评估套件中取得可衡量的改进来验证训练逻辑。MTaC通过 `git blame` 提供决策追溯,Savanna在此基础上扩展了工件追溯。运行是封闭的,所有非代码工件(如数据、模型和分词器)都是不可变的,并在注册表中进行版本控制,因此你可以确保每次都能得到相同的结果。当你启动一个运行时,引用的工件、训练日志、指标和评估结果都与该运行和生成的检查点相关联,这样你就可以轻松地将输出归因于输入。要确定哪些模型是在特定数据集上训练的,你可以使用工件追溯图,而不是在Slack中搜索。Savanna使大规模运行变得容易,但要改变这些运行的样子,需要能够在较小的规模上对流程的各个方面进行实验性修改,包括数据、超参数、流程步骤、环境、分片拓扑等。在Savanna中,进行实验就像将更改推送到分支并从那里运行CI一样简单。如果你想尝试一个新的数据集,可以将其添加到消融训练配置中并运行CI。如果评估结果显示有改进,你可以将此更改合并到 `main` 分支,使其成为下一次大规模运行的一部分。超参数搜索也很容易。由于训练流程只是一个函数,你可以通过编程方式多次调用它,使用不同的参数。例如,以下是一个实验,用于找出前面所示后训练流程中SFT和RL的最佳学习率:
async post_training_learning_rate_experiment(config: PostTrainConfig) -> str: post_train_runs = [] for sft_learning_rate in (1e-4, 1e-5): for rl_learning_rate in (1e-4, 1e-5): run_config = config .with_sft_learning_rate(sft_learning_rate) .with_rl_learning_rate(rl_learning_rate) post_train_runs.append(spawn post_train(run_config)) post_train_evaluations = gather post_train_runs experiment_report_url = create_report(post_train_evaluations) return experiment_report_urlSavanna会自动编排搜索过程,并将最终结果整理成报告供你分析。以下是这个实验在Savanna工作流引擎UI中的可视化展示。蓝色节点表示“正在运行”,橙色节点表示“等待缓存”。虽然我们调用了四次 `post_train`,但SFT阶段只会运行两次:Savanna的工作流引擎会识别出哪些阶段具有相同的输入,并在相应的运行阶段完成后从缓存中读取其输出。这让你可以启动修改流程多个方面的搜索,而不用担心冗余计算的组合爆炸问题。对于预训练运行或长时间运行的RL任务,我们会逐步生成并评估检查点,以便更好地了解模型在训练过程中的变化。训练完成后,Savanna会自动在我们的基准测试套件上评估模型,并将所有结果和指标收集到一个运行报告中。Savanna还会自动更新我们的模型排行榜,我们将其展示在海德堡总部的大屏幕上,这样当我们训练出新的最佳模型时,每个人都能一同感受这份喜悦。Savanna的工作原理
当你触发一个运行时,Savanna会在我们选择的工作流引擎Flyte上启动一个作业,Flyte在Kubernetes中运行。Flyte提供了一种方便的方式来运行任意任务,支持持久执行、排序、并行处理、重试、缓存,并提供一个UI来可视化运行过程。我们将模型和数据工件不可变地存储在我们的本地对象存储中,并在Weights & Biases中跟踪它们的版本。这使我们能够轻松分配清理策略,保持存储系统的整洁,并提供一个UI来交互式地探索工件追溯。然后,我们将这些数据流式传输到我们的Kubernetes GPU集群进行训练。在训练过程中,我们的作业会将指标记录到我们的监控系统中,以便实时跟踪进度和性能,如果需要干预,还会发送警报。
Savanna对我们有何帮助?
我们知道,随着领域的发展,模型训练的复杂度只会不断增加,组织协调的挑战也会随之增大。MTaC使我们能够将组织协调的复杂度转化为代码,从根本上改变了我们的工作方式。在日常工作中,我们的迭代速度更快了。我们的大部分工作是小规模的实验和搜索,Savanna自动化了以前手动启动和评估的过程。现在,我们可以将精力投入到分析结果和设计下一个实验中。对于单次大规模运行,情况则有所不同。在最近一次大规模预训练运行中,我们多次恢复训练,以便根据自动化的中间评估结果调整设置。每次重新启动都快速且风险低,因为MTaC提供的共识意味着无需重建设置或担心忘记设置标志。而且由于重新启动很容易,不需要每次都是同一个人操作,所以任何在场的人都可以安全地接手。从更高层面来看,MTaC使我们能够组建多个以能力为导向的后训练团队,这些团队从头到尾负责模型某种行为的集成和改进。例如,我们的多语言团队正在通过构建SFT数据集、RL环境和评估套件,使模型在德语语言和文化方面表现出色。自从采用Savanna并融入工程文化以来,我们作为一个组织的学习速度显著提高。随着我们的训练流程变得更加复杂,团队规模不断扩大,这种方法的价值也越来越凸显。展望未来,我们认为MTaC是自动研究的关键推动因素。由于我们的整个训练流程都以代码形式存在,一个大语言模型(LLM)代理可以自主读取、修改和运行它,我们现在已经开始探索这一可能性。我们希望有一天,我们的模型能够通过Savanna实现自我改进。
致谢
本文由Michael Barlow撰写。这项工作反映了Aleph Alpha研究团队众多贡献者的集体努力,是他们让Savanna得以实现。感谢Martin Reinhardt、Dominik Kellner和Jordan Sassoon提供的宝贵反馈,这些反馈塑造了这篇博客;感谢Paige Reddington和Noé Beckerle Vallejo让文章更具可读性。
联系信息
Speyerer Straße 14
69115 海德堡
Wallstraße 16
10179 柏林
Weiherstraße 26
95448 拜罗伊特
Einsteinstraße 174
81677 慕尼黑
法律声明
* [ 隐私政策 ](/en/privacy/)
* [ 版权声明 ](/en/imprint/)
社交媒体
* [ LinkedIn (在新窗口中打开) ](https://de.linkedin.com/company/aleph-alpha)
* [ X (在新窗口中打开) ](https://x.com/Aleph__Alpha)
* [ GitHub (在新窗口中打开) ](https://github.com/Aleph-Alpha)
咨询方式
* [ 联系我们 ](/en/contact/)
* [ 支持 (在新窗口中打开) ](https://supportportal.aleph-alpha.com)
* [ 职业机会 (在新窗口中打开) ](https://jobs.ashbyhq.com/AlephAlpha)
版权所有 © 2026 Aleph Alpha GmbH
