news 2026/8/28 17:34:20

Agentic RL后训练动态资源分配:Libra如何提升集群吞吐

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agentic RL后训练动态资源分配:Libra如何提升集群吞吐

在大模型后训练进入 Agent 阶段之后,资源分配从“怎么把模型训练完”变成了“怎么让多个训练任务在一个集群里都按时跑完”。Agentic RL 后训练和普通 SFT 最大的区别是 workload 不稳定:策略模型要反复调用工具、查询知识库、和环境交互,轨迹长度从几百 token 到几万 token 都可能出现。同一个任务在 rollout 阶段可能只需要少量 GPU,在 trainer 阶段又突然需要整卡。如果按传统方式给每个任务固定分 8 卡、固定显存额度,集群会出现排队区堆满任务,运行区却大量 GPU 空转的情况。香港中文大学和恒生大学提出的 Libra,正是把焦点放在后训练资源分配上,公开描述中吞吐最高提升 3 倍。下文不会逐条复述论文公式,而是把“为什么要动态分配、资源分配器怎么设计、怎么用一个最小模拟器验证效果”讲清楚。

1. 先理解 Agentic RL 后训练为什么这么不稳定

1.1 后训练不再只是把文本样本喂进去

传统 SFT 的后训练过程是:准备一批指令和回答,计算交叉熵损失,更新模型参数。每个 batch 的输入输出长度基本可控,显存占用、计算时间、数据读取速度都相对平稳,资源分配可以按“一个 job 固定占几卡”来规划。

Agentic RL 后训练不同。模型不再是简单生成一段文本,而是在一个回合制环境里反复决策:它要决定调用哪个工具,读取工具返回结果,再决定下一步动作。每一步都会产生新的文本和状态,整条轨迹的长度由环境反馈决定。比如一个 agent 在调用搜索接口时返回 8000 token,在下一轮又只返回 50 token,同一个 job 内的显存需求和推理延迟会出现很大毛刺。

训练目标也不再是直接对文本求损失,而是把采样到的轨迹放入策略梯度目标里更新。为了算 advantage,还需要 critic 或 reward model 对每个状态打分;如果使用 PPO 这类方法,还要维护旧策略、做 clip、做 GAE。这些环节都会额外消耗显存、CPU 和内存,而且消耗量跟着轨迹内容变化。

1.2 四个环节的资源画像会按分钟级变化

在一个典型的 Agentic RL 后训练循环里,至少有四个环节在抢资源,而它们各自的资源敏感度差异很大。

环节主要资源波动来源最容易出现的问题
轨迹采样 rolloutGPU/CPU 推理、KV cache、网络工具调用次数、环境响应长度、并发度GPU 空转或推理排队
奖励/验证模型GPU/CPU 推理外部服务延迟、评估 prompt 长度单个慢请求拖慢整批结果
策略更新GPU 计算、显存带宽batch 内轨迹长度方差、是否用梯度检查点显存超限或训练吞吐下降
经验缓存 replay bufferCPU 内存、磁盘长轨迹积压、日志量内存被打满、日志写入慢

因此,只看 GPU 利用率是不够的。一个 job 可能 GPU 利用率很低,但 CPU 上已经有几千条 rollout 在排队;另一个 job 可能 GPU 计算很忙,但显存因为某一条超长轨迹突然被打爆。资源调度必须能同时感知这些维度,否则任何单一指标都会误导决策。

1.3 多任务并发时,静态配额会放大不确定性

单任务训练就算波动大,只要资源够,也能靠排队慢慢跑完。真正让问题恶化的是多个训练 job 共享同一个集群。

假设集群有 8 张卡,Job A 正在做 Agentic RL 后训练,当前处于 rollout 阶段,8 张卡里实际只有 1 张卡在做推理,其余 7 张处于空闲或低负载。Job B 在后面对列里等着申请 8 张卡。静态调度下,Job B 必须等到 Job A 整体结束才能获得资源,即使 Job A 在未来五分钟内都用不到那 7 张卡,它们也不能转给 Job B。结果就是:集群总 GPU 利用率不高,任务排队时间却很长。

Libra 这类资源分配方案要解决的,就是这种“固定配额和实际需求错配”的问题。它把后训练 job 当作一个动态负载,而不是一个提交后就不会变化的黑盒。

2. Libra 的资源分配核心:把任务当成动态可调度负载

2.1 静态预留为什么在 Agentic RL 上失灵

静态预留最典型的做法是:每个 job 申请固定数量的 GPU、固定显存、固定 CPU,调度器只在开始时刻做一次决策,之后不再调整。

这种模型适合计算量均匀的批处理任务。它的优点是简单、可预期、不容易互相影响。但 Agentic RL 后训练有两个特征会破坏这个假设:

  • 需求随时间变化:rollout 和 training 交替出现,工具调用和长文本又会引入尖峰。
  • 需求随内容变化:同样一个模型,在不同环境、不同用户 prompt 下产生的轨迹长度差异很大。

于是固定 8 卡的 job 可能在 60% 时间内只用到 2 卡,却把另外 6 卡锁死;其他 job 想用却申请不到。这属于典型的资源碎片化,也会让队列里的任务越积越多。

2.2 动态调度器只需要四个核心组件

Libra 这类方法的具体实现可以各有不同,但核心思路通常是四件事:观测、预测、规划、反馈。

  1. 观测:实时采集每个 job 的 GPU 使用率、显存水位、CPU 排队长度、rollout 平均步数、tool call 次数。
  2. 预测:根据当前轨迹和历史窗口,预测下一个时间段内这个 job 对资源的需求。
  3. 规划:在总资源有限、每个 job 有最小配额和最大配额约束下,把空闲资源动态分配给需求较高的 job。
  4. 反馈:执行新分配方案后,继续观测指标,如果发现任务被频繁抢占或队列延迟变大,就回调参数。

可以把这四个组件理解成一个闭环控制。调度器不是每秒钟都去抢资源,而是每隔一个固定周期做一次再平衡。这个周期不能太短,否则调度本身会成为瓶颈;也不能太长,否则无法跟上工具调用带来的负载尖峰。

2.3 GPU 卡之外,还要分配显存、CPU、内存和网络

很多集群调度器只认“卡数”,这在实际 Agentic RL 后训练里远远不够。

资源维度单位典型瓶颈不纳入调度的后果
GPU 算力TFLOPS/SM 占用策略更新和 rollout 推理算力不足,训练步数变慢
GPU 显存GBKV cache、模型权重、梯度显存超限,job OOM
CPU 核数vCPUrollout 数据预处理、tokenizerCPU 排队,GPU 空转
主机内存GBreplay buffer、采样结果暂存内存不足,进程被杀
网络带宽GB/s模型并行通信、工具调用通信开销拖慢训练

实际调度中,最好把每个 job 抽象成一组多维资源需求,例如gpu: 8, gpu_mem: 80Gi, cpu: 32, mem: 128Gi,而不是只写gpu: 8。否则会出现显存明明够,但卡数被人占满,导致小显存任务无法调度;或者 CPU 已经排队到几千条,但 GPU 还空在那里等数据。

2.4 如何理解“吞吐最高提升 3 倍”

“吞吐提升 3 倍”在标题里是一个很引人注意的数字,但要正确理解它的适用范围。它通常不是指所有任务、所有集群配置下都能提升 3 倍,而是指在资源竞争明显、job 之间需求互补、静态分配造成大量空闲的场景下,动态分配让集群整体完成工作量更快。

吞吐指标本身也分很多种:

  • 单位时间完成的训练 step 数。
  • 单位时间完成的 rollout 轨迹数。
  • 单位时间完成的 job 总数。
  • 单位时间完成的有效训练量,例如处理了多少 token。

不同指标下的提升幅度会不一样。因此在对比方案时,先明确“吞吐”到底指什么,再看这个指标是否和业务目标一致。Libra 的价值不在于把单卡算力提升,而在于把集群空闲资源利用起来,减少排队和等待。

3. 用最小模拟器验证“固定分卡”和“动态分配”的差距

3.1 最小可行模型:需求曲线加工作量

为了理解资源分配策略,不一定要先搭大规模集群。可以用一个 Python 模拟器建模:每个 job 有一条需求曲线,表示每个时间片内它能用掉多少资源;还有一个总工作量,表示完成它需要消耗多少资源单位。调度器在每时刻决定给每个 job 分配多少资源,实际推进量是分配量和需求量的较小值

下面的模型只用于说明思路,不包含显存、带宽、抢占成本。要放到真实集群,需要再叠加这些约束。

from dataclasses import dataclass @dataclass class Job: name: str demand_curve: list[float] total_work: float JOBS = [ Job("tool-call-heavy", [0.2, 0.1, 0.9, 0.9, 0.9, 0.1], 2.6), Job("long-context", [0.8, 0.8, 0.5, 0.5], 2.0), Job("rag-light", [0.5, 0.5, 0.3, 0.3, 0.3], 1.7), Job("interleaved", [0.4, 0.9, 0.1, 0.9, 0.4], 2.4), ]

这里的demand_curve是每个时间片的最大可用资源,取值在 0 到 1 之间。total_work是完成该 job 需要的总资源单位。如果 job 没完成,曲线会循环复用,用来模拟周期性出现的 rollout 高峰。

3.2 静态平分调度

静态调度的规则最简单:不管需求是多少,始终给每个 job 平均分配资源。

def static_equal(demands): n = len(demands) return [1.0 / n] * n

这种策略的问题是:当一个 job 的需求低于平均份额时,多出来的份额不会被其他 job 使用;当一个 job 的需求远高于平均份额时,它又会因为拿不到更多资源而迟迟无法完成。在真实集群里,这就对应着 GPU 空转和任务排队并存。

3.3 按需求动态分配调度

动态调度可以先保证

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 17:34:15

大模型选型与多模型路由:从任务分类到工程实践

各位做 AI 应用开发的朋友,不知道你们有没有一种感觉:最近这半年,大模型的能力迭代非常快,各家厂商几乎每隔一段时间就会推出新版本。但越是用得多,越会发现一个现实问题——没有哪个模型是万能的。有的模型写代码很强…

作者头像 李华
网站建设 2026/8/28 17:34:14

物理AI从模型竞赛转向经验竞赛:全链路数据基建成为新壁垒

如果要给“Physical AI”这几个字找一个最准的落点,我的判断是:它已经从“模型竞赛”进入“经验竞赛”。 过去两年我们见证了大模型在文本、图像、代码上的爆发,核心范式是“参数够大、算力够多、数据够宽”。但到了机器人、自动驾驶、工业控…

作者头像 李华
网站建设 2026/8/28 17:34:08

碾压同行配图[特殊字符]OKBIYE科研绘图,论文高分的隐形王牌

很多人写论文只死磕正文、查重和文献,却忽略了科研配图才是盲审最直观的加分扣分点。 在整篇论文内容同质化严重的情况下,正文论述、研究思路、文献引用大多大同小异,真正能快速拉开视觉质感、体现学术严谨度的,就是图表可视化呈…

作者头像 李华
网站建设 2026/8/28 17:31:37

C++结构体与模块化开发实践:从零构建控制台电子时钟

1. 项目概述:从零构建一个模拟电子时钟最近在带新人做C项目练习,发现很多朋友对结构体和模块化开发的理解还停留在书本上的“定义几个变量”和“把代码分几个文件”。正好,之前带他们做过一个“模拟电子时钟”的小项目,我觉得特别…

作者头像 李华
网站建设 2026/8/28 17:31:19

学习EPLAN软件笔记三

一、连接及连接定义点(手动)核心:原理图上看到的直线只是「图形预览」;执行【更新连接】之后,才生成带有源、目标、截面积、线号等数据的逻辑连接,才能出接线表、电缆清单。对于两个元件之间在进行水平/垂直…

作者头像 李华
网站建设 2026/8/28 17:28:47

Java服装进销存系统实战:Spring Boot+MyBatis-Plus核心设计与源码解析

简介:进销存系统是企业资源管理的核心,它通过数字化流程管控商品的采购、销售与库存状态,确保业务数据准确、可追溯。其技术原理通常基于经典的三层架构,结合关系型数据库的事务特性与索引优化,保障数据一致性并提升查…

作者头像 李华