LLM as Judge 在 Agentic 环境中的优化实现
本文档介绍 ROLL 框架中 LLM as Judge 在 Agentic 环境中的优化实现方案,包括系统架构、调用链路、配置方法和最佳实践。
概览
LLM as Judge 是一种使用大语言模型作为评判器来评估智能体响应质量的方法。在 Agentic 训练场景中,大规模环境实例并发执行 rollout 时,使用 LLM as Judge 计算 reward 会产生大量并发 LLM 请求,这对外部 LLM 服务的稳定性和吞吐量提出了巨大挑战。
为解决这一问题,ROLL 框架通过独立的 Reward Cluster 和高效的调度机制,实现了可扩展的本地化并行评估系统,避免了对外部服务的依赖,确保了训 练过程的稳定性和可控性。
本文档以 DeepEyes 环境的 LLM as Judge 实现为例进行说明。对于其他需要使用 LLM as Judge 的环境,可以参考 env_manager 和 env 内的调用方式自定义实现。
核心优势
- 独立资源管理:Reward 模型与 Policy 模型分离,可独立分配 GPU 资源,避免资源竞争
- 本地化部署:通过本地 Reward Cluster 避免外部 API 依赖,保证服务稳定性和数据安全
- 高并发支持:通过 RequestScheduler 实现多环境并行的高效 reward 评估,支持环境并发扩展
- 统一接口设计:提供
generate_by_proxy统一工具函数,简化 LLM 调用逻辑,支持文本和多模态 - 灵活配置:支持多种推理后端(vLLM、SGLang)和自定义生成参数
应用场景
典型的 Agentic 训练场景:
- 环境规模:256个环境组,每组 4 个环境,共 1024个并发环境实例
- Rollout 频率:每个环境完成 episode 后调用 LLM Judge
- 并发压力:在 rollout 高峰期可能有 500+ 个环境同时请求 reward 评估
- 稳定性要求:训练过程不能因为外部 API 限流或超时而中断
通过本文档介绍的优化实现,可以有效应对上述挑战。
系统架构
整体架构
AgenticPipeline
├── Reward Cluster (可选,独立GPU资源)
│ ├── InferWorker (默认)
│ └── 支持 vLLM/SGLang 后端
│
├── Reward Scheduler (Ray Named Actor)
│ ├── 请求路由与负载均衡
│ ├── 并发控制
│ └── 请求追踪与清理
│
└── Environment Manager
├── llm_proxy: 用于 policy 推理
├── reward_proxy: 用于 LLM as Judge
└── env实例
└── 在 obtain_outcome_reward 中调用 reward_proxy
关键组件
1. Reward Cluster
位置: roll/pipeline/agentic/agentic_pipeline.py:88-98
Reward Cluster 是可选组件,仅在配置了 device_mapping 时创建:
self.reward = None
if (self.pipeline_config.reward is not None and
len(self.pipeline_config.reward.device_mapping) > 0):
self.reward = Cluster(
name=self.pipeline_config.reward.name,
worker_cls=self.pipeline_config.reward.worker_cls, # 默认 InferWorker
resource_manager=self.resource_manager,
worker_config=self.pipeline_config.reward,
)
Worker Class 默认配置: roll/pipeline/agentic/agentic_config.py:287
- 默认使用
InferWorker作为推理引擎,复用ActorInfer Worker实现 - 支持 vLLM、SGLang等多种后端
2. Reward Scheduler (Ray Named Actor)
位置: roll/pipeline/agentic/agentic_pipeline.py:112-125
Reward Scheduler 作为 Ray Named Actor 创建,供所有环境管理器共享访问:
self.reward_scheduler = RequestScheduler.options(
name=f"RewardScheduler-{self.pipeline_config.reward.name}",
get_if_exists=True,
namespace=RAY_NAMESPACE,
scheduling_strategy=NodeAffinitySchedulingStrategy(...)
).remote(
infer_cluster=self.reward,
pipeline_config=self.pipeline_config,
resource_manager=self.resource_manager,
)
核心功能:
- 智能路由: 使用最少负载路由算法分配请求到不同的 DP rank
- 粘性路由: 同一环境的请求固定路由到同一 worker(利于 KV cache)
- 请求追踪: 维护
request_id到 worker 的映射关系
3. Reward Proxy
位置: roll/pipeline/agentic/env_manager/vl_traj_env_manager.py:85-109
环境管理器通过 Ray 获取 Reward Scheduler 并创建 Reward Proxy:
# 从 Ray 获取 reward scheduler (Named Actor)
if self.pipeline_config.reward:
self.reward_scheduler = ray.get_actor(
name=f"RewardScheduler-{pipeline_config.reward.name}",
namespace=RAY_NAMESPACE
)
# 创建 reward proxy
self.reward_proxy = create_llm_proxy(
generate_scheduler=self.reward_scheduler,
llm_proxy_config=pipeline_config.reward.llm_proxy,
tokenizer=self.reward_tokenizer,
env=None,
)
Proxy 工厂函数: roll/pipeline/agentic/llm_proxy/__init__.py:11
- 支持多种 proxy 类型:
policy、openai、random - 通过注册机制实现可扩展性
- 训练验证过policy设置功能正常,基于外部部署的大模型服务可使用openai proxy,注意对并发的挑战
4. 统一工具函数 generate_by_proxy
位置: roll/pipeline/agentic/llm_proxy/proxy_utils.py:18-170
这是env调用的核心组件,提供统一的 LLM 调用接口:
def generate_by_proxy(
messages: List[Dict[str, Any]],
tokenizer: PreTrainedTokenizer,
proxy: BaseLLMProxy,
enable_thinking: bool = False,
generation_config: Optional[Dict[str, Any]] = None,
collator: Optional[Any] = None,
mm_data: Optional[Dict[str, Any]] = None,
src_rank: Optional[int] = None,
) -> Optional[str]
核心特性:
- 统一接口: 无论文本还是多模态,都使用相同的调用方式
- 自动格式化: 使用
tokenizer.apply_chat_template格式化消息 - 多模态支持: 通过
collator参数支持图像/视频输入 - thinking 机制: 支持 DeepSeek、Qwen 等模型的思考链
- 路由控制: 通过
src_rank参数实现粘性路由 - 错误处理: 返回
None表示推理失败,由调用方处理
调用链路
完整调用流程
1. DeepEyesEnv.step() (env/deepeyes/env.py:182-197)
当 done=True 时触发 obtain_outcome_reward
↓
2. DeepEyesEnv.obtain_outcome_reward() (env/deepeyes/env.py:199-254)
构建 judge prompt,调用 reward model
↓
3. generate_by_proxy() (llm_proxy/proxy_utils.py:18)
统一的 LLM 调用工具函数
↓
4. reward_proxy.generate() (llm_proxy/policy_proxy.py:15)
通过 Ray 调用 scheduler
↓
5. reward_scheduler.generate_one_request() (scheduler/generate_scheduler.py:1296)
请求路由与负载均衡
↓
6. infer_cluster.workers[dp_rank].generate_request()
实际的模型推理
↓
7. 返回 LLM 判断结果
配置说明
完整配置示例
# Reward 配置 (LLM as Judge for AgenticPipeline)
reward:
name: "reward"
worker_cls: "roll.pipeline.base_worker.InferWorker" # 默认值,可省略
model_args:
model_name_or_path: Qwen/Qwen2.5-72B-Instruct
dtype: bf16
generating_args:
max_new_tokens: 2048
temperature: 0.2 # 较低温度提高判断稳定性
top_p: 0.95
top_k: 20
strategy_args:
strategy_name: vllm # 或 sglang
strategy_config:
gpu_memory_utilization: 0.8
tensor_parallel_size: 4
load_format: auto
# 关键:必须非空才会创建 reward cluster
device_mapping: list(range(8, 16)) # GPUs 8-15
llm_proxy:
proxy_type: policy # 使用 policy proxy
配置关键点
1. device_mapping(必须配置)
# 推荐配置:Policy 和 Reward 使用独立 GPU
actor_infer:
device_mapping: list(range(0, 8)) # GPUs 0-7
reward:
device_mapping: list(range(8, 16)) # GPUs 8-15,独立资源
- 空或 None: 不创建 reward cluster,环境无法使用 LLM as Judge
- 非空: 创建独立的 reward cluster,支持 LLM as Judge
- 独立部署: 与 actor_infer 使用不同的 GPU 资源,Policy 推理和 Reward 评估并行执行,actor_infer与reward必须得独立部署
2. strategy_name(推理后端选择)
strategy_args:
strategy_name: vllm # 或 sglang
strategy_config:
gpu_memory_utilization: 0.8
tensor_parallel_size: 4
load_format: auto # 必须配置auto, vllm/sglang strategy里默认使用dummy load,会随机初始化参数
3. generating_args(生成参数)
generating_args:
max_new_tokens: 2048 # 根据 judge 输出长度调整
temperature: 0.2 # 较低温度提高稳定性
top_p: 0.95
top_k: 20
总结
LLM as Judge 在 Agentic 环境中的优化实现通过以下关键设计实现高效可扩展:
- 独立 Reward Cluster: 资源隔离,避免与 Policy 推理竞争
- Ray Named Actor: Reward Scheduler 作为共享服务,供所有环境访问
- 统一工具函数:
generate_by_proxy简化调用,支持文本和多模态 - 智能路由: 粘性路由和负载均衡,提高缓存利用率
通过合理配置和使用这些组件,可以构建高效、可靠的 LLM as Judge 评估系统。