TL;DR
Molt 是一个 agentic-first、纯 PyTorch-Native 的强化学习框架:
- 约 9,000 行核心 RL 代码,你能一口气从 CLI 追到执行分支;
- 却能训练从 Qwen3.5-397B 到 GLM-5.2 753B 这样的超大规模 MoE;
- 整个栈只有三个 PyTorch 原生组件:Ray(编排)· vLLM(rollout)· NVIDIA AutoModel + FSDP2(训练),全程不依赖 Megatron;
- 智能体就是你写的一段 Python,奖励也是 —— 多轮工具、多模态 VLM、LLM-as-judge 全是一等公民。
代码:https://github.com/NVIDIA-NeMo/labs-molt
技术报告: https://www.researchgate.net/publication/409325071_Molt_A_Scalable_PyTorch-Native_Training_Framework_for_Agentic_Reinforcement_Learning
一、先说痛点:为什么又要造一个 RL 框架?
如果你真的拿大模型跑过 agentic RL,大概都体会过这种无力感:
想验证一个想法 —— 换个奖励、加个工具调用、调一下 off-policy 的处理方式 —— 结果打开框架一看,五万行起步,和 Megatron 深度缠绕,想改一行得先啃一周源码,改完还不确定有没有踩到隐藏的控制流。
主流框架为了「什么都能做」,把复杂度堆到了研究者读不动、也不敢动的地步。但研究的本质是快速试错:你需要的是一个能看懂、改得动、又不掉规模的框架。
Molt 就是奔着这个矛盾去的:把 agentic RL 做小,但不做弱。
二、Molt 是什么
一句话:智能体即程序,训练器只是一个可训练的 actor,奖励是你写的任意 Python。
它把一个完整的 RL 后训练系统压缩到三个概念上:
- 一个 agent API(Gymnasium 风格的
Env/ChatAgent); - 一个可训练 actor(PyTorch + AutoModel/FSDP2);
- 一条异步循环(Ray 编排 rollout ↔ training)。
就这些。没有 Megatron,没有一层套一层的抽象,没有你追不到底的隐藏调度。
三、架构:三个盒子,一条异步循环

整个运行时就是 Ray Runtime(全异步) 下的四块,靠一条异步循环串起来:
1、 vLLM Router / Rollout —— 高吞吐生成,连续批处理,专家并行(EP 可达 256),负责把 token 路由到各个 vLLM engine;
2、 Agent(Environment / ChatAgent) —— 你的程序:Gymnasium API、多轮、工具、VLM、打分器、模拟器、API server;
3、 Ray Queue(Agent → Trainer) —— 缓冲轨迹、调度负载、背压与容错;
4、 RL Trainer(Single Actor) —— 计算 advantage、更新策略,跑在 PyTorch / FSDP2 / NVIDIA AutoModel 上。
数据流是 token-first 的:token id、logprob、action range、reward、多模态张量,从 rollout 到 training 全程对齐。而 权重同步是异步的(NCCL),trainer 更新完的权重异步刷回 vLLM router。
一句话概括这张图右下角的那颗星:Scales to Frontier MoE —— DeepSeek-V3,EP = 256,1T 级 MoE 直接跑在 vLLM 上。
四、核心设计:轻在哪,硬在哪
4.1 Agentic-first:智能体即程序
多数框架把「多轮 / 工具 / 多模态」当成事后拼接的插件。Molt 反过来:agent 就是你写的那段 Python,框架只负责在它外面跑异步的 rollout↔train 循环。
奖励?任意 Python 都行 —— 规则、启发式、LLM-as-judge、工具返回、模拟器信号。而且 LLM-as-judge 的调用会走回同一批驱动 rollout 的 vLLM engine,不用你再单独起一套推理。
# Agent API (Gymnasium 对齐)
obs, info = env.reset(seed)
for t in range(T):
action = agent.act(obs, info)
obs, reward, done, info = env.step(action)
也支持 OpenAI/Anthropic 接口黑盒访问环境。
Molt 会自动追踪背后的 token in token out 路径。
from openai import AsyncOpenAI
from molt.agents import ChatAgent, ChatAgentRunner, ChatContext, Result
class MyAgent(ChatAgent):
async def run(self, ctx: ChatContext) -> Result:
# ctx.base_url carries the session id and auto-captures the token
# trace — no extra_body, no logprobs=True, no session plumbing.
client = AsyncOpenAI(base_url=ctx.base_url, api_key=ctx.api_key)
resp = await client.chat.completions.create(
model=ctx.model_name,
messages=[{"role": "user", "content": ctx.prompt}],
max_tokens=ctx.sampling_params.max_tokens,
temperature=ctx.sampling_params.temperature,
)
return Result(reward=grade(resp.choices[0].message.content, ctx.label))
class AgentRunner(ChatAgentRunner):
def __init__(self):
super().__init__(MyAgent)
4.2 纯 PyTorch 栈:Ray + vLLM + AutoModel,不碰 Megatron
- Ray 管放置和异步队列 —— 这就是整个运行时;
- vLLM 管 rollout —— 连续批处理、高吞吐、动态扩缩;
- NVIDIA AutoModel + FSDP2 管训练 —— MoE-native、TE 融合注意力、自定义并行化器,全程纯 PyTorch。
没有 Megatron 依赖,意味着你能把训练侧的每一步都读懂并改动,而不是隔着一层黑箱。
4.3 规模:从 397B 到 753B
轻量不等于跑不动大的。同一套约 9K 行的代码:
- TP · EP · CP(可选 DP)并行,通信/计算重叠;
- 已在 Qwen3.5-397B 上验证;
- 一路扩到 GLM-5.2 753B 级 MoE;
- 极限规模上,DeepSeek-V3 跑在
--fsdp.ep_size 256,最大 actor 支持优化器 CPU offload。
从单卡实验到千亿级 MoE,同一份代码,平滑扩展。
4.4 训推一致性:vllm_kl 与重要性采样矫正(硬核)
这是 Molt 我最想单独拎出来讲的部分,也是异步 RL 里最容易翻车、最难 debug 的地方。
异步 / partial rollout 会让 训练侧(FSDP actor 重算)的 logprob 和 推理侧(vLLM 生成时)的 logprob 产生偏差 —— 因为算子不同、还有一次 HTTP router 观察不到的权重切换。
Molt 用一个专门的指标 vllm_kl(= mean(rollout_logprob − actor_logprob),在 action token 上)把这个失配量化出来,并用逐 token 的重要性采样比 pi_train / pi_rollout 去矫正它。
矫正被拆成两个正交的旋钮:
--algo.advantage.is_correction_level {off, token, seq, geo}—— 被门控比值的粒度;--algo.advantage.is_correction_mode {mask, clip, trunc}—— 出带后怎么处理。
默认的 geo × mask(几何均值过滤整条 + 存活 token 用逐 token IS 权重)对应业界的 seq-mask-tis;token × trunc/mask 覆盖 TIS / IcePop;seq/geo 则对应 masked importance sampling 一脉。这套东西的存在,本身就说明 Molt 是被「真的拿去训大模型」打磨出来的,而不是一个玩具。
4.5 MoE 路由稳定性:R3
MoE 训练最隐蔽的坑之一:vLLM 和 actor 把同一个 token 路由到了不同的专家,导致训推 logprob 悄悄发散。Molt 提供:
- Router Replay(R3):捕获 rollout 时 vLLM 的逐 token top-k 专家选择,在训练 forward 里原样回放,让训练和 rollout 的路由对齐;
- Router Freeze:直接冻住 gate/router 权重,从源头消除漂移。
4.6 全异步 rollout
--train.async_queue_size解耦 rollout 与 training;--train.partial_rollout_enable让生成在权重同步时用 vLLM pause/resume 继续,和训练重叠;- 想严格 on-policy?一个 flag 切回同步。
五、能力矩阵
| 维度 | 支持 |
|---|---|
| 训练范式 | SFT + 全套 RL |
| Estimator | REINFORCE / RLOO / GRPO / DR-GRPO / PPO(GAE)/ on-policy 蒸馏 |
| 模态 | 文本 + 多模态(VLM,含图像) |
| 交互 | 多轮工具调用、VLM 环境、LLM-as-judge |
| 并行 | TP · EP · CP(·DP),优化器 / 全参 CPU offload |
| 稳定性 | IS 矫正(vllm_kl)、R3 路由回放、Router freeze |
| 已验证 chat template | Qwen3.x、Nemotron Omni、Kimi、GLM、Gemma、DeepSeek |
六、和 verl / slime / OpenRLHF 比,Molt 的位置
不是说别的框架不好 —— verl / slime / OpenRLHF 都很强。Molt 的差异化只有一句:
别人几万行、深绑 Megatron;Molt 约 9K 行核心 RL 代码、纯 PyTorch,还是能扛到几百 B MoE。
它不追求「功能最全」,追求的是 「读得懂、改得动、又不掉规模」 这个别人很少同时给到的组合。对研究者来说,这往往比多几个开关重要得多。
七、快速上手
python3 -m molt.cli.train_rl_ray \
--actor.model_name_or_path /path/to/automodel \
--data.prompt_dataset /path/to/prompts.jsonl \
--train.agent_path examples/python/agents/math.py \
--vllm.num_engines 2 --vllm.tensor_parallel_size 2 \
--rollout.batch_size 128 --train.batch_size 128 \
--algo.advantage.estimator reinforce \
--fsdp.attn_implementation te \
--ckpt.output_dir ./ckpt/rl
SFT 走同一套 AutoModel/FSDP2 加载路径;想上几百 B 的 MoE,把 --fsdp.ep_size / cp_size 调上去即可。
仓库里 examples/scripts/ 有从 Qwen3-4B 到 397B/753B 的现成 recipe。
八、这个框架适合谁
- 你想从想法直达实验,而不是先和一个五万行、绑 Megatron 的栈搏斗;
- 你在做 agentic / 多轮 / 多模态 RL,需要奖励是任意 Python、工具和 judge 都能直接塞进去;
- 你要训几百 B 的 MoE,但又想保留「整份代码读得懂、改得动」的能力;
- 你在意训推一致性这种异步 RL 的深水区问题,想要一个把 vllm_kl / IS 矫正 / 路由回放当一等公民的框架。
结语
Molt 的设计信条很简单:人能一遍读懂的代码优先;智能体是程序,训练器是一个 actor,奖励是 Python。 几百 B 不该是重型框架的专利,这一次,约 9K 行就够了。
如果它帮到了你的研究,欢迎点 star、提 issue、引用技术报告。