# PR #6039 完整报告

- 仓库：`verl-project/verl`
- 标题：[trainer, rollout, algo] refactor: Remove OPD colocate mode
- 合并时间：2026-04-17 13:12
- 原文链接：http://prhub.com.cn/verl-project/verl/pull/6039

---

# 执行摘要

- 一句话：移除在线策略蒸馏的共置模式，强制使用独立资源池，简化教师模型管理逻辑。
- 推荐动作：该 PR 值得精读，尤其是对于涉及蒸馏和资源管理的开发者。关注点包括：教师模型管理器的简化设计、配置契约的变更，以及 review 中提到的序列化优化机会。

# 功能与动机

根据 PR 描述，移除 OPD 的共置模式是为了简化系统，目前仅支持独立的教师模型（standalone teachers）。这可能是为了减少维护负担、统一资源管理模型，并消除共置模式带来的复杂性。

# 实现拆解

1. **重构教师模型管理器**：修改 `verl/experimental/teacher_loop/teacher_model.py` 中的 `TeacherModelManager` 类，移除对 `resource_pool` 可选参数的支持，强制要求传入专用资源池。删除 `_initialize_async_server_manager` 和 `_initialize_router` 方法，合并为 `_initialize_load_balancer`。移除 `compute_logprobs` 方法及其依赖的 `_run_single` 和 `run` 方法，因为共置模式下教师模型与 rollout 共享资源池的逻辑已废弃。
2. **清理教师管理器逻辑**：在 `verl/experimental/teacher_loop/teacher_manager.py` 中，删除 `_unpad_teacher_inputs` 函数和 `compute_teacher_logprobs_batch` 方法，因为共置模式下的批量计算逻辑不再需要。同时，`AsyncTeacherLLMServerManager` 的构造函数移除了 `pad_token_id` 参数。
3. **移除训练器中的共置逻辑**：在 `verl/trainer/ppo/ray_trainer.py` 中，删除 `_should_compute_teacher_colocate` 和 `_compute_teacher_colocate` 方法，以及训练循环中调用这些方法的代码块。
4. **更新配置和依赖**：修改 `verl/trainer/main_ppo.py` 和 `verl/trainer/main_ppo_sync.py` 中的资源池初始化逻辑，移除对 `enable_resource_pool` 配置的检查，强制使用专用教师资源池。同时，更新相关配置文件（如 `verl/trainer/config/distillation/distillation.yaml`）以移除 `enable_resource_pool` 配置项。
5. **调整代理循环依赖**：在 `verl/experimental/agent_loop/agent_loop.py` 中，简化蒸馏相关的初始化逻辑，移除 `stream_teacher_with_rollout` 标志，并更新 `_compute_teacher_logprobs` 方法中的条件判断。

关键文件：
- `verl/experimental/teacher_loop/teacher_model.py`（模块 教师循环；类别 source；类型 data-contract；符号 _initialize_async_server_manager, _initialize_load_balancer, _initialize_router, get_router_address）: 教师模型管理器的核心重构，移除了共置模式的支持，强制使用独立资源池，并简化了初始化逻辑。
- `verl/experimental/teacher_loop/teacher_manager.py`（模块 教师循环；类别 source；类型 core-logic；符号 _unpad_teacher_inputs, compute_teacher_logprobs_batch）: 清理了共置模式特有的数据解填充和批量计算逻辑，简化了异步教师服务器管理器。
- `verl/trainer/ppo/ray_trainer.py`（模块 训练器；类别 source；类型 core-logic；符号 _should_compute_teacher_colocate, _compute_teacher_colocate）: 移除了训练器中判断和执行共置教师模型计算的逻辑，简化了训练流程。
- `verl/experimental/agent_loop/agent_loop.py`（模块 代理循环；类别 source；类型 dependency-wiring）: 更新代理循环中的蒸馏初始化逻辑，移除 stream_teacher_with_rollout 标志，简化教师服务器管理器的创建。

关键符号：_initialize_load_balancer, _unpad_teacher_inputs, compute_teacher_logprobs_batch, _should_compute_teacher_colocate, _compute_teacher_colocate


## 关键源码片段

### `verl/experimental/teacher_loop/teacher_model.py`

教师模型管理器的核心重构，移除了共置模式的支持，强制使用独立资源池，并简化了初始化逻辑。

```python
class TeacherModelManager:
    """教师模型管理器。"""

    def __init__(
        self,
        config: DictConfig,
        resource_pool: RayResourcePool,  # 变更：resource_pool 不再是可选参数，强制要求传入专用资源池
    ):
        """
        初始化教师模型管理器。

        Args:
            config (DictConfig): 教师模型配置。
            resource_pool (RayResourcePool): 专用教师资源池。  # 变更：文档更新，强调专用资源池
        """
        self.config: DistillationConfig = omega_conf_to_dataclass(config)
        self.resource_pool = resource_pool
        self._initialize_llm_servers()
        self._initialize_load_balancer()  # 变更：合并了原有的 _initialize_async_server_manager 和 _initialize_router 逻辑
        self.sleep()

    def _initialize_llm_servers(self):
        teacher_model_config: DistillationTeacherModelConfig = self.config.teacher_model
        teacher_world_size = (
            teacher_model_config.inference.tensor_model_parallel_size
            * teacher_model_config.inference.data_parallel_size
            * teacher_model_config.inference.pipeline_model_parallel_size
        )
        num_replicas = self.resource_pool.world_size // teacher_world_size  # 变更：直接使用资源池的世界大小，不再区分共置/独立模式
        # ... 后续初始化 rollout 副本的逻辑，仅保留 init_colocated 路径
```

### `verl/experimental/teacher_loop/teacher_manager.py`

清理了共置模式特有的数据解填充和批量计算逻辑，简化了异步教师服务器管理器。

```python
class AsyncTeacherLLMServerManager(AsyncLLMServerManager):
    """用于蒸馏对数概率计算的教师特定异步客户端。"""

    def __init__(
        self,
        config: DictConfig,
        servers: list[tuple[str, ray.actor.ActorHandle]],
        load_balancer_handle: ray.actor.ActorHandle,
        distillation_config: DictConfig | DistillationConfig,
        # 变更：移除了 pad_token_id 参数，因为共置模式下的填充逻辑已不再需要
    ):
        super().__init__(config=config, servers=servers, load_balancer_handle=load_balancer_handle)
        if isinstance(distillation_config, DistillationConfig):
            self.distillation_config = distillation_config
        else:
            self.distillation_config: DistillationConfig = omega_conf_to_dataclass(distillation_config)
        self.distillation_loss_config: DistillationLossConfig = self.distillation_config.distillation_loss
        # 变更：不再存储 pad_token_id
```

# 评论区精华

reviewer `gemini-code-assist[bot]` 在 `verl/experimental/agent_loop/agent_loop.py` 第 491 行附近指出，`AsyncTeacherLLMServerManager` 的初始化传递了整个 `config` 对象，但该类仅使用了其中的蒸馏配置部分，这可能导致不必要的序列化开销。建议仅传递所需的子配置以优化性能。此评论被标记为高优先级，但 PR 已合并，未在本次提交中解决。

- AsyncTeacherLLMServerManager 初始化序列化开销 (performance): 建议仅传递所需的子配置以优化性能，但此建议未在本次 PR 中实施。

# 风险与影响

- 风险：1. **回归风险**：移除了共置模式的所有代码路径，如果现有用户仍依赖此模式，将导致功能不可用。需要确保所有配置已更新为使用独立资源池。
2. **性能风险**：review 中提到的序列化开销问题未解决，可能影响分布式环境下的性能。
3. **兼容性风险**：配置文件中的 `enable_resource_pool` 配置项被移除，旧配置将无法解析，可能导致启动失败。
4. **逻辑简化风险**：删除 `_unpad_teacher_inputs` 和 `compute_teacher_logprobs_batch` 可能影响某些边缘情况下的数据处理，但鉴于这些是共置模式特有的，风险可控。
- 影响：1. **对用户的影响**：使用 OPD 的用户必须配置独立的教师资源池，无法再使用共置模式。这增加了资源规划的要求，但简化了配置和运维。
2. **对系统的影响**：减少了代码复杂性和维护成本，统一了教师模型的管理方式。可能轻微影响启动时的序列化性能。
3. **对团队的影响**：开发者需要更新相关文档和示例，以反映新的配置要求。
- 风险标记：配置契约变更 , 核心路径移除 , 序列化开销未优化

# 关联脉络

- PR #5997 [trainer,algo] feat: Support On-Policy Distillation in `main_ppo_sync`: 该 PR 引入了在线策略蒸馏（OPD）功能，本次重构移除了其共置模式，是功能演进的一部分。
- PR #6041 [rollout] fix: RM sleep/wake teacher replicas: 该 PR 涉及教师模型管理器的休眠 / 唤醒逻辑，本次重构进一步简化了教师模型管理，可能存在关联。