
verl 扩展指南面向奖励函数、Agent Loop、Replay Buffer 与训练/推理引擎的自定义开发实战【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verlverlHybridFlow是一个灵活高效的 RL 后训练框架其设计哲学是一切皆可扩展从奖励函数、工具调用与 Agent 循环到异步采样的 Replay Buffer 采样策略、训练器钩子与检查点回调再到底层的推理框架、训练框架乃至硬件芯片都预留了明确的扩展点。本文以 docs/extend_guide.rst 为主线结合仓库源码与配置按RL 研究者—Agent 框架开发者—训练/推理框架开发者三条角色路径系统讲解 verl 的每类扩展接口的继承方式、配置接入方法与底层实现原理帮助你快速把自定义能力接入 verl。面向 RL 研究者从奖励函数到 Agent 行为的自定义1. 自定义奖励函数verl 支持四类奖励函数全部允许用户自定义基于规则Rule-based数学、代码等带有 ground truth 的奖励例如 GSM8K 答案匹配、代码执行结果校验判别式奖励模型DisRM对轨迹/响应输出打分或分类的判别模型生成式奖励模型GenRM以生成式方式评估响应的奖励模型混合奖励Hybrid规则奖励 GenRM/DisRM 的组合。所有类型的奖励函数都支持用户自定义详细的实现与接入方式参见 Reward Loop。从源码结构看奖励计算的流式路径由verl/workers/reward_manager/下的实现承载用户自定义奖励函数可通过数据集字段如reward_model与奖励管理器完成绑定。2. 自定义工具调用function_tool 与 BaseToolverl 内置了 ReAct Agent 循环实现ToolAgentLoop源码见 verl/experimental/agent_loop/tool_agent_loop.py支持两种工具定义方式无状态函数式工具用function_tool装饰器装饰一个函数工具即函数签名与 docstring 的自动解析有状态类式工具继承BaseTool并实现execute方法适合需要维护内部状态的工具如沙箱、搜索服务客户端。定义好工具后通过以下配置项在 rollout 中启用对应 rollout.yaml 中的agent配置段actor_rollout_ref.rollout.agent.default_agent_looptool_agent actor_rollout_ref.rollout.multi_turn.formathermes # hermes, gpt-oss, qwen3_coder 等 actor_rollout_ref.rollout.multi_turn.function_tool_pathpath/to/your_tools.py # 函数式工具路径 actor_rollout_ref.rollout.multi_turn.tool_config_pathpath/to/your_tools.yaml # 类式工具路径其中default_agent_loop默认使用的 agent loop 名称未在数据集中显式指定agent_name时生效源码见 agent_loop.pymulti_turn.format多轮对话的 chat template 格式支持hermes、gpt-oss、qwen3_coder等function_tool_path/tool_config_path工具加载入口。AgentLoopWorker在每个 worker 上通过load_all_tools一次性加载全部工具每条轨迹直接复用self.tools避免重复加载开销源码见 agent_loop.py。更多细节参见 Multi-turn Rollout Support、Agent Loop以及端到端示例 agent_loop_tutorial.ipynb内含 code sandbox 训练 ReAct agent 的完整流程。3. 自定义 Agent Loop继承 AgentLoopBase如果ToolAgentLoop无法满足需求可以继承AgentLoopBase并实现run方法抽象方法定义见 agent_loop.pyclass MyAgentLoop(AgentLoopBase): async def run(self, sampling_params: dict[str, Any], **kwargs) - AgentLoopOutput: 与 LLM server 和外部环境交互运行 agent loop。 Args: sampling_params (Dict[str, Any]): LLM sampling 参数。 **kwargs: 来自 verl.utils.dataset.RLHFDataset 的数据集字段。 Returns: AgentLoopOutput: Agent loop 输出。 ...重要警告自定义 loop 需要在 TITOtoken-in-token-out模式下自行请求 LLM server务必遵守一条黄金法则永远不要对已经解码过的 token 重新编码never re-encode tokens youve decoded。定义完成后通过配置文件指定自定义 agent loop 类actor_rollout_ref.rollout.agent.agent_loop_config_pathpath/to/your_agent.yamlagent_loop_config_path指向一个包含多个 agent loop 配置的 YAML 文件每个配置是一个 Hydra instantiate 条目例如rollout.yaml 中的注释给出了同样格式的示例- name: react_agent _target_: recipe.langgraph_agent.react_agent_loop.ReactAgentLoop tools: [get_current_temperature] - name: math_expression _target_: recipe.langgraph_agent.example.math_expression.MathExpressionReactAgentLoop min_terms: 2 max_terms: 6加载机制上AgentLoopWorker.__init__会通过OmegaConf.load读取该配置文件并把每个{name: config}条目写入全局_agent_loop_registry源码见 agent_loop.py真正执行时通过hydra.utils.instantiate实例化 loop并注入trainer_config、server_manager、tokenizer、processor、dataset_cls、data_config与tools等运行期依赖源码见 agent_loop.py。run方法返回的AgentLoopOutput是 agent loop 的标准化输出契约定义见 agent_loop.py包含prompt_ids、response_ids、response_mask1 表示 LLM 生成 token0 表示工具响应 token、response_logprobs、reward_score、num_turns、metrics等字段。AgentLoopWorker._agent_loop_postprocess会随后完成 padding、attention mask/position id 计算、reward score 与 teacher logprobs在线蒸馏场景计算最终聚合为DataProto批数据因此自定义 loop 只需正确产出这些字段。4. 异步训练中自定义 Replay Buffer 采样策略异步训练时agent 框架把生成的轨迹流式写入TransferQueuetrainer 通过ReplayBuffer源码见 verl/trainer/ppo/v1/replay_buffer.py从 TransferQueue 采样一个 batch 用于训练。verl 提供了默认采样策略但用户经常需要自定义。做法是继承ReplayBuffer并实现sample方法class UserCustomReplayBuffer(ReplayBuffer): def sample(self, global_steps: int, partition_id: str, batch_size: int) - tuple[KVBatchMeta, dict]: 从 replay buffer 中采样一个 batch。 Args: global_steps (int): 当前训练的全局步数。 partition_id (str): TransferQueue 的分区如 train 或 val。 batch_size (int): 批量大小。 Returns: KVBatchMeta: 一个 batch 的数据。 dict: 辅助指标如 off-policy staleness 统计。 ...然后通过配置接入ppo_trainer.yaml 中trainer.v1.sampler段的字段与之对应trainer.v1.sampler.custom_sampler.path path/to/your/sampler.py trainer.v1.sampler.custom_sampler.name UserCustomReplayBuffer该路径/名称机制在默认sample的 docstring 中有明确说明replay_buffer.py。理解默认实现有助于设计自定义策略。默认ReplayBuffer以 TransferQueue 为 KV 存储key 格式为{uid}_{session_id}_{index}其中uid是采样 prompt 时自动生成的唯一 idsession_id是 GRPO 组采样的会话 idindex是会话内轨迹序号。除轨迹外原始 prompt 也以{uid}为 key 存入并通过statustag 追踪 GRPO 组采样状态pending已采样未开始、running所有 session 运行中、finished全部正常结束、failure至少一个 session 失败。只有finished或failure状态的 prompt 组才会进入终态处理流程replay_buffer.py。另外两个与采样密切相关的内置配置值得了解max_off_policy_threshold默认 8与max_off_policy_strategydrop或wait控制轨迹最多可跨越的模型版本数drop丢弃超限轨迹wait为无丢弃模式、阻塞采样直到达到阈值的在途 prompt 完成该机制仅对异步 trainer 生效同步采样为 on-policy策略为 NO-OPsync_refill_failed_groups默认False是否让同步 trainer 替换没有任何轨迹的失败组要求gen_batch_size1。同步ReplayBuffer与异步ReplayBufferAsync采样在 DAPO 组过滤filter_groups_metric过滤配置指标在所有轨迹上完全相同的组、失败组处理与 off-policy 淘汰上的行为差异体现在_terminal_eviction_reasons的矩阵中replay_buffer.py。5. 自定义同步/异步 trainer 行为Hook 体系用户可能需要改变 trainer 的默认行为例如过采样over-sampling采样比 batch size 更多的轨迹动态过滤dynamic filtering过滤掉组内响应全部正确或全部错误的样本如 DAPO 式过滤。verl v1 PPO trainer源码见 verl/trainer/ppo/v1/ 下的trainer_base.py、trainer_sync.py、trainer_colocate_async.py、trainer_separate_async.py提供了一组生命周期 Hookon_init_endon_train_beginon_train_endon_validate_beginon_validate_endon_step_beginon_step_endon_sample_beginon_sample_end这组 Hook 同样被sync、colocate_async、separate_async三种 trainer 用于改变模型引擎、LLM server 与 checkpoint 引擎的行为是 v1 PPO 训练流程扩展的核心入口。6. 在 trainer 检查点时运行自定义代码CheckpointCallback子类化verl.trainer.ppo.checkpoint_callback.CheckpointCallback源码见 verl/trainer/ppo/checkpoint_callback.py并覆写on_save语义与 HuggingFacetransformers的TrainerCallback.on_save事件类似然后把 trainer 指向该类的完整限定名该类必须在 driver 上可导入trainer.checkpoint_callback_classmy_package.module.MyCheckpointCallback该 Hook 在 v1 PPO trainer 中每次检查点保存后于 driver 进程运行完整的 Hook 语义参见 checkpoint.rst。源码层面需要注意两个行为细节均记录在 checkpoint_callback.py 的模块 docstring 中on_save(trainer, global_step, checkpoint_dir, async_saveFalse, **kwargs)必须在签名中接受**kwargs以便未来版本传递更多上下文而不破坏用户子类Hook 抛出的异常会向上传播并中止训练——检查点回调通常执行持久性关键副作用上传分片、注册模型版本等静默吞掉失败可能导致无信号丢 checkpoint。若需要 best-effort 语义请在 Hook 体内自行try/except当async_saveTrueMegatron 异步 checkpointing时回调触发时 worker 侧写入可能仍在进行、latest_checkpointed_iteration.txt尚未写入此时不能假定 checkpoint 已持久化。build_checkpoint_callback在未设置该配置时返回 no-op 回调因此 trainer 调用点无需判空checkpoint_callback.py。面向 Agent 框架开发者替换 AgentLoopManager 与接入黑盒 Agent7. 用自有 Agent 框架替换 AgentLoopManagerAgentLoopManager源码见 agent_loop.py是 verl 中 agent 框架的一个参考实现被设计为可被其他 agent 框架完全替换——例如 NVIDIA Nemo-Gym、AWS Bedrock AgentCore、SWE-agent 等见 agent_loop.py 的模块 docstring。接入自有框架只需满足两个要求实现一个非阻塞的generate_sequences方法rollout 结束后把轨迹字段如prompt_ids、response_ids、response_mask等写入TransferQueue。class MyAgentLoopManager: classmethod auto_await async def create( cls, config: DictConfig, llm_client: LLMServerClient, teacher_client: dict[str, LLMServerClient] None, reward_loop_worker_handles: list[ray.actor.ActorHandle] None, ): 创建 agent loop manager。 Args: config (DictConfig): 主入口的完整配置。 llm_client (LLMServerClient): LLM server 的 client。 teacher_client (dict[str, LLMServerClient]): 多个 teacher server 的 client。 reward_loop_worker_handles (List[ray.actor.ActorHandle]): 流式奖励计算的 actor handles。 ... def generate_sequences(self, prompts: TensorDict) - None: 向 agent 框架提交一批 prompt 用于 rollout不阻塞。框架应在 rollout 完成后把轨迹字段 如 prompt_ids, response_ids, response_mask ...写入 TransferQueue。 Args: prompts (TensorDict): 来自训练或验证数据集的一批 prompt。 ...定义后通过配置指定自定义 manager 类注意前缀表示向配置新增字段actor_rollout_ref.rollout.agent.agent_loop_manager_classmy_package.module.MyAgentLoopManager作为参考内置AgentLoopManager的create类方法会通过auto_await异步创建并初始化一组AgentLoopWorker默认使用ray.remote(AgentLoopWorker)数量由rollout.agent.num_workers控制默认 8并按 round-robin 策略把 worker 调度到集群中的存活节点上agent_loop.pygenerate_sequences则把输入 batch 切分后并行分发到各 worker再聚合结果agent_loop.py。8. 以黑盒方式接入 Claude Code / Codex / Trae 等 Agentverl 启动了子项目verl-project/uni-agent其中提供一个 agent gateway用于把外部 Agent 框架以黑盒方式接入训练核心能力包括Message API提供 OpenAI/v1/chat/completions与 Anthropic/v1/messages兼容 APIToken-in-token-out把user, tool消息编码为 token id 并请求 LLM server把响应 id 解码并将工具解析为assistant消息轨迹追踪Trajectory tracking消息前缀匹配前缀变化时派生新轨迹会话管理Session management支持多个活动会话并发管理。详细设计可查阅 Agent Gateway 的 RFC 与实现文档对应 verl 仓库中的 agent_loop.rst 及相关 issue/子项目资料。面向训练/推理框架开发者接入自有引擎与硬件9. 推理框架开发者用 VERL_USE_EXTERNAL_MODULES 注册自定义推理框架verl 提供了环境变量钩子VERL_USE_EXTERNAL_MODULES用于加载外部模块。你可以在自己的模块中定义注册钩子并设置该环境变量来动态注册自定义模块主要包括两类扩展点RolloutReplica自定义 rollout replica 类决定如何启动你自己的推理 serverServerAdapter自定义 server adapter 类决定如何用你自己的推理 server 更新权重。verl-project/vexact就是通过这种方式与 verl 集成的。vexact 在register.py中定义了注册钩子def _load_vexact_replica(): Lazy loader for VeXactReplica to avoid circular imports. from vexact.integrations.verl.async_server import VeXactReplica return VeXactReplica # Register VeXact rollout replica (for server mode) RolloutReplicaRegistry.register(vexact, _load_vexact_replica) # Register VeXact rollout base (for hybrid mode with device mesh) _ROLLOUT_REGISTRY[(vexact, async)] vexact.integrations.verl.rollout.ServerAdapter用户只需设置环境变量即可加载 vexactexport VERL_USE_EXTERNAL_MODULESvexact.integrations.verl.register10. 训练框架开发者继承 BaseEngine 接入自有训练框架verl 提供了统一的训练引擎抽象BaseEngine源码见 verl/workers/engine/base.py。基于该抽象verl 原生支持多个主流训练框架训练框架并行策略FSDPFSDP1/2 SPMegatronDP TP CP EP PPVeOmniFSDP2 SP EPTorchTitanFSDP2 TP CP EP PPAutomodelFSDP2 TP CP EP PP训练框架开发者只需继承BaseEngine并实现全部接口然后与推理框架一样通过VERL_USE_EXTERNAL_MODULES在 verl 中注册自己的训练引擎。BaseEngine的接口设计base.py覆盖了训练引擎的全生命周期初始化initialize()实例化或加载模型、优化器与 LR scheduler模式切换train_mode()/eval_mode()上下文管理器配合BaseEngineCtx完成参数/优化器的设备 offload 与回载训练步骤optimizer_zero_grad()、forward_backward_batch()、optimizer_step()、lr_scheduler_step()train_batch()在基类中已经组合好zero-grad → forward/backward → step → 记录 grad_norm的标准流程推理infer_batch()在torch.no_grad()下执行前向参数导出get_per_tensor_param()/get_per_tensor_param_shard()/get_per_tensor_param_delta_shard()分别支持全量导出、本地分片导出与 delta 增量导出供delta_shardedcheckpoint 后端使用并行信息get_data_parallel_size()/get_data_parallel_rank()/get_data_parallel_group()检查点save_checkpoint()/load_checkpoint()设备与 LoRAto()、disable_adapter()。引擎注册机制由EngineRegistry提供base.pyregister(model_type, backend, device, vendor)装饰器按model_type → backend → (device, vendor)三级键注册引擎类new()依据当前设备与厂商动态实例化还支持VERL_ENGINE_DEVICE/VERL_ENGINE_VENDOR环境变量覆盖自动探测结果。例如verl-hardware-pluginFlagOS在__init__.py中定义注册钩子from verl_hardware_plugin.engines import register_all_engines from verl_hardware_plugin.platforms import register_all_platforms register_all_platforms() register_all_engines()用户同样通过环境变量加载export VERL_USE_EXTERNAL_MODULESverl_hardware_plugin关于训练引擎的更多设计参见 Model Engine。11. 硬件厂商接入自有芯片verl 主分支原生支持 NVIDIA GPU、华为 Ascend NPU 与 AMD GPU并提供统一的插件系统支持其他硬件平台。硬件接入的完整说明参见Multi-chip Support外部硬件插件verl-project/verl-hardware-plugin面向 MLU、XPU、MetaX 等芯片从仓库结构看硬件抽象还体现在平台插件层 verl/plugin/platform/含 6 个 Python 模块与verl/utils/device.py中的设备/厂商探测逻辑配合实现设备无关的引擎选择。总结verl 扩展点全景把上述扩展点归纳为一张速查表扩展需求扩展方式接入配置自定义奖励函数规则/DisRM/GenRM/混合全部可定制数据集字段 Reward Loop自定义工具function_tool或继承BaseToolrollout.multi_turn.function_tool_path/tool_config_path自定义 agent loop继承AgentLoopBase实现runrollout.agent.agent_loop_config_path自定义采样策略继承ReplayBuffer实现sampletrainer.v1.sampler.custom_sampler.path/name自定义 trainer 行为覆写 v1 PPO 的 9 个生命周期 Hook子类化 trainer 或直接覆写 Hook检查点回调继承CheckpointCallback覆写on_savetrainer.checkpoint_callback_class替换整个 agent 框架实现非阻塞generate_sequences 写入 TransferQueuerollout.agent.agent_loop_manager_class接入自定义推理框架注册RolloutReplica/ServerAdapterexport VERL_USE_EXTERNAL_MODULES...接入自定义训练框架继承BaseEngine实现全部接口export VERL_USE_EXTERNAL_MODULES...接入自有芯片统一插件系统平台层 引擎层参考 multi_chip_support.rstverl 的扩展设计遵循一致的模式抽象基类定义契约AgentLoopBase、ReplayBuffer、CheckpointCallback、BaseEngine注册表或配置文件完成绑定_agent_loop_registry、EngineRegistry、agent_loop_config_path、custom_sampler环境变量或命令行参数实现运行时装载VERL_USE_EXTERNAL_MODULES、checkpoint_callback_class。无论你是 RL 研究者、Agent 框架开发者还是训练/推理框架开发者都可以在不改动 verl 核心代码的前提下沿着上述扩展点把自有实现无缝接入训练流程。【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考