ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在 slime 中新增自定义 Rollout 函数:从接口契约到 `--rollout-function-path` 全流程接入指南

在 slime 中新增自定义 Rollout 函数:从接口契约到 `--rollout-function-path` 全流程接入指南 在 slime 中新增自定义 Rollout 函数从接口契约到--rollout-function-path全流程接入指南【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime本文是一份面向 slimeLLM post-training / RL 训练框架开发者的实战指南核心主题是如何在项目中新增一个自定义 rollout 函数rollout function并通过--rollout-function-path参数将其安全地接入 slime 的训练 / 评估流程。读完本文你将掌握 slime 自定义 rollout 的函数签名与返回值契约、训练 / 评估双分支的实现规范、Sample数据字段的填充要求以及如何参照仓库内的sglang_rollout引擎驱动的异步生成与sft_rollout文件 / 缓冲区驱动的简单路径两种模板完成自己的实现并能避开常见坑位。何时需要使用自定义 Rollout 函数在 slime 中rollout 阶段负责给定 prompt 生成样本、计算奖励、产出可训练的Sample数据。框架默认使用slime.rollout.sglang_rollout.generate_rollout完成整条生成链路。当以下需求出现时就应该考虑自定义 rollout 函数需要新增一个全新的 rollout 任务或生成逻辑需要替换默认的slime.rollout.sglang_rollout.generate_rollout需要完全自定义训练 / 评估数据的生成行为。需要说明的是如果你的定制点只在于每条样本内部的生成方式例如 agent 循环、工具调用、RAG、沙箱执行、多轮生成而非整条 rollout 编排逻辑通常优先使用--custom-generate-function-path在默认 rollout 外层循环内注入生成逻辑而不是直接替换整个 rollout 函数。只有默认 rollout 编排确实无法满足需求时才动用--rollout-function-path参见 customization 文档 中的函数路径参数总览。仓库中的 search-r1 示例 正是自定义生成 复用默认 rollout 外层循环的典型用法而 fully_async 示例 则是需要整体替换 rollout 编排时可以参考的完整实现。第一步选择合适的起点模板动手之前先在仓库里找到与你目标最接近的参照实现异步 RL 风格 rolloutslime/rollout/sglang_rollout.py简单 SFT 风格 rolloutslime/rollout/sft_rollout.py选择依据如果任务需要基于推理引擎的异步生成 奖励计算典型 RL 训练场景以sglang_rollout路径为基底可复用其采样、异步奖励rm_hub、动态过滤、样本钩子等能力如果任务由文件 / 缓冲区驱动、逻辑简单如 SFT 数据制作、规则奖励的离线生成以sft_rollout为基底即可。sft_rollout.py是一个很好的最小模板它仅依赖load_tokenizer/load_processor加载分词器与处理器借助MultiTurnLossMaskGenerator生成loss_mask然后从data_buffer.get_samples(args.rollout_batch_size)取样本并填充tokens、response_length、reward、loss_mask后直接返回——没有引擎调用也没有异步逻辑非常适合作为自定义函数的起点。第二步创建新的 Rollout 模块在slime/rollout/目录下新建一个模块文件例如slime/rollout/your_rollout.py。slime 通过--rollout-function-path指定的字符串加载函数加载逻辑在 slime/utils/misc.py 的load_function中实现它按路径最后一个.切分模块与属性名先importlib.import_module(module_path)再取属性因此你的模块必须可以从项目根目录以slime.rollout.your_rollout的形式被 import。自定义函数必须满足如下调用签名该签名在 slime/utils/arguments.py 的--rollout-function-pathhelp 中也有明确说明def generate_rollout(args, rollout_id, data_source, evaluationFalse) - RolloutFnTrainOutput | RolloutFnEvalOutput: ...参数含义args整个训练 / 评估的全局参数argparse解析结果rollout_idint当前 rollout 的编号可用于保证数据生成的确定性例如按它选择数据分片、写入调试文件data_source数据源对象提供get_samples(...)等方法取出待处理样本evaluationbool标记当前是训练还是评估分支。返回值类型定义在slime/rollout/base_types.py见下文第三步这是 slime 与自定义函数之间的正式数据契约。第三步显式实现训练与评估两个分支返回值契约定义在 slime/rollout/base_types.pyRolloutFnTrainOutput训练分支返回值字段为samples: list[list[Sample]]与可选的metrics: dict[str, Any]RolloutFnEvalOutput评估分支返回值字段为data: dict[str, dict[str, Any]]与可选的metrics: dict[str, Any]。base_types.py中的call_rollout_fn(fn, *args, evaluation..., **kwargs)负责统一调用它显式传入evaluation关键字参数并对旧版本返回裸 list/dict 的兼容处理——非两个输出 dataclass 的返回值会被自动包装成RolloutFnEvalOutput(data...)或RolloutFnTrainOutput(samples...)。因此即使不显式返回 dataclass也应保证返回值结构符合对应语义。最小骨架如下继承自 SKILL.md并做了字段级说明from slime.rollout.base_types import RolloutFnTrainOutput, RolloutFnEvalOutput def generate_rollout(args, rollout_id, data_source, evaluationFalse): if evaluation: result { custom_eval: { rewards: [], truncated: [], samples: [], } } return RolloutFnEvalOutput(dataresult) groups data_source.get_samples(args.rollout_batch_size) # 填充训练所需字段tokens/response_length/reward/status需要时还有 loss_mask return RolloutFnTrainOutput(samplesgroups)评估分支的data是dict[str, dict]外层 key 是评估项名称内层通常至少包含rewardslist、truncatedlist[bool]、sampleslist。参考 slime/rollout/forge_load.py 的评估分支实现可以看到这种结构的实际形态它还会通过args.eval_reward_key or args.reward_key解析出奖励值。在slime/ray/rollout.py的eval()路径中result.data会被交给log_eval_rollout_data记录指标——如果你返回空 dict评估会成为一个空操作这也是合法的forge_load 在未找到评估转储时正是返回RolloutFnEvalOutput(data{})。训练分支的samples是list[list[Sample]]分组结构每个内层 list 是一组样本。slime/ray/rollout.py的_get_rollout_data在拿到结果后会先做validate_rollout_id_annotated校验再执行while isinstance(data[0], list)展平。第四步保持数据契约兼容每个生成的样本必须是slime/utils/types.py中定义的Sampledataclass实例。与训练直接相关的必填字段包括tokens样本的完整 token id 序列list[int]训练时用于计算 lossresponse_lengthint响应部分的 token 数rewardfloat或配置了--reward-key时的 dict多奖励场景训练阶段由Sample.get_reward_value(args)取出标量用于优势计算statusSample.Status枚举取值包括PENDING/COMPLETED/TRUNCATED/ABORTED/FAILED。其中TRUNCATED表示因长度截断ABORTED表示被中止FAILED表示可恢复或非致命的生成失败如工具调用失败、外部 API 报错FAILED样本仍可能携带部分有效输出loss_mask若涉及部分 rolloutpartial rollout或掩码逻辑必须保持其语义与既有行为一致——loss_mask中值为 1 的位置参与 loss 计算0 的位置如工具 / 环境返回的 token被屏蔽。此外Sample还提供了若干训练元数据字段rollout_id一个 rollout 执行被拆成多个训练样本时兄弟样本必须共享同一rollout_id以便 loss 聚合按 rollout 平均而不是重复计数、rollout_log_probsoff-policy 修正、rollout_top_p_token_ids/rollout_top_p_token_offsetstop-p 采样重放、rollout_routed_expertsMoE 路由重放等。如果你的自定义生成逻辑用不到这些高级能力保持默认值即可不必填充。一个有用的细节Sample.append_response_tokens(...)方法可以帮你增量追加响应 token 并自动维护tokens、response_length、loss_mask、rollout_log_probs的长度一致性——模型生成的 token 传trainableTrue工具 / 环境 token 传trainableFalse自动获得 loss-mask 零值与空 top-p 段它内部还会调用_validate_response_metadata_lengths做长度校验。第五步通过--rollout-function-path接入在启动命令中加入参数即可替换默认 rollout 函数--rollout-function-path slime.rollout.your_rollout.generate_rollout参数默认值与签名约定记录在 slime/utils/arguments.py默认值为slime.rollout.sglang_rollout.generate_rollout更详细的定制化说明见 customization 文档。启动后的实际接线发生在 slime/ray/rollout.py 的RolloutManagerRay actor中初始化时通过load_function(self.args.rollout_function_path)加载训练函数通过load_function(self.args.eval_function_path)加载评估函数--eval-function-path默认回落到--rollout-function-path见 slime/utils/arguments.py 中对eval_function_path的处理训练流程的generate()调用call_rollout_fn(self.generate_rollout, self.args, rollout_id, self.data_source, evaluationFalse)随后依次做rollout_id校验、展平、调试数据保存save_debug_rollout_data、指标记录log_rollout_data、奖励后处理_post_process_rewards支持--custom-reward-post-process-path接管与_convert_samples_to_train_data评估流程的eval()调用call_rollout_fn(self.eval_generate_rollout, ..., evaluationTrue)将result.data交给log_eval_rollout_data。也就是说你只需要关心给定args / rollout_id / data_source产出符合契约的返回值其余编排、DP 切分、调试与指标上报都由框架完成。常见错误与规避建议根据 SKILL.md 的总结并结合源码以下四类错误最容易在自定义 rollout 中出现返回裸 Python list/dict 且 schema 不匹配虽然call_rollout_fn对旧版裸返回值有兼容包装但包装后的结构语义仍必须与RolloutFnTrainOutput/RolloutFnEvalOutput对齐训练返回list[list[Sample]]、评估返回dict[str, dict]否则下游展平或指标记录会拿到错误结构只实现训练分支而遗漏评估分支evaluationTrue分支缺失会导致评估阶段行为异常可能返回 None 或直接报错。SKILL.md 与forge_load.py都演示了如何显式处理评估分支——即使评估想做成空操作也应显式返回RolloutFnEvalOutput(data{})生成的样本缺少必填字段tokens、response_length、reward、status这些字段是训练数据转换_convert_samples_to_train_data和奖励后处理的基础缺失会在数据流水线中引发错误或产生无意义的训练信号在高频 rollout 路径中使用阻塞式重逻辑、缺乏批处理 / 并发控制rollout 是 RL 训练中吞吐敏感的阶段sglang_rollout之所以采用异步引擎调用 并发奖励async_rm/batched_async_rm正是为了压满吞吐自定义函数如果串行阻塞如逐样本同步请求外部 API会直接拖慢整轮训练节奏。参考位置汇总默认 rollout 实现slime/rollout/sglang_rollout.py简单自定义示例规则奖励 SFT 风格slime/rollout/sft_rollout.py另一个完整自定义示例从磁盘转储加载样本用于内存测试slime/rollout/forge_load.py它同时展示了 train/eval 双分支、字面量路径与模板路径两种转储解析策略以及不要覆盖rollout_id的边界细节输出 dataclass 与统一调用入口slime/rollout/base_types.pySample数据契约字段、Status枚举、辅助方法slime/utils/types.py接线 / 加载slime/ray/rollout.py参数定义slime/utils/arguments.py定制化总览文档docs/en/get_started/customization.md契约测试tests/plugin_contracts/test_plugin_rollout_contracts.py覆盖--rollout-function-path的插件化加载契约可用python tests/plugin_contracts/test_plugin_rollout_contracts.py --rollout-function-path my_project.custom_rollout.generate_rollout验证你自己的函数路径能否被框架正确解析遵循以上接口契约与实现规范你就可以在不动 slime 核心代码的前提下为训练 / 评估流程注入任意自定义的 rollout 数据生成逻辑。【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表