news 2026/10/15 16:49:42

Molt自定义奖励函数完整指南:LLM-as-Judge、打分器与多轮工具实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Molt自定义奖励函数完整指南:LLM-as-Judge、打分器与多轮工具实战

【免费下载链接】labs-molt

A scalable, agentic-first, and HuggingFace-native RL framework for research (9k lines).

项目地址:https://gitcode.com/gh_mirrors/la/labs-molt
点击查看免费下载

Molt 是一个 agentic-first 的强化学习(RL)训练框架,用约 9.2K 行 Python 代码打通了 vLLM 推理、Ray 异步队列和 PyTorch/FSDP2 训练。在 Molt 里,"奖励函数"不需要任何特殊接口——它就是你在 Python 里写的任意一段逻辑:规则打分器、LLM-as-Judge 大模型评委、多轮工具调用环境,都统一收敛为一个Result(reward=...)返回值。本文带你用最少代码掌握 Molt 自定义奖励函数、打分器与多轮工具的实战写法。

一、为什么 Molt 的奖励函数这么自由?

传统 RL 框架通常要求你把奖励模型注册成独立组件,而 Molt 的设计是"Agent 即程序,Trainer 只是一个 Actor":

  • 你的环境/代理继承Env或ChatAgent,在step()/run()里执行任意 Python 代码;
  • 返回Result(reward=...)后,框架自动完成 token 对齐、轨迹累积、优势估计等所有脏活;
  • 甚至可以让评委模型回调正在 rollout 的同一组 vLLM 引擎做 LLM-as-Judge,不用额外部署推理服务。

整条契约定义在 molt/agents/base.py 中,Result类(molt/agents/base.py#L105-L114)只强制一个字段:reward必须是标量,其余全是可选增强。

二、单轮打分器:一个 step() 函数即可

最简单的奖励函数是"规则打分器"。Molt 内置的数学环境 examples/python/agents/math.py 只有 20 行有效代码:

class MathEnv(Env): async def step(self, state) -> Result: prompt, action, label = state.get("observation_text", ""), state["action_text"], state.get("label") or "" result = await asyncio.to_thread(_GRADER.score_response, prompt + action, prompt, label) reward = torch.tensor(float(result.get("reward", 0.0)), dtype=torch.float32) return Result(reward=reward, info={"math_exact": reward})

关键点:

  1. state字典由框架喂给你:observation_text(对话上下文)、action_text(模型本轮生成)、label(数据集里的标准答案);
  2. 打分逻辑放在线程里(asyncio.to_thread),避免阻塞 rollout 的 asyncio 事件循环;
  3. info里的数值会自动变成监控指标,比如math_exact准确率、missing_answer缺失率,训练时直接可见。

配套的打分器 examples/python/utils/math_grader.py 采用两级答案等价判断:先做字符串归一化 + 精确匹配,再走 sympy 符号等价,所以\frac{1}{2}和0.5都能被正确判分,且sympy缺失时优雅降级。

💡自定义你的打分器:复制 math.py 改两处即可——step()里换成你自己的判分逻辑(正则、执行代码、比对结构),再把启动参数--train.agent_path指向你的文件。

三、LLM-as-Judge:把大模型当评委

当任务没有标准答案(开放式问答、代码评审、对话质量)时,规则打分器失效,需要 LLM-as-Judge。Molt 对此有两层支持:

3.1 通过 ChatAgent 调用同一组 vLLM 引擎

ChatAgent路径(molt/agents/chat_agent.py)会在会话地址下自动拉起一个 OpenAI/Anthropic 兼容的 FastAPI 服务。你在代理里用标准的AsyncOpenAI客户端发起第二次请求,把"模型回答 + 评分提示词"发给它,让模型自己打分:

class JudgeAgent(ChatAgent): async def run(self, ctx: ChatContext) -> Result: client = AsyncOpenAI(base_url=ctx.base_url, api_key=ctx.api_key) resp = await client.chat.completions.create(model=ctx.model_name, messages=list(ctx.messages), ...) judge = await judge_with_same_engine(client, resp.choices[0].message.content) return Result(reward=judge_score, info={"judge": judge_score})

因为评委调用走的是 rollout 用的同一批 vLLM 引擎,零额外 GPU 成本;参考最小实现见 examples/python/agents/chat_minimal.py。

3.2 把打分信号交给score做动态过滤

Result还有一个score字段(默认等于reward)。训练时开启:

--algo.dynamic_filtering_enable --algo.dynamic_filtering_range 0.0 1.0

框架会按代理的 score 过滤低质量样本再进梯度计算。让评委模型的score输出 0/1 的"是否通过"判断,配合reward输出细粒度分数,是 LLM-as-Judge 场景的常见组合。

四、多轮工具调用实战:Python 沙箱执行器

最有代表性的示例是 geo3k 视觉数学环境 examples/python/agents/geo3k.py:模型可以反复调用python_executor工具验算,最终在<answer>中提交答案才结算奖励。

奖励设计的三个要点:

  1. 过程不奖励,终点才结算:工具轮返回Result(reward=0.0, observation=工具输出, terminated=False),只有模型给出最终答案或轮数耗尽时(geo3k.py#L169-L219)才调用_final_reward()对整条轨迹判分;
  2. 提交答案即终止:防止"答完又反复验算"的刷长度行为(length-hacking),代码注释中明确标注了这一失败模式;
  3. 沙箱安全:工具执行器 examples/python/tools/python_executor.py 用一次性临时目录 + 硬超时(默认 10 秒)+ 内存上限(默认 1GB)运行用户代码,跑飞了也不会卡死 rollout。

多轮奖励天然支持过程奖励 + 结果奖励:你可以在每一轮step()里给小分(比如格式正确 +0.1),最后一轮给大头(答案正确 +1.0),框架会自动累加为trajectory.reward。

五、奖励整形参数速查

代理返回的原始 reward 在进入损失函数前,还可被框架统一整形(定义见 molt/cli/train_rl_ray.py):

参数作用典型用法
--reward.clip_range奖励裁剪范围,默认(-10, 10)防止评委模型输出异常大分数
--reward.overlong_buffer_len+--reward.overlong_penalty_factorDAPO 式超长惩罚:在max_len最后 B 个 token 内线性升压抑制模型用废话填满上下文
--reward.stop_properly_penalty_coef截断轨迹的奖励乘系数 C∈[0,1](负值直接替换为 C)惩罚答到一半被截断的样本

两个长度惩罚互斥(CLI 会直接拒绝同时开启),且都以 rollout 的峰值 segment 计算,不会因多轮上下文压缩而失真。

六、一键跑起来:启动命令与参考脚本

以 4B 文本数学 RL 为例(完整脚本:examples/scripts/quick_start/rl_qwen3_4b.sh):

python3 -m molt.cli.train_rl_ray \ --actor.model_name_or_path /path/to/Qwen3-4B \ --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 \ --algo.kl.init_coef 0

只需把--train.agent_path换成你自己的奖励函数文件,框架会导入其中的AgentRunner类(校验逻辑见 molt/agents/base.py#L281-L297)。仓库提供了四套可直接参考的代理:

代理路径演示内容
单轮规则打分examples/python/agents/math.py\boxed{}判分,最小模板
VLM 多轮 + 工具examples/python/agents/geo3k.pyPython 沙箱工具调用
ChatAgent 最小示例examples/python/agents/chat_minimal.pyOpenAI SDK 黑盒 rollout
ChatAgent 多轮工具examples/python/agents/chat_geo3k.py自管理轮次上限

七、总结:三步写出你的自定义奖励函数

  1. 选路径:简单单轮/框架管循环 → 继承Env;自己管多轮对话/外部 SDK → 继承ChatAgent;
  2. 写判分:在step()/run()里用任意 Python(正则、执行器、LLM-as-Judge 回调)计算分数;
  3. 返回 Result:reward必填,info加诊断指标、score加过滤信号,--train.agent_path指向文件即可训练。

Molt 把"奖励函数"从框架组件降级成了普通 Python 代码,这正是它 ~9.2K 行还能支撑 1T 级 MoE agentic RL 的原因——你能在 Python 里算出来的,都是合法的奖励。

【免费下载链接】labs-molt

A scalable, agentic-first, and HuggingFace-native RL framework for research (9k lines).

项目地址:https://gitcode.com/gh_mirrors/la/labs-molt
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

C++内存池技术解析:消除延迟毛刺与内存碎片

简介&#xff1a;一套C内存池实现源码包&#xff0c;采用一级全局内存池与每线程独立二级内存池的双层结构&#xff0c;面向需要优化高并发场景下频繁分配与释放小块内存的C开发者&#xff0c;可有效减少系统调用和内存碎片。资源共33个文件&#xff0c;以17个h头文件和9个cpp源…

作者头像 李华
网站建设 2026/10/15 16:48:39

无线话筒射频链路复现指南:从综合文档到可量产方案

简介&#xff1a;这份资源是围绕无线话筒技术整理的综合性文档包&#xff0c;面向音频工程初学者、电子设计爱好者及需要了解无线传输原理的从业者&#xff0c;帮助其系统认识无线话筒的工作机制与工程实现。压缩包共12个文件&#xff0c;约70KB&#xff0c;以Altium Designer工…

作者头像 李华