Source code for protomotions.agents.supervised.config

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Configuration for generic supervised rollout training."""

from dataclasses import dataclass, field
from enum import Enum
import math
from typing import Optional

from protomotions.agents.base_agent.config import BaseAgentConfig, BaseModelConfig
from protomotions.agents.common.supervision import SupervisionLossConfig


[docs] class RolloutActor(Enum): """Which model forward produces the rollout. STUDENT uses the model's forward. EXPERT uses the model's own ``collect_expert_rollout``. An optional external expert labels every state and drives a fraction of episodes through ``expert_rollout_probability``. """ STUDENT = "student" EXPERT = "expert"
[docs] @dataclass class SupervisedAgentConfig(BaseAgentConfig): """Generic supervised imitation agent configuration. Experiment files choose the rollout actor, optional external expert checkpoint, and supervised loss keys. The agent loop stays independent of the specific student model. """ _target_: str = "protomotions.agents.supervised.agent.SupervisedAgent" model: BaseModelConfig = field( default_factory=BaseModelConfig, metadata={"help": "Model configuration."}, ) expert_model_path: Optional[str] = field( default=None, metadata={ "help": "External expert checkpoint that labels rollouts; requires rollout_actor=student." }, ) rollout_actor: RolloutActor = field( default=RolloutActor.STUDENT, metadata={"help": "Model forward used for collecting rollout actions."}, ) loss: SupervisionLossConfig = field( default_factory=SupervisionLossConfig, metadata={"help": "Supervised loss over model outputs and labels."}, ) expert_rollout_probability: float = field( default=0.0, metadata={ "help": "Per-episode probability that the external expert drives the episode." }, ) def __post_init__(self): if not isinstance(self.rollout_actor, RolloutActor): raise TypeError("rollout_actor must be a RolloutActor") if ( not math.isfinite(self.expert_rollout_probability) or not 0 <= self.expert_rollout_probability <= 1 ): raise ValueError("expert_rollout_probability must be finite and in [0, 1]") if self.expert_model_path is None: if self.expert_rollout_probability > 0: raise ValueError( "expert_rollout_probability > 0 requires expert_model_path" ) elif self.rollout_actor is not RolloutActor.STUDENT: raise ValueError("expert_model_path requires rollout_actor=student")
[docs] def apply_inference_defaults(self, env) -> None: """Run the trained student alone: drop the expert and its observations. The expert labels rollouts during training; at inference the student acts on its own, so the expert checkpoint, its rollout share and the expert-prefixed observations it added are removed. """ from protomotions.agents.supervised.expert_utils import EXPERT_OBS_PREFIX for key in [ key for key in env.observation_components if key.startswith(EXPERT_OBS_PREFIX) ]: del env.observation_components[key] self.expert_model_path = None self.rollout_actor = RolloutActor.STUDENT self.expert_rollout_probability = 0.0