SkyRL
API ReferenceSkyRL

Configuration

Configuration dataclasses for SkyRL training.

Top-Level Config

The root configuration object and helpers.

class SkyRLTrainConfig

SkyRLTrainConfig(data: DataConfig = DataConfig(), trainer: TrainerConfig = TrainerConfig(), generator: GeneratorConfig = GeneratorConfig(), environment: EnvironmentConfig = EnvironmentConfig()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.
from_cli_overridesConstruct a SkyRLTrainConfig from CLI arguments or a dict of overrides.

Attributes:

Source code in skyrl/train/config/config.py:1220-1391
@dataclass
class SkyRLTrainConfig(BaseConfig):
    data: DataConfig = field(default_factory=DataConfig)
    trainer: TrainerConfig = field(default_factory=TrainerConfig)
    generator: GeneratorConfig = field(default_factory=GeneratorConfig)
    environment: EnvironmentConfig = field(default_factory=EnvironmentConfig)

    def __post_init__(self):

        # generator.max_input_length defaults to trainer.max_prompt_length
        if self.generator.max_input_length is None:
            self.generator.max_input_length = self.trainer.max_prompt_length

        # Copy temperature from generator sampling params to algorithm config
        # so workers can access it without needing the generator config
        if self.trainer.algorithm.temperature is None:
            self.trainer.algorithm.temperature = self.generator.sampling_params.temperature

        if self.data.dataloader.num_workers is None:
            self.data.dataloader.num_workers = 8
        if self.data.dataloader.persistent_workers and self.data.dataloader.num_workers == 0:
            raise ValueError(
                "data.dataloader.persistent_workers requires num_workers > 0, but it was set explicitly to 0."
            )

        # TODO(devpatel): Bandaid solution, replace this once we have a better
        # solution for LoRA performance degradation on the vLLM side
        from skyrl.backends.skyrl_train.inference_servers.utils import (
            _uses_lora_weight_sync,
        )

        ie_cfg = self.generator.inference_engine
        if _uses_lora_weight_sync(self) and ie_cfg.enforce_eager and ie_cfg.backend == "vllm":
            import warnings

            warnings.warn(
                "LoRA is enabled but inference_engine.enforce_eager=true. "
                "This combination causes significant performance degradation (2-3x slower generation). "
                "Automatically setting enforce_eager=false for better performance. "
            )
            ie_cfg.enforce_eager = False

    @classmethod
    def from_cli_overrides(cls, args: Union[List[str], dict]) -> "SkyRLTrainConfig":
        """Construct a SkyRLTrainConfig from CLI arguments or a dict of overrides.

        Parses CLI arguments and builds a typed config. Dataclass field defaults
        are used for any values not specified on the command line.

        Args:
            args: Either a list of CLI arguments in 'key.path=value' format, or a dict
                  mapping dot-notation keys to values.
                  Example list: ['trainer.policy.model.path=Qwen/Qwen2.5-1.5B-Instruct', 'trainer.seed=123']
                  Example dict: {'trainer.policy.model.path': 'Qwen/Qwen2.5-1.5B-Instruct', 'trainer.seed': 123}

        Returns:
            A fully constructed SkyRLTrainConfig with CLI overrides applied.

        Raises:
            ValueError: If an argument uses the unsupported '+' prefix.
        """
        if isinstance(args, dict):
            # OmegaConf's CLI parser only treats "null" as None; Python's
            # None stringifies to "None" which is parsed as the literal
            # string. Map None -> "null" so JSON-style overrides survive
            # the round-trip through OmegaConf.from_cli below.
            args = [f"{k}=null" if v is None else f"{k}={v}" for k, v in args.items()]

        # Check for unsupported '+' prefix
        for arg in args:
            if arg.startswith("+"):
                raise ValueError(
                    f"The '+' prefix for adding new config fields is not supported: '{arg}'. "
                    "To add custom config fields, subclass the relevant config dataclass."
                )
        overrides = OmegaConf.from_cli(args)
        unsupported_rope_paths = (
            "trainer.rope_scaling",
            "trainer.rope_theta",
            "trainer.rope_parameters",
            "generator.rope_scaling",
            "generator.rope_theta",
            "generator.rope_parameters",
            "generator.inference_engine.rope_scaling",
            "generator.inference_engine.rope_theta",
            "generator.inference_engine.rope_parameters",
            "generator.inference_engine.engine_init_kwargs.rope_scaling",
            "generator.inference_engine.engine_init_kwargs.rope_theta",
            "generator.inference_engine.engine_init_kwargs.rope_parameters",
            "generator.inference_engine.engine_init_kwargs.hf_overrides.rope_scaling",
            "generator.inference_engine.engine_init_kwargs.hf_overrides.rope_theta",
        )
        if any(_has_nested_key(overrides, path) for path in unsupported_rope_paths):
            raise ValueError(
                "`rope_scaling`, `rope_theta`, and `rope_parameters` are no longer supported as native "
                "config overrides, use `generator.inference_engine.engine_init_kwargs.hf_overrides.rope_parameters` "
                "and `trainer.policy.model_config_kwargs.rope_parameters` or "
                "`trainer.policy.megatron_config.transformer_config_kwargs.rope_parameters` instead"
            )
        inference_rope_parameters = _get_nested_value(
            overrides, "generator.inference_engine.engine_init_kwargs.hf_overrides.rope_parameters"
        )
        if inference_rope_parameters is not _MISSING:
            trainer_strategy = _get_nested_value(overrides, "trainer.strategy")
            trainer_strategy = "fsdp" if trainer_strategy is _MISSING else trainer_strategy
            trainer_rope_parameters_path = (
                "trainer.policy.megatron_config.transformer_config_kwargs.rope_parameters"
                if trainer_strategy == "megatron"
                else "trainer.policy.model_config_kwargs.rope_parameters"
            )
            trainer_rope_parameters = _get_nested_value(overrides, trainer_rope_parameters_path)
            if inference_rope_parameters != trainer_rope_parameters:
                raise ValueError(
                    "`generator.inference_engine.engine_init_kwargs.hf_overrides.rope_parameters` must match "
                    f"the trainer-side override at `{trainer_rope_parameters_path}`"
                )
        async_engine_path = "generator.inference_engine.async_engine"
        async_engine = _get_nested_value(overrides, async_engine_path)
        if async_engine is not _MISSING:
            if async_engine is True or (isinstance(async_engine, str) and async_engine.lower() == "true"):
                _delete_nested_key(overrides, async_engine_path)
            elif async_engine is False or (isinstance(async_engine, str) and async_engine.lower() == "false"):
                raise ValueError(
                    "`async_engine=False` is no longer supported; SkyRL always uses the async "
                    "HTTP/vLLM inference path. Remove the override."
                )
            else:
                raise ValueError("`async_engine` is no longer supported as a config field. Remove the override.")
        removed_inference_engine_overrides = {
            "generator.inference_engine.enable_http_endpoint": (
                "`enable_http_endpoint` is no longer supported; SkyRL always uses the HTTP/vLLM inference path. "
                "Remove the override."
            ),
            "generator.inference_engine.override_existing_update_group": (
                "`override_existing_update_group` is no longer supported; update-group handling is managed "
                "automatically by the vLLM-native inference path. Remove the override."
            ),
        }
        for path, message in removed_inference_engine_overrides.items():
            if _has_nested_key(overrides, path):
                raise ValueError(message)
        if (
            "generator" in overrides
            and "inference_engine" in overrides.generator
            and "remote_urls" in overrides.generator.inference_engine
        ):
            raise ValueError(
                "`remote_urls` is no longer supported, external inference servers can be used with "
                "`external_proxy_url` and `external_server_urls` instead"
            )
        # Accept the deprecated ``trainer.use_sample_packing`` key as an alias
        # for ``trainer.remove_microbatch_padding``. Remap it before
        # construction so the strict key validation does not reject the old
        # name.
        if "trainer" in overrides and "use_sample_packing" in overrides.trainer:
            if "remove_microbatch_padding" in overrides.trainer:
                raise ValueError(
                    "Specify only one of trainer.use_sample_packing (deprecated) and "
                    "trainer.remove_microbatch_padding, not both."
                )
            import warnings

            warnings.warn(
                "trainer.use_sample_packing has been renamed to "
                "trainer.remove_microbatch_padding; use "
                "trainer.remove_microbatch_padding instead.",
                DeprecationWarning,
                stacklevel=2,
            )
            overrides.trainer["remove_microbatch_padding"] = overrides.trainer["use_sample_packing"]
            del overrides.trainer["use_sample_packing"]
        return cls.from_dict_config(overrides)

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr data

data: DataConfig = field(default_factory=DataConfig)

attr trainer

trainer: TrainerConfig = field(default_factory=TrainerConfig)

attr generator

generator: GeneratorConfig = field(default_factory=GeneratorConfig)

attr environment

environment: EnvironmentConfig = field(default_factory=EnvironmentConfig)

method classmethod from_cli_overrides

from_cli_overrides(args: Union[List[str], dict]) -> SkyRLTrainConfig

Construct a SkyRLTrainConfig from CLI arguments or a dict of overrides.

Parses CLI arguments and builds a typed config. Dataclass field defaults are used for any values not specified on the command line.

Parameters:

NameTypeDescriptionDefault
argsUnion[List[str], dict]Either a list of CLI arguments in 'key.path=value' format, or a dict mapping dot-notation keys to values. Example list: ['trainer.policy.model.path=Qwen/Qwen2.5-1.5B-Instruct', 'trainer.seed=123'] Example dict: {'trainer.policy.model.path': 'Qwen/Qwen2.5-1.5B-Instruct', 'trainer.seed': 123}required

Returns:

TypeDescription
SkyRLTrainConfigA fully constructed SkyRLTrainConfig with CLI overrides applied.

Raises:

TypeDescription
ValueErrorIf an argument uses the unsupported '+' prefix.
Source code in skyrl/train/config/config.py:1262-1391
    @classmethod
    def from_cli_overrides(cls, args: Union[List[str], dict]) -> "SkyRLTrainConfig":
        """Construct a SkyRLTrainConfig from CLI arguments or a dict of overrides.

        Parses CLI arguments and builds a typed config. Dataclass field defaults
        are used for any values not specified on the command line.

        Args:
            args: Either a list of CLI arguments in 'key.path=value' format, or a dict
                  mapping dot-notation keys to values.
                  Example list: ['trainer.policy.model.path=Qwen/Qwen2.5-1.5B-Instruct', 'trainer.seed=123']
                  Example dict: {'trainer.policy.model.path': 'Qwen/Qwen2.5-1.5B-Instruct', 'trainer.seed': 123}

        Returns:
            A fully constructed SkyRLTrainConfig with CLI overrides applied.

        Raises:
            ValueError: If an argument uses the unsupported '+' prefix.
        """
        if isinstance(args, dict):
            # OmegaConf's CLI parser only treats "null" as None; Python's
            # None stringifies to "None" which is parsed as the literal
            # string. Map None -> "null" so JSON-style overrides survive
            # the round-trip through OmegaConf.from_cli below.
            args = [f"{k}=null" if v is None else f"{k}={v}" for k, v in args.items()]

        # Check for unsupported '+' prefix
        for arg in args:
            if arg.startswith("+"):
                raise ValueError(
                    f"The '+' prefix for adding new config fields is not supported: '{arg}'. "
                    "To add custom config fields, subclass the relevant config dataclass."
                )
        overrides = OmegaConf.from_cli(args)
        unsupported_rope_paths = (
            "trainer.rope_scaling",
            "trainer.rope_theta",
            "trainer.rope_parameters",
            "generator.rope_scaling",
            "generator.rope_theta",
            "generator.rope_parameters",
            "generator.inference_engine.rope_scaling",
            "generator.inference_engine.rope_theta",
            "generator.inference_engine.rope_parameters",
            "generator.inference_engine.engine_init_kwargs.rope_scaling",
            "generator.inference_engine.engine_init_kwargs.rope_theta",
            "generator.inference_engine.engine_init_kwargs.rope_parameters",
            "generator.inference_engine.engine_init_kwargs.hf_overrides.rope_scaling",
            "generator.inference_engine.engine_init_kwargs.hf_overrides.rope_theta",
        )
        if any(_has_nested_key(overrides, path) for path in unsupported_rope_paths):
            raise ValueError(
                "`rope_scaling`, `rope_theta`, and `rope_parameters` are no longer supported as native "
                "config overrides, use `generator.inference_engine.engine_init_kwargs.hf_overrides.rope_parameters` "
                "and `trainer.policy.model_config_kwargs.rope_parameters` or "
                "`trainer.policy.megatron_config.transformer_config_kwargs.rope_parameters` instead"
            )
        inference_rope_parameters = _get_nested_value(
            overrides, "generator.inference_engine.engine_init_kwargs.hf_overrides.rope_parameters"
        )
        if inference_rope_parameters is not _MISSING:
            trainer_strategy = _get_nested_value(overrides, "trainer.strategy")
            trainer_strategy = "fsdp" if trainer_strategy is _MISSING else trainer_strategy
            trainer_rope_parameters_path = (
                "trainer.policy.megatron_config.transformer_config_kwargs.rope_parameters"
                if trainer_strategy == "megatron"
                else "trainer.policy.model_config_kwargs.rope_parameters"
            )
            trainer_rope_parameters = _get_nested_value(overrides, trainer_rope_parameters_path)
            if inference_rope_parameters != trainer_rope_parameters:
                raise ValueError(
                    "`generator.inference_engine.engine_init_kwargs.hf_overrides.rope_parameters` must match "
                    f"the trainer-side override at `{trainer_rope_parameters_path}`"
                )
        async_engine_path = "generator.inference_engine.async_engine"
        async_engine = _get_nested_value(overrides, async_engine_path)
        if async_engine is not _MISSING:
            if async_engine is True or (isinstance(async_engine, str) and async_engine.lower() == "true"):
                _delete_nested_key(overrides, async_engine_path)
            elif async_engine is False or (isinstance(async_engine, str) and async_engine.lower() == "false"):
                raise ValueError(
                    "`async_engine=False` is no longer supported; SkyRL always uses the async "
                    "HTTP/vLLM inference path. Remove the override."
                )
            else:
                raise ValueError("`async_engine` is no longer supported as a config field. Remove the override.")
        removed_inference_engine_overrides = {
            "generator.inference_engine.enable_http_endpoint": (
                "`enable_http_endpoint` is no longer supported; SkyRL always uses the HTTP/vLLM inference path. "
                "Remove the override."
            ),
            "generator.inference_engine.override_existing_update_group": (
                "`override_existing_update_group` is no longer supported; update-group handling is managed "
                "automatically by the vLLM-native inference path. Remove the override."
            ),
        }
        for path, message in removed_inference_engine_overrides.items():
            if _has_nested_key(overrides, path):
                raise ValueError(message)
        if (
            "generator" in overrides
            and "inference_engine" in overrides.generator
            and "remote_urls" in overrides.generator.inference_engine
        ):
            raise ValueError(
                "`remote_urls` is no longer supported, external inference servers can be used with "
                "`external_proxy_url` and `external_server_urls` instead"
            )
        # Accept the deprecated ``trainer.use_sample_packing`` key as an alias
        # for ``trainer.remove_microbatch_padding``. Remap it before
        # construction so the strict key validation does not reject the old
        # name.
        if "trainer" in overrides and "use_sample_packing" in overrides.trainer:
            if "remove_microbatch_padding" in overrides.trainer:
                raise ValueError(
                    "Specify only one of trainer.use_sample_packing (deprecated) and "
                    "trainer.remove_microbatch_padding, not both."
                )
            import warnings

            warnings.warn(
                "trainer.use_sample_packing has been renamed to "
                "trainer.remove_microbatch_padding; use "
                "trainer.remove_microbatch_padding instead.",
                DeprecationWarning,
                stacklevel=2,
            )
            overrides.trainer["remove_microbatch_padding"] = overrides.trainer["use_sample_packing"]
            del overrides.trainer["use_sample_packing"]
        return cls.from_dict_config(overrides)

method make_config

make_config(algorithm_cls: Optional[Type[AlgorithmConfig]] = None, trainer_cls: Optional[Type[TrainerConfig]] = None, generator_cls: Optional[Type[GeneratorConfig]] = None) -> Type[SkyRLTrainConfig]

Create a SkyRLTrainConfig subclass with custom nested config classes.

Convenience helper to avoid boilerplate when extending configs for custom algorithms or generators. For full IDE autocomplete on custom fields, use explicit subclassing instead (see examples/algorithms/dapo/main_dapo.py).

Parameters:

NameTypeDescriptionDefault
algorithm_clsOptional[Type[AlgorithmConfig]]Custom AlgorithmConfig subclass. If provided without trainer_cls, a TrainerConfig subclass is automatically created.None
trainer_clsOptional[Type[TrainerConfig]]Custom TrainerConfig subclass. Takes precedence over algorithm_cls for the trainer config.None
generator_clsOptional[Type[GeneratorConfig]]Custom GeneratorConfig subclass.None

Returns:

TypeDescription
Type[SkyRLTrainConfig]A SkyRLTrainConfig subclass wired up with the custom config classes.

Example::

@dataclass class MyAlgorithmConfig(AlgorithmConfig): my_param: int = 42

MyConfig = make_config(algorithm_cls=MyAlgorithmConfig) cfg = MyConfig.from_cli_overrides(sys.argv[1:])

method get_config_as_dict

get_config_as_dict(cfg: Union[dict, BaseConfig]) -> dict

method get_config_as_yaml_str

get_config_as_yaml_str(cfg: BaseConfig) -> str

Data & Model

class DataConfig

DataConfig(train_data: List[str] = (lambda: [os.path.expanduser('~/data/gsm8k/train.parquet')])(), val_data: List[str] = (lambda: [os.path.expanduser('~/data/gsm8k/validation.parquet')])(), dataloader: DataLoaderConfig = DataLoaderConfig()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
train_dataList[str]
val_dataList[str]
dataloaderDataLoaderConfig
Source code in skyrl/train/config/config.py:67-71
@dataclass
class DataConfig(BaseConfig):
    train_data: List[str] = field(default_factory=lambda: [os.path.expanduser("~/data/gsm8k/train.parquet")])
    val_data: List[str] = field(default_factory=lambda: [os.path.expanduser("~/data/gsm8k/validation.parquet")])
    dataloader: DataLoaderConfig = field(default_factory=DataLoaderConfig)

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr train_data

train_data: List[str] = field(default_factory=(lambda: [os.path.expanduser('~/data/gsm8k/train.parquet')]))

attr val_data

val_data: List[str] = field(default_factory=(lambda: [os.path.expanduser('~/data/gsm8k/validation.parquet')]))

attr dataloader

dataloader: DataLoaderConfig = field(default_factory=DataLoaderConfig)

class ModelConfig

ModelConfig(path: Optional[str] = None, lora: SkyRLLoraConfig = SkyRLLoraConfig(), fake_int4_qat: FakeInt4QatConfig = FakeInt4QatConfig()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

Source code in skyrl/train/config/config.py:137-149
@dataclass
class ModelConfig(BaseConfig):
    path: Optional[str] = None
    lora: SkyRLLoraConfig = field(default_factory=SkyRLLoraConfig)
    fake_int4_qat: FakeInt4QatConfig = field(default_factory=FakeInt4QatConfig)

    def __post_init__(self) -> None:
        if self.fake_int4_qat.enabled:
            assert self.lora.rank > 0, (
                "`trainer.policy.model.fake_int4_qat.enabled=True` currently requires LoRA "
                "(`trainer.policy.model.lora.rank > 0`) because full-weight sync exports "
                "dense expert weights."
            )

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr path

path: Optional[str] = None

attr lora

lora: SkyRLLoraConfig = field(default_factory=SkyRLLoraConfig)

attr fake_int4_qat

fake_int4_qat: FakeInt4QatConfig = field(default_factory=FakeInt4QatConfig)

class SkyRLLoraConfig

SkyRLLoraConfig(rank: int = 0, alpha: int = 16, dropout: float = 0.0, lora_sync_path: str = '/tmp/skyrl_lora_sync', target_modules: str = 'all-linear', exclude_modules: Optional[str] = None, init_method: str = 'kaiming', max_loras: int = 1, max_cpu_loras: Optional[int] = None) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
rankint
alphaint
dropoutfloat
lora_sync_pathstr
target_modulesstr
exclude_modulesOptional[str]
init_methodstrFor FSDP, corresponds to init_lora_weights in PEFT.
max_lorasintMaximum number of LoRA adapters that can be active concurrently in a
max_cpu_lorasOptional[int]Total LoRA adapter capacity in vLLM's CPU LRU cache. Maps to vLLM's
Source code in skyrl/train/config/config.py:80-100
@dataclass
class SkyRLLoraConfig(BaseConfig):
    rank: int = 0
    alpha: int = 16
    dropout: float = 0.0
    lora_sync_path: str = "/tmp/skyrl_lora_sync"
    target_modules: str = "all-linear"
    exclude_modules: Optional[str] = None
    init_method: str = "kaiming"
    """For FSDP, corresponds to ``init_lora_weights`` in PEFT.
    For Megatron, used for ``lora_A_init_method``; supports "xavier", "normal", "kaiming", "zero"."""

    max_loras: int = 1
    """Maximum number of LoRA adapters that can be active concurrently in a
    single GPU batch. Maps to vLLM's ``max_loras``. Increase past 1 to enable
    multi-tenant LoRA serving via ``RemoteInferenceClient.load_lora_adapter``."""

    max_cpu_loras: Optional[int] = None
    """Total LoRA adapter capacity in vLLM's CPU LRU cache. Maps to vLLM's
    ``max_cpu_loras``; when None, vLLM defaults it to ``max_loras``. Must be
    >= ``max_loras`` if explicitly set."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr rank

rank: int = 0

attr alpha

alpha: int = 16

attr dropout

dropout: float = 0.0

attr lora_sync_path

lora_sync_path: str = '/tmp/skyrl_lora_sync'

attr target_modules

target_modules: str = 'all-linear'

attr exclude_modules

exclude_modules: Optional[str] = None

attr init_method

init_method: str = 'kaiming'

For FSDP, corresponds to init_lora_weights in PEFT. For Megatron, used for lora_A_init_method; supports "xavier", "normal", "kaiming", "zero".

attr max_loras

max_loras: int = 1

Maximum number of LoRA adapters that can be active concurrently in a single GPU batch. Maps to vLLM's max_loras. Increase past 1 to enable multi-tenant LoRA serving via RemoteInferenceClient.load_lora_adapter.

attr max_cpu_loras

max_cpu_loras: Optional[int] = None

Total LoRA adapter capacity in vLLM's CPU LRU cache. Maps to vLLM's max_cpu_loras; when None, vLLM defaults it to max_loras. Must be

= max_loras if explicitly set.

Training

class TrainerConfig

TrainerConfig(placement: PlacementConfig = PlacementConfig(), use_expandable_segments: bool = True, sequence_parallel_backend: str = 'ulysses', strategy: str = 'fsdp', policy: PolicyConfig = PolicyConfig(), ref: RefConfig = RefConfig(), critic: CriticConfig = CriticConfig(), algorithm: AlgorithmConfig = AlgorithmConfig(), mtp: MTPConfig = MTPConfig(), fully_async: FullyAsyncConfig = FullyAsyncConfig(), gradient_checkpointing: bool = True, gradient_checkpointing_use_reentrant: bool = False, seed: int = 42, resume_mode: Optional[str] = 'latest', resume_path: Optional[str] = None, log_path: str = '/tmp/skyrl-logs', ckpt_path: str = (lambda: os.path.expanduser('~/ckpts/'))(), max_ckpts_to_keep: int = -1, ckpt_interval: int = 10, hf_save_interval: int = -1, export_path: str = (lambda: os.path.expanduser('~/exports/'))(), bf16: bool = True, epochs: int = 1, max_training_steps: Optional[int] = None, update_epochs_per_batch: int = 1, train_batch_size: int = 1024, policy_mini_batch_size: int = 256, critic_mini_batch_size: int = 256, micro_train_batch_size_per_gpu: int = 1, micro_forward_batch_size_per_gpu: int = 1, max_tokens_per_microbatch: int = -1, recompute_old_logprobs_per_minibatch: bool = True, update_ref_every_epoch: bool = False, remove_microbatch_padding: bool = True, eval_batch_size: int = 1024, eval_before_train: bool = True, eval_interval: int = 5, max_prompt_length: int = 512, flash_attn: bool = True, disable_fast_tokenizer: bool = False, project_name: str = 'skyrl', run_name: str = 'test_run', logger: str = 'wandb', enable_ray_gpu_monitor: bool = True, tags: Optional[List[str]] = None, dump_data_batch: bool = False, dump_eval_results: bool = True, print_example_interval: int = 1, num_logger_eval_samples: int = -1, num_logger_train_samples: int = -1, log_example_interval: int = -1, logprobs_chunk_size: Optional[int] = 1024, vocab_entropy_chunk_size: Optional[int] = 0, vocab_entropy_chunk_memory_mb: int = 512, fused_lm_head_logprob: bool = False, fused_lm_head_logprob_backend: str = 'torch') -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
placementPlacementConfig
use_expandable_segmentsboolEnable PyTorch's CUDA expandable_segments allocator on the training
sequence_parallel_backendstr
strategystr
policyPolicyConfig
refRefConfig
criticCriticConfig
algorithmAlgorithmConfig
mtpMTPConfig
fully_asyncFullyAsyncConfig
gradient_checkpointingbool
gradient_checkpointing_use_reentrantbool
seedint
resume_modeOptional[str]None/"none", "latest", or "from_path".
resume_pathOptional[str]
log_pathstrPath for infrastructure log files. For multi-node, use a shared filesystem path to consolidate logs.
ckpt_pathstr
max_ckpts_to_keepint-1 to keep all checkpoints, N to keep only the last N.
ckpt_intervalint
hf_save_intervalintSave HuggingFace-format model every N steps. -1 to disable.
export_pathstrPath for exported artifacts (HF models, debug dumps, etc.).
bf16bool
epochsint
max_training_stepsOptional[int]If set, stop training after this many steps regardless of epochs or dataset size.
update_epochs_per_batchintNumber of gradient update passes over each training batch.
train_batch_sizeintSee utils/utils.py::validate_batch_sizes for train, mini, and micro batch size constraints.
policy_mini_batch_sizeint
critic_mini_batch_sizeint
micro_train_batch_size_per_gpuint
micro_forward_batch_size_per_gpuint
max_tokens_per_microbatchintMaximum number of tokens per microbatch for both forward and training steps. When > 0, microbatches
recompute_old_logprobs_per_minibatchboolWhen True, recomputes policy/ref model logprobs (and critic values) per mini-batch using
update_ref_every_epochbool
remove_microbatch_paddingboolPack samples into the THD layout and strip intra-microbatch padding (requires flash attention).
eval_batch_sizeint
eval_before_trainbool
eval_intervalint-1 to disable evaluation.
max_prompt_lengthint
flash_attnbool
disable_fast_tokenizerbool
project_namestr
run_namestr
loggerstr
enable_ray_gpu_monitorboolEnable background Ray GPU/RAM metrics collection and logging to wandb.
tagsOptional[List[str]]Optional list of tags to apply to the W&B run. Has no effect on other backends.
dump_data_batchbool
dump_eval_resultsbool
print_example_intervalintPretty-print an example prompt/response/reward to stdout every N
num_logger_eval_samplesintNumber of evaluation trajectory (prompt, response, score) tuples to upload to a wandb
num_logger_train_samplesintNumber of training trajectory (prompt, response, score) tuples to upload to a wandb
log_example_intervalintLog an example prompt every N training steps, 0/-1 to disable
logprobs_chunk_sizeOptional[int]Chunk size along the sequence dimension when computing log-probs from logits.
vocab_entropy_chunk_sizeOptional[int]Chunk size along the sequence dimension when computing Megatron vocab entropy.
vocab_entropy_chunk_memory_mbintApproximate per-chunk temporary memory budget for auto-sized Megatron vocab entropy chunks.
fused_lm_head_logprobboolMegatron only. Fuse the LM-head projection into log-prob / entropy
fused_lm_head_logprob_backendstrFused LM-head backend: "torch" (default) or "triton".
Source code in skyrl/train/config/config.py:922-1099
@dataclass
class TrainerConfig(BaseConfig):
    placement: PlacementConfig = field(default_factory=PlacementConfig)
    use_expandable_segments: bool = True
    """Enable PyTorch's CUDA ``expandable_segments`` allocator on the training
    workers to reduce GPU memory fragmentation across the offload/backload and
    forward/backward cycles. See ``InferenceEngineConfig`` for the
    equivalent inference-engine knob."""
    sequence_parallel_backend: str = "ulysses"
    strategy: str = "fsdp"
    policy: PolicyConfig = field(default_factory=PolicyConfig)
    ref: RefConfig = field(default_factory=RefConfig)
    critic: CriticConfig = field(default_factory=CriticConfig)
    algorithm: AlgorithmConfig = field(default_factory=AlgorithmConfig)
    mtp: MTPConfig = field(default_factory=MTPConfig)
    fully_async: FullyAsyncConfig = field(default_factory=FullyAsyncConfig)
    gradient_checkpointing: bool = True
    gradient_checkpointing_use_reentrant: bool = False
    seed: int = 42
    resume_mode: Optional[str] = "latest"
    """``None``/``"none"``, ``"latest"``, or ``"from_path"``."""
    resume_path: Optional[str] = None
    log_path: str = "/tmp/skyrl-logs"
    """Path for infrastructure log files. For multi-node, use a shared filesystem path to consolidate logs."""
    ckpt_path: str = field(default_factory=lambda: os.path.expanduser("~/ckpts/"))
    max_ckpts_to_keep: int = -1
    """``-1`` to keep all checkpoints, ``N`` to keep only the last N."""
    ckpt_interval: int = 10
    hf_save_interval: int = -1
    """Save HuggingFace-format model every N steps. ``-1`` to disable."""
    export_path: str = field(default_factory=lambda: os.path.expanduser("~/exports/"))
    """Path for exported artifacts (HF models, debug dumps, etc.)."""
    bf16: bool = True
    epochs: int = 1
    max_training_steps: Optional[int] = None
    """If set, stop training after this many steps regardless of epochs or dataset size.
    Useful for CI smoke tests and quick validation runs."""
    update_epochs_per_batch: int = 1
    """Number of gradient update passes over each training batch."""
    train_batch_size: int = 1024
    """See ``utils/utils.py::validate_batch_sizes`` for train, mini, and micro batch size constraints."""
    policy_mini_batch_size: int = 256
    critic_mini_batch_size: int = 256
    micro_train_batch_size_per_gpu: int = 1
    micro_forward_batch_size_per_gpu: int = 1
    max_tokens_per_microbatch: int = -1
    """Maximum number of tokens per microbatch for both forward and training steps. When > 0, microbatches 
    are formed by bin-packing samples based on their token counts (from attention_mask) instead of using a 
    fixed sample count, and micro_train_batch_size_per_gpu / micro_forward_batch_size_per_gpu are ignored.
    -1 means disabled (use sample-based micro_train_batch_size_per_gpu / micro_forward_batch_size_per_gpu).
    Applies to both forward and training micro-batching.

    NOTE: this is a *soft* cap. Sequences are never split across microbatches, so a single sequence
    longer than ``max_tokens_per_microbatch`` is placed alone in its own microbatch that exceeds the
    cap (no error, no truncation). The true peak microbatch size is therefore
    ``max(max_tokens_per_microbatch, longest_sequence_in_batch)``."""
    recompute_old_logprobs_per_minibatch: bool = True
    """When True, recomputes policy/ref model logprobs (and critic values) per mini-batch using
    the same mini-batch + DP partition as the training step. When False, a single full-batch forward is run.
    This makes the microbatch packing — and therefore the resulting logprobs/values — identical to
    what forward_backward recomputes, so the PPO ratio (and critic value clipping) is exact at the
    first inner step."""
    update_ref_every_epoch: bool = False
    remove_microbatch_padding: bool = True
    """Pack samples into the THD layout and strip intra-microbatch padding (requires flash attention)."""
    eval_batch_size: int = 1024
    eval_before_train: bool = True
    eval_interval: int = 5
    """``-1`` to disable evaluation."""
    max_prompt_length: int = 512
    flash_attn: bool = True
    disable_fast_tokenizer: bool = False
    project_name: str = "skyrl"
    run_name: str = "test_run"
    logger: str = "wandb"
    enable_ray_gpu_monitor: bool = True
    """Enable background Ray GPU/RAM metrics collection and logging to wandb."""
    tags: Optional[List[str]] = None
    """Optional list of tags to apply to the W&B run. Has no effect on other backends."""
    dump_data_batch: bool = False
    dump_eval_results: bool = True
    print_example_interval: int = 1
    """Pretty-print an example prompt/response/reward to stdout every N
    training steps; ``0``/``-1`` disables. Renamed from ``log_example_interval``."""
    num_logger_eval_samples: int = -1
    """Number of evaluation trajectory (prompt, response, score) tuples to upload to a wandb
    table on each eval. ``-1`` (default) or ``0`` disables. When positive,
    up to this many samples are taken from the start of each eval pass and
    logged via :class:`TrajectoryLogger`. Column count is fixed
    by the first call, so keep the eval set size and this value stable."""
    num_logger_train_samples: int = -1
    """Number of training trajectory (prompt, response, score) tuples to upload to a wandb
    table on each training step. ``-1`` (default) or ``0`` disables. When positive,
    up to this many samples are taken from the start of each training step and
    logged via :class:`TrajectoryLogger`. Column count is fixed
    by the first call, so keep the training set size and this value stable."""
    log_example_interval: int = -1
    """Log an example prompt every N training steps, ``0``/``-1`` to disable"""
    logprobs_chunk_size: Optional[int] = 1024
    """Chunk size along the sequence dimension when computing log-probs from logits.
    This lowers peak GPU memory at the cost of ~2x wall-clock time.
    ``None`` disables chunking (Megatron backend only; FSDP requires a positive int).
    See https://github.com/NovaSky-AI/SkyRL/pull/1610 for more details."""
    vocab_entropy_chunk_size: Optional[int] = 0
    """Chunk size along the sequence dimension when computing Megatron vocab entropy.
    ``0`` auto-sizes from the local vocab shard size and ``vocab_entropy_chunk_memory_mb``.
    ``None`` disables chunking."""
    vocab_entropy_chunk_memory_mb: int = 512
    """Approximate per-chunk temporary memory budget for auto-sized Megatron vocab entropy chunks."""
    fused_lm_head_logprob: bool = False
    """Megatron only. Fuse the LM-head projection into log-prob / entropy
    computation so the full ``[B, S, vocab//TP]`` logits tensor is never
    materialized. Uses ``logprobs_chunk_size`` to bound peak memory."""
    fused_lm_head_logprob_backend: str = "torch"
    """Fused LM-head backend: ``"torch"`` (default) or ``"triton"``.
    The Triton backend requires CUDA + triton and falls back to ``"torch"``
    when unavailable. Ignored unless ``fused_lm_head_logprob`` is true."""

    def __post_init__(self):
        # ref model defaults to the policy model
        if self.ref.model.path is None:
            self.ref.model.path = self.policy.model.path

        if self.log_example_interval > 0:
            print(
                f"log_example_interval has been renamed, use print_example_interval instead. Setting print_example_interval to {self.log_example_interval}"
            )
            self.print_example_interval = self.log_example_interval

        if self.policy.model.fake_int4_qat.enabled:
            assert (
                self.strategy == "megatron"
            ), "`trainer.policy.model.fake_int4_qat.enabled=True` is only supported with `trainer.strategy=megatron`."
            assert not self.policy.megatron_config.lora_config.merge_lora, (
                "`trainer.policy.model.fake_int4_qat.enabled=True` currently requires "
                "`trainer.policy.megatron_config.lora_config.merge_lora=False` so weight "
                "sync preserves the inference engine's INT4 base weights."
            )

        if self.logprobs_chunk_size is not None and (
            not isinstance(self.logprobs_chunk_size, int) or self.logprobs_chunk_size <= 0
        ):
            raise ValueError(
                f"logprobs_chunk_size must be a positive integer or None, got {self.logprobs_chunk_size!r}."
            )
        if self.logprobs_chunk_size is None and self.strategy != "megatron":
            raise ValueError(
                "logprobs_chunk_size=None (no chunking) is only supported with the Megatron backend. "
                f"Set a positive integer for strategy={self.strategy!r}."
            )
        if self.fused_lm_head_logprob and self.strategy != "megatron":
            raise ValueError(
                "fused_lm_head_logprob=True is only supported with the Megatron backend, "
                f"got strategy={self.strategy!r}."
            )
        if self.fused_lm_head_logprob_backend not in ("torch", "triton"):
            raise ValueError(
                "fused_lm_head_logprob_backend must be 'torch' or 'triton', "
                f"got {self.fused_lm_head_logprob_backend!r}."
            )
        if self.vocab_entropy_chunk_size is not None and (
            isinstance(self.vocab_entropy_chunk_size, bool)
            or not isinstance(self.vocab_entropy_chunk_size, int)
            or self.vocab_entropy_chunk_size < 0
        ):
            raise ValueError(
                "vocab_entropy_chunk_size must be a non-negative integer or None, "
                f"got {self.vocab_entropy_chunk_size!r}."
            )
        if (
            isinstance(self.vocab_entropy_chunk_memory_mb, bool)
            or not isinstance(self.vocab_entropy_chunk_memory_mb, int)
            or self.vocab_entropy_chunk_memory_mb <= 0
        ):
            raise ValueError(
                "vocab_entropy_chunk_memory_mb must be a positive integer, "
                f"got {self.vocab_entropy_chunk_memory_mb!r}."
            )

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr placement

placement: PlacementConfig = field(default_factory=PlacementConfig)

attr use_expandable_segments

use_expandable_segments: bool = True

Enable PyTorch's CUDA expandable_segments allocator on the training workers to reduce GPU memory fragmentation across the offload/backload and forward/backward cycles. See InferenceEngineConfig for the equivalent inference-engine knob.

attr sequence_parallel_backend

sequence_parallel_backend: str = 'ulysses'

attr strategy

strategy: str = 'fsdp'

attr policy

policy: PolicyConfig = field(default_factory=PolicyConfig)

attr ref

ref: RefConfig = field(default_factory=RefConfig)

attr critic

critic: CriticConfig = field(default_factory=CriticConfig)

attr algorithm

algorithm: AlgorithmConfig = field(default_factory=AlgorithmConfig)

attr mtp

mtp: MTPConfig = field(default_factory=MTPConfig)

attr fully_async

fully_async: FullyAsyncConfig = field(default_factory=FullyAsyncConfig)

attr gradient_checkpointing

gradient_checkpointing: bool = True

attr gradient_checkpointing_use_reentrant

gradient_checkpointing_use_reentrant: bool = False

attr seed

seed: int = 42

attr resume_mode

resume_mode: Optional[str] = 'latest'

None/"none", "latest", or "from_path".

attr resume_path

resume_path: Optional[str] = None

attr log_path

log_path: str = '/tmp/skyrl-logs'

Path for infrastructure log files. For multi-node, use a shared filesystem path to consolidate logs.

attr ckpt_path

ckpt_path: str = field(default_factory=(lambda: os.path.expanduser('~/ckpts/')))

attr max_ckpts_to_keep

max_ckpts_to_keep: int = -1

-1 to keep all checkpoints, N to keep only the last N.

attr ckpt_interval

ckpt_interval: int = 10

attr hf_save_interval

hf_save_interval: int = -1

Save HuggingFace-format model every N steps. -1 to disable.

attr export_path

export_path: str = field(default_factory=(lambda: os.path.expanduser('~/exports/')))

Path for exported artifacts (HF models, debug dumps, etc.).

attr bf16

bf16: bool = True

attr epochs

epochs: int = 1

attr max_training_steps

max_training_steps: Optional[int] = None

If set, stop training after this many steps regardless of epochs or dataset size. Useful for CI smoke tests and quick validation runs.

attr update_epochs_per_batch

update_epochs_per_batch: int = 1

Number of gradient update passes over each training batch.

attr train_batch_size

train_batch_size: int = 1024

See utils/utils.py::validate_batch_sizes for train, mini, and micro batch size constraints.

attr policy_mini_batch_size

policy_mini_batch_size: int = 256

attr critic_mini_batch_size

critic_mini_batch_size: int = 256

attr micro_train_batch_size_per_gpu

micro_train_batch_size_per_gpu: int = 1

attr micro_forward_batch_size_per_gpu

micro_forward_batch_size_per_gpu: int = 1

attr max_tokens_per_microbatch

max_tokens_per_microbatch: int = -1

Maximum number of tokens per microbatch for both forward and training steps. When > 0, microbatches are formed by bin-packing samples based on their token counts (from attention_mask) instead of using a fixed sample count, and micro_train_batch_size_per_gpu / micro_forward_batch_size_per_gpu are ignored. -1 means disabled (use sample-based micro_train_batch_size_per_gpu / micro_forward_batch_size_per_gpu). Applies to both forward and training micro-batching.

NOTE: this is a soft cap. Sequences are never split across microbatches, so a single sequence longer than max_tokens_per_microbatch is placed alone in its own microbatch that exceeds the cap (no error, no truncation). The true peak microbatch size is therefore max(max_tokens_per_microbatch, longest_sequence_in_batch).

attr recompute_old_logprobs_per_minibatch

recompute_old_logprobs_per_minibatch: bool = True

When True, recomputes policy/ref model logprobs (and critic values) per mini-batch using the same mini-batch + DP partition as the training step. When False, a single full-batch forward is run. This makes the microbatch packing — and therefore the resulting logprobs/values — identical to what forward_backward recomputes, so the PPO ratio (and critic value clipping) is exact at the first inner step.

attr update_ref_every_epoch

update_ref_every_epoch: bool = False

attr remove_microbatch_padding

remove_microbatch_padding: bool = True

Pack samples into the THD layout and strip intra-microbatch padding (requires flash attention).

attr eval_batch_size

eval_batch_size: int = 1024

attr eval_before_train

eval_before_train: bool = True

attr eval_interval

eval_interval: int = 5

-1 to disable evaluation.

attr max_prompt_length

max_prompt_length: int = 512

attr flash_attn

flash_attn: bool = True

attr disable_fast_tokenizer

disable_fast_tokenizer: bool = False

attr project_name

project_name: str = 'skyrl'

attr run_name

run_name: str = 'test_run'

attr logger

logger: str = 'wandb'

attr enable_ray_gpu_monitor

enable_ray_gpu_monitor: bool = True

Enable background Ray GPU/RAM metrics collection and logging to wandb.

attr tags

tags: Optional[List[str]] = None

Optional list of tags to apply to the W&B run. Has no effect on other backends.

attr dump_data_batch

dump_data_batch: bool = False

attr dump_eval_results

dump_eval_results: bool = True

attr print_example_interval

print_example_interval: int = 1

Pretty-print an example prompt/response/reward to stdout every N training steps; 0/-1 disables. Renamed from log_example_interval.

attr num_logger_eval_samples

num_logger_eval_samples: int = -1

Number of evaluation trajectory (prompt, response, score) tuples to upload to a wandb table on each eval. -1 (default) or 0 disables. When positive, up to this many samples are taken from the start of each eval pass and logged via :class:TrajectoryLogger. Column count is fixed by the first call, so keep the eval set size and this value stable.

attr num_logger_train_samples

num_logger_train_samples: int = -1

Number of training trajectory (prompt, response, score) tuples to upload to a wandb table on each training step. -1 (default) or 0 disables. When positive, up to this many samples are taken from the start of each training step and logged via :class:TrajectoryLogger. Column count is fixed by the first call, so keep the training set size and this value stable.

attr log_example_interval

log_example_interval: int = -1

Log an example prompt every N training steps, 0/-1 to disable

attr logprobs_chunk_size

logprobs_chunk_size: Optional[int] = 1024

Chunk size along the sequence dimension when computing log-probs from logits. This lowers peak GPU memory at the cost of ~2x wall-clock time. None disables chunking (Megatron backend only; FSDP requires a positive int). See https://github.com/NovaSky-AI/SkyRL/pull/1610 for more details.

attr vocab_entropy_chunk_size

vocab_entropy_chunk_size: Optional[int] = 0

Chunk size along the sequence dimension when computing Megatron vocab entropy. 0 auto-sizes from the local vocab shard size and vocab_entropy_chunk_memory_mb. None disables chunking.

attr vocab_entropy_chunk_memory_mb

vocab_entropy_chunk_memory_mb: int = 512

Approximate per-chunk temporary memory budget for auto-sized Megatron vocab entropy chunks.

attr fused_lm_head_logprob

fused_lm_head_logprob: bool = False

Megatron only. Fuse the LM-head projection into log-prob / entropy computation so the full [B, S, vocab//TP] logits tensor is never materialized. Uses logprobs_chunk_size to bound peak memory.

attr fused_lm_head_logprob_backend

fused_lm_head_logprob_backend: str = 'torch'

Fused LM-head backend: "torch" (default) or "triton". The Triton backend requires CUDA + triton and falls back to "torch" when unavailable. Ignored unless fused_lm_head_logprob is true.

class OptimizerConfig

OptimizerConfig(lr: float = 1e-06, adam_betas: List[float] = (lambda: [0.9, 0.999])(), weight_decay: float = 0.01, max_grad_norm: float = 1.0, offload_after_step: bool = True, num_warmup_steps: int = 0, scheduler: str = 'constant_with_warmup') -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
lrfloat
adam_betasList[float]
weight_decayfloat
max_grad_normfloat
offload_after_stepboolOffload optimizer state to CPU after each full training step. Only applicable when colocate_all=True.
num_warmup_stepsintNumber of mini-batch steps to warmup the optimizer.
schedulerstr
Source code in skyrl/train/config/config.py:157-167
@dataclass
class OptimizerConfig(BaseConfig):
    lr: float = 1e-6
    adam_betas: List[float] = field(default_factory=lambda: [0.9, 0.999])
    weight_decay: float = 1e-2
    max_grad_norm: float = 1.0
    offload_after_step: bool = True
    """Offload optimizer state to CPU after each full training step. Only applicable when ``colocate_all=True``."""
    num_warmup_steps: int = 0
    """Number of mini-batch steps to warmup the optimizer."""
    scheduler: str = "constant_with_warmup"

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr lr

lr: float = 1e-06

attr adam_betas

adam_betas: List[float] = field(default_factory=(lambda: [0.9, 0.999]))

attr weight_decay

weight_decay: float = 0.01

attr max_grad_norm

max_grad_norm: float = 1.0

attr offload_after_step

offload_after_step: bool = True

Offload optimizer state to CPU after each full training step. Only applicable when colocate_all=True.

attr num_warmup_steps

num_warmup_steps: int = 0

Number of mini-batch steps to warmup the optimizer.

attr scheduler

scheduler: str = 'constant_with_warmup'

class MixedPrecisionConfig

MixedPrecisionConfig(param_dtype: str = 'bf16', reduce_dtype: str = 'fp32', buffer_dtype: str = 'fp32') -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
param_dtypestr
reduce_dtypestr
buffer_dtypestr
Source code in skyrl/train/config/config.py:170-174
@dataclass
class MixedPrecisionConfig(BaseConfig):
    param_dtype: str = "bf16"
    reduce_dtype: str = "fp32"
    buffer_dtype: str = "fp32"

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr param_dtype

param_dtype: str = 'bf16'

attr reduce_dtype

reduce_dtype: str = 'fp32'

attr buffer_dtype

buffer_dtype: str = 'fp32'

Backend Config

class FSDPConfig

FSDPConfig(cpu_offload: bool = False, reshard_after_forward: Union[bool, int] = True, fsdp_size: int = -1, mixed_precision: Optional[MixedPrecisionConfig] = None, wrap_policy: dict = dict()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
cpu_offloadboolOffload params and optimizer state to CPU during the forward pass.
reshard_after_forwardUnion[bool, int]FSDP2 only. Accepts True, False, or an int between 1 and fsdp_size.
fsdp_sizeint
mixed_precisionOptional[MixedPrecisionConfig]
wrap_policydict
Source code in skyrl/train/config/config.py:177-186
@dataclass
class FSDPConfig(BaseConfig):
    cpu_offload: bool = False
    """Offload params and optimizer state to CPU during the forward pass."""
    reshard_after_forward: Union[bool, int] = True
    """FSDP2 only. Accepts True, False, or an int between 1 and ``fsdp_size``."""
    fsdp_size: int = -1
    mixed_precision: Optional[MixedPrecisionConfig] = None
    # specify wrap policy as a dict with `transformer_layer_cls_to_wrap` key for custom module based wrapping
    wrap_policy: dict = field(default_factory=dict)

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr cpu_offload

cpu_offload: bool = False

Offload params and optimizer state to CPU during the forward pass.

attr reshard_after_forward

reshard_after_forward: Union[bool, int] = True

FSDP2 only. Accepts True, False, or an int between 1 and fsdp_size.

attr fsdp_size

fsdp_size: int = -1

attr mixed_precision

mixed_precision: Optional[MixedPrecisionConfig] = None

attr wrap_policy

wrap_policy: dict = field(default_factory=dict)

class MegatronConfig

MegatronConfig(tensor_model_parallel_size: int = 1, pipeline_model_parallel_size: int = 1, context_parallel_size: int = 1, expert_model_parallel_size: int = 1, expert_tensor_parallel_size: Optional[int] = None, moe_token_dispatcher_type: str = 'alltoall', moe_router_load_balancing_type: str = 'none', moe_aux_loss_coeff: float = 0.0, moe_grouped_gemm: bool = True, moe_router_score_function: Optional[str] = None, moe_router_enable_expert_bias: Optional[bool] = None, moe_enable_routing_replay: bool = False, moe_per_layer_logging: bool = False, moe_router_dtype: str = 'fp32', ddp_config: MegatronDDPConfig = MegatronDDPConfig(), hf_export_config: MegatronHFExportConfig = MegatronHFExportConfig(), lora_config: MegatronLoraConfig = MegatronLoraConfig(), optimizer_config_kwargs: Dict[str, Any] = (lambda: copy.deepcopy(DEFAULT_MEGATRON_OPTIMIZER_KWARGS))(), transformer_config_kwargs: Dict[str, Any] = (lambda: copy.deepcopy(DEFAULT_TRANSFORMER_CONFIG_KWARGS))(), empty_cuda_cache: Optional[bool] = True, model_config_kwargs: dict = dict(), dist_ckpt_optim_fully_reshardable: bool = False, freeze_moe_router: bool = False, mtp_num_layers: Optional[int] = None, mtp_loss_weight: float = 0.1, mtp_loss_chunk_size: Optional[int] = 1024, mtp_loss_topk: Optional[int] = None, async_dist_ckpt_save: bool = False, async_dist_ckpt_strategy: str = 'mcore') -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
tensor_model_parallel_sizeint
pipeline_model_parallel_sizeint
context_parallel_sizeint
expert_model_parallel_sizeint
expert_tensor_parallel_sizeOptional[int]
moe_token_dispatcher_typestr
moe_router_load_balancing_typestrSet to "aux_loss", "seq_aux_loss", or "global_aux_loss" to enable aux loss-based load balancing and logging.
moe_aux_loss_coefffloatScaling coefficient for the moe load balancing loss if moe_router_load_balancing_type is not 'none'. Will disable aux loss in megatron-core if set to 0.
moe_grouped_gemmbool
moe_router_score_functionOptional[str]
moe_router_enable_expert_biasOptional[bool]
moe_enable_routing_replaybool
moe_per_layer_loggingboolEnable per-layer logging of MoE metrics (i.e. per layer aux losses).
moe_router_dtypestrPass through to Megatron-Bridge - can be set to 'fp64' for additional numerical stability.
ddp_configMegatronDDPConfig
hf_export_configMegatronHFExportConfig
lora_configMegatronLoraConfig
optimizer_config_kwargsDict[str, Any]
transformer_config_kwargsDict[str, Any]
empty_cuda_cacheOptional[bool]
model_config_kwargsdict
dist_ckpt_optim_fully_reshardablebool
freeze_moe_routerboolIf True, freeze MoE router parameters so they are not updated during training. No-op on
mtp_num_layersOptional[int]Number of Multi-Token Prediction (MTP) heads to build. None honors the model's HF config
mtp_loss_weightfloatWeight w of the draft loss in policy_loss + w * draft_loss. The draft loss is fully
mtp_loss_chunk_sizeOptional[int]Sequence-chunk size for the draft loss, with gradient checkpointing, to bound peak memory at
mtp_loss_topkOptional[int]If set, use a top-k approximation of the soft-CE draft loss: distill only the teacher's top-k
async_dist_ckpt_saveboolWrite the torch_dist checkpoint from a background process so training resumes
async_dist_ckpt_strategystrBackend for the async write. mcore needs no extra deps; megatron-core's own
Source code in skyrl/train/config/config.py:344-417
@dataclass
class MegatronConfig(BaseConfig):
    tensor_model_parallel_size: int = 1
    pipeline_model_parallel_size: int = 1
    context_parallel_size: int = 1
    expert_model_parallel_size: int = 1
    expert_tensor_parallel_size: Optional[int] = None
    # MoE runtime configuration flags
    moe_token_dispatcher_type: str = "alltoall"
    moe_router_load_balancing_type: str = "none"
    """Set to "aux_loss", "seq_aux_loss", or "global_aux_loss" to enable aux loss-based load balancing and logging."""
    moe_aux_loss_coeff: float = 0.0
    """Scaling coefficient for the moe load balancing loss if moe_router_load_balancing_type is not 'none'. Will disable aux loss in megatron-core if set to 0."""
    moe_grouped_gemm: bool = True
    moe_router_score_function: Optional[str] = None
    moe_router_enable_expert_bias: Optional[bool] = None
    moe_enable_routing_replay: bool = False
    moe_per_layer_logging: bool = False
    """Enable per-layer logging of MoE metrics (i.e. per layer aux losses)."""
    moe_router_dtype: str = "fp32"
    """Pass through to Megatron-Bridge - can be set to 'fp64' for additional numerical stability."""
    ddp_config: MegatronDDPConfig = field(default_factory=MegatronDDPConfig)
    hf_export_config: MegatronHFExportConfig = field(default_factory=MegatronHFExportConfig)
    lora_config: MegatronLoraConfig = field(default_factory=MegatronLoraConfig)
    optimizer_config_kwargs: Dict[str, Any] = field(
        default_factory=lambda: copy.deepcopy(DEFAULT_MEGATRON_OPTIMIZER_KWARGS)
    )
    transformer_config_kwargs: Dict[str, Any] = field(
        default_factory=lambda: copy.deepcopy(DEFAULT_TRANSFORMER_CONFIG_KWARGS)
    )
    empty_cuda_cache: Optional[bool] = True
    model_config_kwargs: dict = field(default_factory=dict)
    dist_ckpt_optim_fully_reshardable: bool = False
    freeze_moe_router: bool = False
    """If True, freeze MoE router parameters so they are not updated during training. No-op on
    non-MoE models."""
    mtp_num_layers: Optional[int] = None
    """Number of Multi-Token Prediction (MTP) heads to build. ``None`` honors the model's HF config
    (``num_nextn_predict_layers``); an int overrides it (``0`` force-disables MTP). Active heads are
    trained with the decoupled draft loss and synced to vLLM for speculative decoding."""
    mtp_loss_weight: float = 0.1
    """Weight ``w`` of the draft loss in ``policy_loss + w * draft_loss``. The draft loss is fully
    decoupled: trunk, re-embedding, output weight and teacher are all detached, so its gradient
    reaches only the ``.mtp.`` head params. Only used when MTP heads are active."""
    mtp_loss_chunk_size: Optional[int] = 1024
    """Sequence-chunk size for the draft loss, with gradient checkpointing, to bound peak memory at
    large vocab (e.g. Qwen3.5's 248K, where the full-sequence softmax OOMs). Numerically identical to
    no chunking. ``None`` disables it; ignored when ``mtp_loss_topk`` is set."""
    mtp_loss_topk: Optional[int] = None
    """If set, use a top-k approximation of the soft-CE draft loss: distill only the teacher's top-k
    tokens (renormalized), ``O(seq*k)`` memory instead of ``O(seq*vocab)`` -- fits at large vocab
    without fragmentation. Reconciled across the TP group, so it scales to any parallel size.
    ``None`` uses the exact full-vocab loss. Typical: 64-128."""
    async_dist_ckpt_save: bool = False
    """Write the torch_dist checkpoint from a background process so training resumes
    immediately; the pending write is finalized at the next checkpoint and at shutdown.
    The on-disk format is identical to a synchronous save. Only the sharded
    model/optimizer state is async -- the rank-0 HF config/tokenizer write stays inline.
    Falls back to synchronous for cloud paths."""
    async_dist_ckpt_strategy: str = "mcore"
    """Backend for the async write. ``mcore`` needs no extra deps; megatron-core's own
    default ``nvrx`` requires nvidia-resiliency-ext. Only used when async saves are on."""

    def __post_init__(self):
        # Backfill defaults for any keys the user didn't override so an override dict
        # doesn't have to repeat every default just to set one value.
        if self.transformer_config_kwargs is None:
            self.transformer_config_kwargs = {}
        for k, v in DEFAULT_TRANSFORMER_CONFIG_KWARGS.items():
            self.transformer_config_kwargs.setdefault(k, copy.deepcopy(v))
        if self.optimizer_config_kwargs is None:
            self.optimizer_config_kwargs = {}
        for k, v in DEFAULT_MEGATRON_OPTIMIZER_KWARGS.items():
            self.optimizer_config_kwargs.setdefault(k, copy.deepcopy(v))

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr tensor_model_parallel_size

tensor_model_parallel_size: int = 1

attr pipeline_model_parallel_size

pipeline_model_parallel_size: int = 1

attr context_parallel_size

context_parallel_size: int = 1

attr expert_model_parallel_size

expert_model_parallel_size: int = 1

attr expert_tensor_parallel_size

expert_tensor_parallel_size: Optional[int] = None

attr moe_token_dispatcher_type

moe_token_dispatcher_type: str = 'alltoall'

attr moe_router_load_balancing_type

moe_router_load_balancing_type: str = 'none'

Set to "aux_loss", "seq_aux_loss", or "global_aux_loss" to enable aux loss-based load balancing and logging.

attr moe_aux_loss_coeff

moe_aux_loss_coeff: float = 0.0

Scaling coefficient for the moe load balancing loss if moe_router_load_balancing_type is not 'none'. Will disable aux loss in megatron-core if set to 0.

attr moe_grouped_gemm

moe_grouped_gemm: bool = True

attr moe_router_score_function

moe_router_score_function: Optional[str] = None

attr moe_router_enable_expert_bias

moe_router_enable_expert_bias: Optional[bool] = None

attr moe_enable_routing_replay

moe_enable_routing_replay: bool = False

attr moe_per_layer_logging

moe_per_layer_logging: bool = False

Enable per-layer logging of MoE metrics (i.e. per layer aux losses).

attr moe_router_dtype

moe_router_dtype: str = 'fp32'

Pass through to Megatron-Bridge - can be set to 'fp64' for additional numerical stability.

attr ddp_config

ddp_config: MegatronDDPConfig = field(default_factory=MegatronDDPConfig)

attr hf_export_config

hf_export_config: MegatronHFExportConfig = field(default_factory=MegatronHFExportConfig)

attr lora_config

lora_config: MegatronLoraConfig = field(default_factory=MegatronLoraConfig)

attr optimizer_config_kwargs

optimizer_config_kwargs: Dict[str, Any] = field(default_factory=(lambda: copy.deepcopy(DEFAULT_MEGATRON_OPTIMIZER_KWARGS)))

attr transformer_config_kwargs

transformer_config_kwargs: Dict[str, Any] = field(default_factory=(lambda: copy.deepcopy(DEFAULT_TRANSFORMER_CONFIG_KWARGS)))

attr empty_cuda_cache

empty_cuda_cache: Optional[bool] = True

attr model_config_kwargs

model_config_kwargs: dict = field(default_factory=dict)

attr dist_ckpt_optim_fully_reshardable

dist_ckpt_optim_fully_reshardable: bool = False

attr freeze_moe_router

freeze_moe_router: bool = False

If True, freeze MoE router parameters so they are not updated during training. No-op on non-MoE models.

attr mtp_num_layers

mtp_num_layers: Optional[int] = None

Number of Multi-Token Prediction (MTP) heads to build. None honors the model's HF config (num_nextn_predict_layers); an int overrides it (0 force-disables MTP). Active heads are trained with the decoupled draft loss and synced to vLLM for speculative decoding.

attr mtp_loss_weight

mtp_loss_weight: float = 0.1

Weight w of the draft loss in policy_loss + w * draft_loss. The draft loss is fully decoupled: trunk, re-embedding, output weight and teacher are all detached, so its gradient reaches only the .mtp. head params. Only used when MTP heads are active.

attr mtp_loss_chunk_size

mtp_loss_chunk_size: Optional[int] = 1024

Sequence-chunk size for the draft loss, with gradient checkpointing, to bound peak memory at large vocab (e.g. Qwen3.5's 248K, where the full-sequence softmax OOMs). Numerically identical to no chunking. None disables it; ignored when mtp_loss_topk is set.

attr mtp_loss_topk

mtp_loss_topk: Optional[int] = None

If set, use a top-k approximation of the soft-CE draft loss: distill only the teacher's top-k tokens (renormalized), O(seq*k) memory instead of O(seq*vocab) -- fits at large vocab without fragmentation. Reconciled across the TP group, so it scales to any parallel size. None uses the exact full-vocab loss. Typical: 64-128.

attr async_dist_ckpt_save

async_dist_ckpt_save: bool = False

Write the torch_dist checkpoint from a background process so training resumes immediately; the pending write is finalized at the next checkpoint and at shutdown. The on-disk format is identical to a synchronous save. Only the sharded model/optimizer state is async -- the rank-0 HF config/tokenizer write stays inline. Falls back to synchronous for cloud paths.

attr async_dist_ckpt_strategy

async_dist_ckpt_strategy: str = 'mcore'

Backend for the async write. mcore needs no extra deps; megatron-core's own default nvrx requires nvidia-resiliency-ext. Only used when async saves are on.

class MegatronDDPConfig

MegatronDDPConfig(grad_reduce_in_fp32: bool = True, overlap_grad_reduce: bool = False, overlap_param_gather: bool = False, average_in_collective: bool = True) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

Source code in skyrl/train/config/config.py:194-199
@dataclass
class MegatronDDPConfig(BaseConfig):
    grad_reduce_in_fp32: bool = True
    overlap_grad_reduce: bool = False
    overlap_param_gather: bool = False
    average_in_collective: bool = True

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr grad_reduce_in_fp32

grad_reduce_in_fp32: bool = True

attr overlap_grad_reduce

overlap_grad_reduce: bool = False

attr overlap_param_gather

overlap_param_gather: bool = False

attr average_in_collective

average_in_collective: bool = True

class MegatronLoraConfig

MegatronLoraConfig(lora_type: str = 'lora', merge_lora: bool = True) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
lora_typestr
merge_lorabool
Source code in skyrl/train/config/config.py:322-325
@dataclass
class MegatronLoraConfig(BaseConfig):
    lora_type: str = "lora"
    merge_lora: bool = True

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr lora_type

lora_type: str = 'lora'

attr merge_lora

merge_lora: bool = True

class TorchProfilerConfig

TorchProfilerConfig(enable: bool = False, ranks: List[int] = (lambda: [0])(), save_path: Optional[str] = None, skip_first: int = 10, wait: int = 0, warmup: int = 1, active: int = 1, repeat: int = 1, activities: List[str] = (lambda: ['cpu', 'cuda'])(), record_shapes: bool = True, profile_memory: bool = False, with_stack: bool = True, with_flops: bool = False, with_modules: bool = False, export_type: str = 'chrome_trace') -> None

Bases: BaseConfig

torch.profiler config for policy training steps.

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.
validateFail fast on invalid or known-incompatible profiler settings.

Attributes:

NameTypeDescription
enablebool
ranksList[int]
save_pathOptional[str]Trace output dir. Required when enable=True; must be a local absolute path.
skip_firstintSteps to skip before scheduling begins.
waitint
warmupint
activeintNumber of steps recorded per cycle.
repeatintNumber of cycles. 0 means forever.
activitiesList[str]
record_shapesbool
profile_memorybool
with_stackbool
with_flopsbool
with_modulesbool
export_typestrchrome_trace or stacks; stacks require with_stack=True.
Source code in skyrl/train/config/config.py:206-301
@dataclass
class TorchProfilerConfig(BaseConfig):
    """``torch.profiler`` config for policy training steps."""

    enable: bool = False
    ranks: List[int] = field(default_factory=lambda: [0])
    save_path: Optional[str] = None
    """Trace output dir. Required when ``enable=True``; must be a local absolute path."""

    # torch.profiler.schedule
    skip_first: int = 10
    """Steps to skip before scheduling begins."""
    wait: int = 0
    warmup: int = 1
    active: int = 1
    """Number of steps recorded per cycle."""
    repeat: int = 1
    """Number of cycles. 0 means forever."""

    # torch.profiler.profile
    activities: List[str] = field(default_factory=lambda: ["cpu", "cuda"])
    record_shapes: bool = True
    profile_memory: bool = False
    with_stack: bool = True
    with_flops: bool = False
    with_modules: bool = False
    export_type: str = "chrome_trace"
    """``chrome_trace`` or ``stacks``; stacks require ``with_stack=True``."""

    def validate(
        self,
        strategy: Optional[str] = None,
        colocate_all: Optional[bool] = None,
        colocate_policy_ref: Optional[bool] = None,
        fsdp_cpu_offload: Optional[bool] = None,
    ) -> None:
        """Fail fast on invalid or known-incompatible profiler settings."""
        if not self.enable:
            return
        if not self.ranks:
            raise ValueError("`torch_profiler_config.ranks` must be non-empty when profiling is enabled.")
        # Avoid implicit relative paths in Ray runtime working dirs.
        if not self.save_path:
            raise ValueError(
                "`torch_profiler_config.save_path` must be set when profiling is enabled. "
                "Use an absolute local path -- Ray workers run from a /tmp/ray runtime "
                "working dir, so a relative path would write traces there."
            )
        from skyrl.backends.skyrl_train.utils.io.io import is_cloud_path

        if is_cloud_path(self.save_path):
            raise ValueError(
                f"`torch_profiler_config.save_path` must be a local path; got cloud URI "
                f"{self.save_path!r}. torch.profiler cannot write to cloud storage."
            )
        # Empty activities record nothing.
        if not self.activities:
            raise ValueError("`torch_profiler_config.activities` must be non-empty when profiling is enabled.")
        bad_activities = [a for a in self.activities if a.lower() not in TORCH_PROFILER_ACTIVITIES]
        if bad_activities:
            raise ValueError(
                f"invalid `torch_profiler_config.activities` entries {bad_activities}. "
                f"Each must be one of {list(TORCH_PROFILER_ACTIVITIES)}."
            )
        if self.export_type not in TORCH_PROFILER_EXPORT_TYPES:
            raise ValueError(
                f"invalid `torch_profiler_config.export_type`: {self.export_type!r}. "
                f"Must be one of {list(TORCH_PROFILER_EXPORT_TYPES)}."
            )
        if self.export_type == "stacks" and not self.with_stack:
            raise ValueError(
                "`torch_profiler_config.export_type='stacks'` requires `with_stack=true` "
                "(torch.profiler.export_stacks needs stack records)."
            )
        for name in ("skip_first", "wait", "warmup", "repeat"):
            value = getattr(self, name)
            if value < 0:
                raise ValueError(f"`torch_profiler_config.{name}` must be >= 0, got {value}.")
        if self.active < 1:
            raise ValueError(f"`torch_profiler_config.active` must be >= 1, got {self.active}.")

        # FSDP manual CPU offload uses swap_tensors, which conflicts with profiler-held
        # parameter refs during colocated runs.
        if strategy == "fsdp" and fsdp_cpu_offload is False and (colocate_all or colocate_policy_ref):
            raise ValueError(
                "`torch_profiler_config.enable=true` is incompatible with this FSDP configuration: "
                "with the manual CPU-offload path (`policy.fsdp_config.cpu_offload=false`, the default) "
                "under colocation "
                f"(`placement.colocate_all={colocate_all}`, `placement.colocate_policy_ref={colocate_policy_ref}`), "
                "the trainer offloads models to CPU via `torch.utils.swap_tensors` while the profiler holds "
                "references to their parameters, which crashes mid-run with "
                "`RuntimeError: _apply(): Couldn't swap <param>`. "
                "To profile: set `policy.fsdp_config.cpu_offload=true` (FSDP2-native offload, no swap), or "
                "disable colocation (`placement.colocate_all=false` and `placement.colocate_policy_ref=false`), "
                "or use the Megatron backend (`trainer.strategy=megatron`)."
            )

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr enable

enable: bool = False

attr ranks

ranks: List[int] = field(default_factory=(lambda: [0]))

attr save_path

save_path: Optional[str] = None

Trace output dir. Required when enable=True; must be a local absolute path.

attr skip_first

skip_first: int = 10

Steps to skip before scheduling begins.

attr wait

wait: int = 0

attr warmup

warmup: int = 1

attr active

active: int = 1

Number of steps recorded per cycle.

attr repeat

repeat: int = 1

Number of cycles. 0 means forever.

attr activities

activities: List[str] = field(default_factory=(lambda: ['cpu', 'cuda']))

attr record_shapes

record_shapes: bool = True

attr profile_memory

profile_memory: bool = False

attr with_stack

with_stack: bool = True

attr with_flops

with_flops: bool = False

attr with_modules

with_modules: bool = False

attr export_type

export_type: str = 'chrome_trace'

chrome_trace or stacks; stacks require with_stack=True.

method validate

validate(strategy: Optional[str] = None, colocate_all: Optional[bool] = None, colocate_policy_ref: Optional[bool] = None, fsdp_cpu_offload: Optional[bool] = None) -> None

Fail fast on invalid or known-incompatible profiler settings.

Source code in skyrl/train/config/config.py:235-301
    def validate(
        self,
        strategy: Optional[str] = None,
        colocate_all: Optional[bool] = None,
        colocate_policy_ref: Optional[bool] = None,
        fsdp_cpu_offload: Optional[bool] = None,
    ) -> None:
        """Fail fast on invalid or known-incompatible profiler settings."""
        if not self.enable:
            return
        if not self.ranks:
            raise ValueError("`torch_profiler_config.ranks` must be non-empty when profiling is enabled.")
        # Avoid implicit relative paths in Ray runtime working dirs.
        if not self.save_path:
            raise ValueError(
                "`torch_profiler_config.save_path` must be set when profiling is enabled. "
                "Use an absolute local path -- Ray workers run from a /tmp/ray runtime "
                "working dir, so a relative path would write traces there."
            )
        from skyrl.backends.skyrl_train.utils.io.io import is_cloud_path

        if is_cloud_path(self.save_path):
            raise ValueError(
                f"`torch_profiler_config.save_path` must be a local path; got cloud URI "
                f"{self.save_path!r}. torch.profiler cannot write to cloud storage."
            )
        # Empty activities record nothing.
        if not self.activities:
            raise ValueError("`torch_profiler_config.activities` must be non-empty when profiling is enabled.")
        bad_activities = [a for a in self.activities if a.lower() not in TORCH_PROFILER_ACTIVITIES]
        if bad_activities:
            raise ValueError(
                f"invalid `torch_profiler_config.activities` entries {bad_activities}. "
                f"Each must be one of {list(TORCH_PROFILER_ACTIVITIES)}."
            )
        if self.export_type not in TORCH_PROFILER_EXPORT_TYPES:
            raise ValueError(
                f"invalid `torch_profiler_config.export_type`: {self.export_type!r}. "
                f"Must be one of {list(TORCH_PROFILER_EXPORT_TYPES)}."
            )
        if self.export_type == "stacks" and not self.with_stack:
            raise ValueError(
                "`torch_profiler_config.export_type='stacks'` requires `with_stack=true` "
                "(torch.profiler.export_stacks needs stack records)."
            )
        for name in ("skip_first", "wait", "warmup", "repeat"):
            value = getattr(self, name)
            if value < 0:
                raise ValueError(f"`torch_profiler_config.{name}` must be >= 0, got {value}.")
        if self.active < 1:
            raise ValueError(f"`torch_profiler_config.active` must be >= 1, got {self.active}.")

        # FSDP manual CPU offload uses swap_tensors, which conflicts with profiler-held
        # parameter refs during colocated runs.
        if strategy == "fsdp" and fsdp_cpu_offload is False and (colocate_all or colocate_policy_ref):
            raise ValueError(
                "`torch_profiler_config.enable=true` is incompatible with this FSDP configuration: "
                "with the manual CPU-offload path (`policy.fsdp_config.cpu_offload=false`, the default) "
                "under colocation "
                f"(`placement.colocate_all={colocate_all}`, `placement.colocate_policy_ref={colocate_policy_ref}`), "
                "the trainer offloads models to CPU via `torch.utils.swap_tensors` while the profiler holds "
                "references to their parameters, which crashes mid-run with "
                "`RuntimeError: _apply(): Couldn't swap <param>`. "
                "To profile: set `policy.fsdp_config.cpu_offload=true` (FSDP2-native offload, no swap), or "
                "disable colocation (`placement.colocate_all=false` and `placement.colocate_policy_ref=false`), "
                "or use the Megatron backend (`trainer.strategy=megatron`)."
            )

Placement

class PlacementConfig

PlacementConfig(colocate_all: bool = True, colocate_policy_ref: bool = True, policy_num_nodes: int = 1, policy_num_gpus_per_node: int = 1, critic_num_nodes: int = 1, critic_num_gpus_per_node: int = 1, ref_num_nodes: int = 1, ref_num_gpus_per_node: int = 1) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
colocate_allboolWhen True, training and inference share the same GPUs.
colocate_policy_refboolWhen colocate_all is False, True (default) still colocates policy and ref
policy_num_nodesint
policy_num_gpus_per_nodeint
critic_num_nodesint
critic_num_gpus_per_nodeint
ref_num_nodesint
ref_num_gpus_per_nodeint
Source code in skyrl/train/config/config.py:425-439
@dataclass
class PlacementConfig(BaseConfig):
    colocate_all: bool = True
    """When True, training and inference share the same GPUs."""
    colocate_policy_ref: bool = True
    """When colocate_all is False, True (default) still colocates policy and ref
    on the same GPUs (one shared placement group). Set this item to False to place
    policy and ref on separate GPUs (their own placement groups); needed when
    a large model's policy and ref shards can't both fit on one GPU."""
    policy_num_nodes: int = 1
    policy_num_gpus_per_node: int = 1
    critic_num_nodes: int = 1
    critic_num_gpus_per_node: int = 1
    ref_num_nodes: int = 1
    ref_num_gpus_per_node: int = 1

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr colocate_all

colocate_all: bool = True

When True, training and inference share the same GPUs.

attr colocate_policy_ref

colocate_policy_ref: bool = True

When colocate_all is False, True (default) still colocates policy and ref on the same GPUs (one shared placement group). Set this item to False to place policy and ref on separate GPUs (their own placement groups); needed when a large model's policy and ref shards can't both fit on one GPU.

attr policy_num_nodes

policy_num_nodes: int = 1

attr policy_num_gpus_per_node

policy_num_gpus_per_node: int = 1

attr critic_num_nodes

critic_num_nodes: int = 1

attr critic_num_gpus_per_node

critic_num_gpus_per_node: int = 1

attr ref_num_nodes

ref_num_nodes: int = 1

attr ref_num_gpus_per_node

ref_num_gpus_per_node: int = 1

Policy & Algorithm

class PolicyConfig

PolicyConfig(model: ModelConfig = (lambda: copy.deepcopy(ModelConfig(path='Qwen/Qwen2.5-1.5B-Instruct')))(), optimizer_config: OptimizerConfig = OptimizerConfig(), fsdp_config: FSDPConfig = FSDPConfig(), sequence_parallel_size: int = 1, use_torch_compile: bool = False, record_memory: bool = False, torch_profiler_config: TorchProfilerConfig = TorchProfilerConfig(), megatron_config: MegatronConfig = MegatronConfig(), model_config_kwargs: dict = dict(), language_model_only: bool = False, inference_only_init: bool = False) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
modelModelConfig
optimizer_configOptimizerConfig
fsdp_configFSDPConfig
sequence_parallel_sizeint
use_torch_compileboolApply torch.compile to logits calculation.
record_memoryboolSave memory snapshots to {ckpt_path}/memory_snapshots/.
torch_profiler_configTorchProfilerConfigtorch.profiler config for policy training steps.
megatron_configMegatronConfig
model_config_kwargsdictPass-through kwargs for the HuggingFace model config (FSDP backends).
language_model_onlyboolWhen True, skip vision encoder initialization for multimodal models (e.g. Qwen3.5).
inference_only_initboolWhen True, set up the policy worker for inference-only flows (forward + weight
Source code in skyrl/train/config/config.py:447-475
@dataclass
class PolicyConfig(BaseConfig):
    model: ModelConfig = field(default_factory=lambda: copy.deepcopy(ModelConfig(path="Qwen/Qwen2.5-1.5B-Instruct")))
    optimizer_config: OptimizerConfig = field(default_factory=OptimizerConfig)
    fsdp_config: FSDPConfig = field(default_factory=FSDPConfig)
    sequence_parallel_size: int = 1
    use_torch_compile: bool = False
    """Apply torch.compile to logits calculation."""
    record_memory: bool = False
    """Save memory snapshots to ``{ckpt_path}/memory_snapshots/``.
    Visualize by dragging pickle files to https://docs.pytorch.org/memory_viz."""
    torch_profiler_config: TorchProfilerConfig = field(default_factory=TorchProfilerConfig)
    """``torch.profiler`` config for policy training steps."""
    megatron_config: MegatronConfig = field(default_factory=MegatronConfig)
    model_config_kwargs: dict = field(default_factory=dict)
    """Pass-through kwargs for the HuggingFace model config (FSDP backends).
    For Megatron, use ``policy.megatron_config.transformer_config_kwargs`` instead."""
    language_model_only: bool = False
    """When True, skip vision encoder initialization for multimodal models (e.g. Qwen3.5).
    Loads only the language model backbone using AutoModelForCausalLM."""
    inference_only_init: bool = False
    """When True, set up the policy worker for inference-only flows (forward + weight
    sync, no train_step), skipping the training-only state that would otherwise OOM
    memory-constrained nodes (e.g. large MoE on 4xH100). NOT valid for actual training.
    Backend-specific behavior:
    - FSDP: initialize weights in bf16 instead of fp32 (skipping the fp32 master weights
      that mixed-precision training requires) and skip optimizer/LR-scheduler construction.
    - Megatron: skip optimizer/LR-scheduler construction (DistributedOptimizer eagerly
      materializes fp32 master + AdamW state on GPU)."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr model

model: ModelConfig = field(default_factory=(lambda: copy.deepcopy(ModelConfig(path='Qwen/Qwen2.5-1.5B-Instruct'))))

attr optimizer_config

optimizer_config: OptimizerConfig = field(default_factory=OptimizerConfig)

attr fsdp_config

fsdp_config: FSDPConfig = field(default_factory=FSDPConfig)

attr sequence_parallel_size

sequence_parallel_size: int = 1

attr use_torch_compile

use_torch_compile: bool = False

Apply torch.compile to logits calculation.

attr record_memory

record_memory: bool = False

Save memory snapshots to {ckpt_path}/memory_snapshots/. Visualize by dragging pickle files to https://docs.pytorch.org/memory_viz.

attr torch_profiler_config

torch_profiler_config: TorchProfilerConfig = field(default_factory=TorchProfilerConfig)

torch.profiler config for policy training steps.

attr megatron_config

megatron_config: MegatronConfig = field(default_factory=MegatronConfig)

attr model_config_kwargs

model_config_kwargs: dict = field(default_factory=dict)

Pass-through kwargs for the HuggingFace model config (FSDP backends). For Megatron, use policy.megatron_config.transformer_config_kwargs instead.

attr language_model_only

language_model_only: bool = False

When True, skip vision encoder initialization for multimodal models (e.g. Qwen3.5). Loads only the language model backbone using AutoModelForCausalLM.

attr inference_only_init

inference_only_init: bool = False

When True, set up the policy worker for inference-only flows (forward + weight sync, no train_step), skipping the training-only state that would otherwise OOM memory-constrained nodes (e.g. large MoE on 4xH100). NOT valid for actual training. Backend-specific behavior:

  • FSDP: initialize weights in bf16 instead of fp32 (skipping the fp32 master weights that mixed-precision training requires) and skip optimizer/LR-scheduler construction.
  • Megatron: skip optimizer/LR-scheduler construction (DistributedOptimizer eagerly materializes fp32 master + AdamW state on GPU).

class CriticConfig

CriticConfig(model: ModelConfig = ModelConfig(), optimizer_config: OptimizerConfig = (lambda: OptimizerConfig(lr=5e-06))(), fsdp_config: FSDPConfig = FSDPConfig(), sequence_parallel_size: int = 1, model_config_kwargs: dict = dict()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

Source code in skyrl/train/config/config.py:478-484
@dataclass
class CriticConfig(BaseConfig):
    model: ModelConfig = field(default_factory=ModelConfig)
    optimizer_config: OptimizerConfig = field(default_factory=lambda: OptimizerConfig(lr=5e-6))
    fsdp_config: FSDPConfig = field(default_factory=FSDPConfig)
    sequence_parallel_size: int = 1
    model_config_kwargs: dict = field(default_factory=dict)

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr model

model: ModelConfig = field(default_factory=ModelConfig)

attr optimizer_config

optimizer_config: OptimizerConfig = field(default_factory=(lambda: OptimizerConfig(lr=5e-06)))

attr fsdp_config

fsdp_config: FSDPConfig = field(default_factory=FSDPConfig)

attr sequence_parallel_size

sequence_parallel_size: int = 1

attr model_config_kwargs

model_config_kwargs: dict = field(default_factory=dict)

class RefConfig

RefConfig(model: ModelConfig = ModelConfig(), sequence_parallel_size: int = 1, fsdp_config: FSDPConfig = FSDPConfig(), megatron_config: MegatronConfig = MegatronConfig(), model_config_kwargs: dict = dict(), language_model_only: bool = False) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
modelModelConfig
sequence_parallel_sizeint
fsdp_configFSDPConfig
megatron_configMegatronConfig
model_config_kwargsdict
language_model_onlyboolWhen True, skip vision encoder initialization for multimodal models (e.g. Qwen3.5).
Source code in skyrl/train/config/config.py:488-497
@dataclass
class RefConfig(BaseConfig):
    model: ModelConfig = field(default_factory=ModelConfig)
    sequence_parallel_size: int = 1
    fsdp_config: FSDPConfig = field(default_factory=FSDPConfig)
    megatron_config: MegatronConfig = field(default_factory=MegatronConfig)
    model_config_kwargs: dict = field(default_factory=dict)
    language_model_only: bool = False
    """When True, skip vision encoder initialization for multimodal models (e.g. Qwen3.5).
    Loads only the language model backbone using AutoModelForCausalLM."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr model

model: ModelConfig = field(default_factory=ModelConfig)

attr sequence_parallel_size

sequence_parallel_size: int = 1

attr fsdp_config

fsdp_config: FSDPConfig = field(default_factory=FSDPConfig)

attr megatron_config

megatron_config: MegatronConfig = field(default_factory=MegatronConfig)

attr model_config_kwargs

model_config_kwargs: dict = field(default_factory=dict)

attr language_model_only

language_model_only: bool = False

When True, skip vision encoder initialization for multimodal models (e.g. Qwen3.5). Loads only the language model backbone using AutoModelForCausalLM.

class AlgorithmConfig

AlgorithmConfig(advantage_estimator: str = 'grpo', kl_ctrl: KLCtrlConfig = KLCtrlConfig(), kl_estimator_type: str = 'k3', use_kl_in_reward: bool = False, use_kl_loss: bool = True, kl_loss_coef: float = 0.001, use_entropy_loss: bool = False, entropy_loss_coef: float = 0.01, temperature: Optional[float] = None, advantage_batch_normalize: bool = False, value_head_prefix: str = 'value_head', policy_loss_type: str = 'regular', loss_reduction: str = 'token_mean', grpo_norm_by_std: bool = True, zero_variance_filter: bool = False, zero_variance_filter_tol: float = 1e-06, lambd: float = 1.0, gamma: float = 1.0, eps_clip_low: float = 0.2, eps_clip_high: float = 0.2, clip_ratio_c: float = 3.0, tis_imp_ratio_cap: float = -1.0, use_tis: bool = False, off_policy_correction: OffPolicyCorrectionConfig = OffPolicyCorrectionConfig(), sapo: SAPOConfig = SAPOConfig(), value_clip: float = 0.2, dynamic_sampling: DynamicSamplingConfig = DynamicSamplingConfig(), clip_cov: ClipCovConfig = ClipCovConfig(), kl_cov: KLCovConfig = KLCovConfig(), cispo: CISPOConfig = CISPOConfig(), dppo: DPPOConfig = DPPOConfig(), max_seq_len: Optional[int] = None) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
advantage_estimatorstr"grpo", "gae", "rloo", "reinforce++", or custom via AdvantageEstimatorRegistry.
kl_ctrlKLCtrlConfigOnly used when use_kl_in_reward=True (not applied when use_kl_loss=True).
kl_estimator_typestr"k1", "k2", "k3", "abs". See http://joschu.net/blog/kl-approx.html.
use_kl_in_rewardboolApply KL penalty to rewards. Mutually exclusive with use_kl_loss.
use_kl_lossboolApply KL loss in the policy model. Mutually exclusive with use_kl_in_reward.
kl_loss_coeffloat
use_entropy_lossbool
entropy_loss_coeffloat
temperatureOptional[float]Temperature for scaling logits in policy loss computation.
advantage_batch_normalizebool
value_head_prefixstr
policy_loss_typestr"regular", "dual_clip", "gspo", "clip_cov", "kl_cov", cispo, sapo, "rollout_is", "dppo", or custom via PolicyLossRegistry.
loss_reductionstr"token_mean", "sequence_mean", "prompt_mean", or "seq_mean_token_sum_norm". max_seq_len must be set explicitly for "seq_mean_token_sum_norm".
grpo_norm_by_stdbool
zero_variance_filterboolLoss-mask prompts with zero-variance rewards. Only applicable when rewards are response-level.
zero_variance_filter_tolfloatTwo rewards within this absolute tolerance count as equal when detecting zero-variance groups.
lambdfloat
gammafloat
eps_clip_lowfloat
eps_clip_highfloat
clip_ratio_cfloatDual-clip parameter.
tis_imp_ratio_capfloatDeprecated: use off_policy_correction.tis_ratio_type="token" and token_tis_ratio_clip_high instead.
use_tisboolDeprecated: use off_policy_correction instead.
off_policy_correctionOffPolicyCorrectionConfig
sapoSAPOConfig
value_clipfloat
dynamic_samplingDynamicSamplingConfig
clip_covClipCovConfigOnly used when policy_loss_type="clip_cov".
kl_covKLCovConfigOnly used when policy_loss_type="kl_cov".
cispoCISPOConfigOnly used when policy_loss_type="cispo".
dppoDPPOConfigOnly used when policy_loss_type="dppo".
max_seq_lenOptional[int]Used for seq_mean_token_sum_norm loss reduction.
Source code in skyrl/train/config/config.py:610-670
@dataclass
class AlgorithmConfig(BaseConfig):
    advantage_estimator: str = "grpo"
    """``"grpo"``, ``"gae"``, ``"rloo"``, ``"reinforce++"``, or custom via ``AdvantageEstimatorRegistry``."""
    kl_ctrl: KLCtrlConfig = field(default_factory=KLCtrlConfig)
    """Only used when ``use_kl_in_reward=True`` (not applied when ``use_kl_loss=True``).
    Uses ``kl_loss_coef`` as the initial KL coefficient."""
    kl_estimator_type: str = "k3"
    """``"k1"``, ``"k2"``, ``"k3"``, ``"abs"``. See http://joschu.net/blog/kl-approx.html."""
    use_kl_in_reward: bool = False
    """Apply KL penalty to rewards. Mutually exclusive with ``use_kl_loss``."""
    use_kl_loss: bool = True
    """Apply KL loss in the policy model. Mutually exclusive with ``use_kl_in_reward``."""
    kl_loss_coef: float = 0.001
    use_entropy_loss: bool = False
    entropy_loss_coef: float = 0.01
    temperature: Optional[float] = None
    """Temperature for scaling logits in policy loss computation.
    If ``None``, will be set to the temperature provided by ``generator.sampling_params.temperature`` during config validation.
    
    NOTE: When using HTTP endpoints directly, make sure to set this value to the temperature used during generation
    """
    advantage_batch_normalize: bool = False
    value_head_prefix: str = "value_head"
    policy_loss_type: str = "regular"
    """``"regular"``, ``"dual_clip"``, ``"gspo"``, ``"clip_cov"``, ``"kl_cov"``, ``cispo``, ``sapo``, ``"rollout_is"``, ``"dppo"``, or custom via ``PolicyLossRegistry``."""
    loss_reduction: str = "token_mean"
    """``"token_mean"``, ``"sequence_mean"``, ``"prompt_mean"``, or ``"seq_mean_token_sum_norm"``. ``max_seq_len`` must be set explicitly for ``"seq_mean_token_sum_norm"``."""
    grpo_norm_by_std: bool = True
    zero_variance_filter: bool = False
    """Loss-mask prompts with zero-variance rewards. Only applicable when rewards are response-level."""
    zero_variance_filter_tol: float = 1e-6
    """Two rewards within this absolute tolerance count as equal when detecting zero-variance groups.
    Only used when ``zero_variance_filter=True``. Defaults to 1e-6 so float (LLM-judge) rewards that are
    effectively identical are still treated as zero-variance; this is a no-op for integer rewards (e.g.
    0/1) where the spread is either 0 or >= 1. Set to 0.0 for exact equality."""
    lambd: float = 1.0
    gamma: float = 1.0
    eps_clip_low: float = 0.2
    eps_clip_high: float = 0.2
    clip_ratio_c: float = 3.0
    """Dual-clip parameter."""
    tis_imp_ratio_cap: float = -1.0
    """Deprecated: use ``off_policy_correction.tis_ratio_type="token"`` and ``token_tis_ratio_clip_high`` instead."""
    use_tis: bool = False
    """Deprecated: use ``off_policy_correction`` instead."""
    off_policy_correction: OffPolicyCorrectionConfig = field(default_factory=OffPolicyCorrectionConfig)
    sapo: SAPOConfig = field(default_factory=SAPOConfig)
    value_clip: float = 0.2
    dynamic_sampling: DynamicSamplingConfig = field(default_factory=DynamicSamplingConfig)
    clip_cov: ClipCovConfig = field(default_factory=ClipCovConfig)
    """Only used when ``policy_loss_type="clip_cov"``."""
    kl_cov: KLCovConfig = field(default_factory=KLCovConfig)
    """Only used when ``policy_loss_type="kl_cov"``."""
    cispo: CISPOConfig = field(default_factory=CISPOConfig)
    """Only used when ``policy_loss_type="cispo"``."""
    dppo: DPPOConfig = field(default_factory=DPPOConfig)
    """Only used when ``policy_loss_type="dppo"``."""
    max_seq_len: Optional[int] = None
    """Used for ``seq_mean_token_sum_norm`` loss reduction.
    Must be set explicitly for that reduction mode; otherwise can remain ``None``."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr advantage_estimator

advantage_estimator: str = 'grpo'

"grpo", "gae", "rloo", "reinforce++", or custom via AdvantageEstimatorRegistry.

attr kl_ctrl

kl_ctrl: KLCtrlConfig = field(default_factory=KLCtrlConfig)

Only used when use_kl_in_reward=True (not applied when use_kl_loss=True). Uses kl_loss_coef as the initial KL coefficient.

attr kl_estimator_type

kl_estimator_type: str = 'k3'

"k1", "k2", "k3", "abs". See http://joschu.net/blog/kl-approx.html.

attr use_kl_in_reward

use_kl_in_reward: bool = False

Apply KL penalty to rewards. Mutually exclusive with use_kl_loss.

attr use_kl_loss

use_kl_loss: bool = True

Apply KL loss in the policy model. Mutually exclusive with use_kl_in_reward.

attr kl_loss_coef

kl_loss_coef: float = 0.001

attr use_entropy_loss

use_entropy_loss: bool = False

attr entropy_loss_coef

entropy_loss_coef: float = 0.01

attr temperature

temperature: Optional[float] = None

Temperature for scaling logits in policy loss computation. If None, will be set to the temperature provided by generator.sampling_params.temperature during config validation.

NOTE: When using HTTP endpoints directly, make sure to set this value to the temperature used during generation

attr advantage_batch_normalize

advantage_batch_normalize: bool = False

attr value_head_prefix

value_head_prefix: str = 'value_head'

attr policy_loss_type

policy_loss_type: str = 'regular'

"regular", "dual_clip", "gspo", "clip_cov", "kl_cov", cispo, sapo, "rollout_is", "dppo", or custom via PolicyLossRegistry.

attr loss_reduction

loss_reduction: str = 'token_mean'

"token_mean", "sequence_mean", "prompt_mean", or "seq_mean_token_sum_norm". max_seq_len must be set explicitly for "seq_mean_token_sum_norm".

attr grpo_norm_by_std

grpo_norm_by_std: bool = True

attr zero_variance_filter

zero_variance_filter: bool = False

Loss-mask prompts with zero-variance rewards. Only applicable when rewards are response-level.

attr zero_variance_filter_tol

zero_variance_filter_tol: float = 1e-06

Two rewards within this absolute tolerance count as equal when detecting zero-variance groups. Only used when zero_variance_filter=True. Defaults to 1e-6 so float (LLM-judge) rewards that are effectively identical are still treated as zero-variance; this is a no-op for integer rewards (e.g. 0/1) where the spread is either 0 or >= 1. Set to 0.0 for exact equality.

attr lambd

lambd: float = 1.0

attr gamma

gamma: float = 1.0

attr eps_clip_low

eps_clip_low: float = 0.2

attr eps_clip_high

eps_clip_high: float = 0.2

attr clip_ratio_c

clip_ratio_c: float = 3.0

Dual-clip parameter.

attr tis_imp_ratio_cap

tis_imp_ratio_cap: float = -1.0

Deprecated: use off_policy_correction.tis_ratio_type="token" and token_tis_ratio_clip_high instead.

attr use_tis

use_tis: bool = False

Deprecated: use off_policy_correction instead.

attr off_policy_correction

off_policy_correction: OffPolicyCorrectionConfig = field(default_factory=OffPolicyCorrectionConfig)

attr sapo

sapo: SAPOConfig = field(default_factory=SAPOConfig)

attr value_clip

value_clip: float = 0.2

attr dynamic_sampling

dynamic_sampling: DynamicSamplingConfig = field(default_factory=DynamicSamplingConfig)

attr clip_cov

clip_cov: ClipCovConfig = field(default_factory=ClipCovConfig)

Only used when policy_loss_type="clip_cov".

attr kl_cov

kl_cov: KLCovConfig = field(default_factory=KLCovConfig)

Only used when policy_loss_type="kl_cov".

attr cispo

cispo: CISPOConfig = field(default_factory=CISPOConfig)

Only used when policy_loss_type="cispo".

attr dppo

dppo: DPPOConfig = field(default_factory=DPPOConfig)

Only used when policy_loss_type="dppo".

attr max_seq_len

max_seq_len: Optional[int] = None

Used for seq_mean_token_sum_norm loss reduction. Must be set explicitly for that reduction mode; otherwise can remain None.

class KLCtrlConfig

KLCtrlConfig(type: str = 'fixed', kl_target: float = 0.1, horizon: int = 10000) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
typestr"fixed" or "adaptive".
kl_targetfloatTarget KL divergence for the adaptive KL controller.
horizonintControls the update rate of the adaptive KL controller.
Source code in skyrl/train/config/config.py:505-513
@dataclass
class KLCtrlConfig(BaseConfig):

    type: str = "fixed"
    """``"fixed"`` or ``"adaptive"``."""
    kl_target: float = 0.1
    """Target KL divergence for the adaptive KL controller."""
    horizon: int = 10000
    """Controls the update rate of the adaptive KL controller."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr type

type: str = 'fixed'

"fixed" or "adaptive".

attr kl_target

kl_target: float = 0.1

Target KL divergence for the adaptive KL controller.

attr horizon

horizon: int = 10000

Controls the update rate of the adaptive KL controller.

Algorithm Extensions

class SAPOConfig

SAPOConfig(tau_pos: float = 1.0, tau_neg: float = 1.05) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
tau_posfloat
tau_negfloat
Source code in skyrl/train/config/config.py:516-519
@dataclass
class SAPOConfig(BaseConfig):
    tau_pos: float = 1.0
    tau_neg: float = 1.05

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr tau_pos

tau_pos: float = 1.0

attr tau_neg

tau_neg: float = 1.05

class DynamicSamplingConfig

DynamicSamplingConfig(type: Optional[str] = None, max_sample_batches: int = 30, min_replace_ratio: float = 0.3) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
typeOptional[str]"filter", "replace", or None.
max_sample_batchesintSample at most this many batches before stopping. -1 to sample forever.
min_replace_ratiofloatMinimum proportion of good samples to replace bad samples. Only used with "replace" strategy.
Source code in skyrl/train/config/config.py:522-529
@dataclass
class DynamicSamplingConfig(BaseConfig):
    type: Optional[str] = None
    """``"filter"``, ``"replace"``, or ``None``."""
    max_sample_batches: int = 30
    """Sample at most this many batches before stopping. ``-1`` to sample forever."""
    min_replace_ratio: float = 0.3
    """Minimum proportion of good samples to replace bad samples. Only used with ``"replace"`` strategy."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr type

type: Optional[str] = None

"filter", "replace", or None.

attr max_sample_batches

max_sample_batches: int = 30

Sample at most this many batches before stopping. -1 to sample forever.

attr min_replace_ratio

min_replace_ratio: float = 0.3

Minimum proportion of good samples to replace bad samples. Only used with "replace" strategy.

class ClipCovConfig

ClipCovConfig(clip_ratio: float = 0.0002, clip_cov_lb: float = 1.0, clip_cov_ub: float = 5.0) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
clip_ratiofloatFraction of tokens to clip based on covariance.
clip_cov_lbfloat
clip_cov_ubfloat
Source code in skyrl/train/config/config.py:532-538
@dataclass
class ClipCovConfig(BaseConfig):

    clip_ratio: float = 0.0002
    """Fraction of tokens to clip based on covariance."""
    clip_cov_lb: float = 1.0
    clip_cov_ub: float = 5.0

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr clip_ratio

clip_ratio: float = 0.0002

Fraction of tokens to clip based on covariance.

attr clip_cov_lb

clip_cov_lb: float = 1.0

attr clip_cov_ub

clip_cov_ub: float = 5.0

class KLCovConfig

KLCovConfig(kl_cov_frac: float = 0.2, ppo_kl_coef: float = 1.0) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
kl_cov_fracfloatFraction of tokens to apply KL regularization to.
ppo_kl_coeffloat
Source code in skyrl/train/config/config.py:541-546
@dataclass
class KLCovConfig(BaseConfig):

    kl_cov_frac: float = 0.2
    """Fraction of tokens to apply KL regularization to."""
    ppo_kl_coef: float = 1.0

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr kl_cov_frac

kl_cov_frac: float = 0.2

Fraction of tokens to apply KL regularization to.

attr ppo_kl_coef

ppo_kl_coef: float = 1.0

class CISPOConfig

CISPOConfig(cispo_eps_clip_low: float = 1.0, cispo_eps_clip_high: float = 4.0) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
cispo_eps_clip_lowfloatOffset for lower bound of importance sampling ratio clipping (as opposed to PPO token update clipping).
cispo_eps_clip_highfloatOffset for upper bound of importance sampling ratio clipping (as opposed to PPO token update clipping).
Source code in skyrl/train/config/config.py:549-561
@dataclass
class CISPOConfig(BaseConfig):

    cispo_eps_clip_low: float = 1.0
    """Offset for lower bound of importance sampling ratio clipping (as opposed to PPO token update clipping).
    
    The lower bound used is ``1-cispo_eps_clip_low``. The default lower bound is 0 following the ScaleRL recipe: https://arxiv.org/abs/2510.13786
    """
    cispo_eps_clip_high: float = 4.0
    """Offset for upper bound of importance sampling ratio clipping (as opposed to PPO token update clipping).
    
    The upper bound used is ``1+cispo_eps_clip_high``. The default upper bound is 5 following the ScaleRL recipe: https://arxiv.org/abs/2510.13786
    """

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr cispo_eps_clip_low

cispo_eps_clip_low: float = 1.0

Offset for lower bound of importance sampling ratio clipping (as opposed to PPO token update clipping).

The lower bound used is 1-cispo_eps_clip_low. The default lower bound is 0 following the ScaleRL recipe: https://arxiv.org/abs/2510.13786

attr cispo_eps_clip_high

cispo_eps_clip_high: float = 4.0

Offset for upper bound of importance sampling ratio clipping (as opposed to PPO token update clipping).

The upper bound used is 1+cispo_eps_clip_high. The default upper bound is 5 following the ScaleRL recipe: https://arxiv.org/abs/2510.13786

class OffPolicyCorrectionConfig

OffPolicyCorrectionConfig(tis_ratio_type: Optional[str] = None, token_tis_ratio_clip_high: float = 2.0, sequence_tis_ratio_clip_high: float = 5.0, sequence_mask_metric: Optional[str] = None, geo_mask_high: float = 1.01, geo_mask_low: float = 0.99, product_mask_high: float = 2.0, product_mask_low: float = 0.5, outlier_token_is_threshold_low: Optional[float] = None, outlier_token_is_threshold_high: Optional[float] = None, token_mask_is_threshold_low: Optional[float] = None, token_mask_is_threshold_high: Optional[float] = None) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
tis_ratio_typeOptional[str]Importance sampling ratio type for PPO loss correction: None, "token", or "sequence".
token_tis_ratio_clip_highfloatUsed when tis_ratio_type="token". Recommended range: 1.5--5.0.
sequence_tis_ratio_clip_highfloatUsed when tis_ratio_type="sequence". Recommended range: 2.0--10.0.
sequence_mask_metricOptional[str]Method for masking sequences with cumulative IS ratios outside cap: None, "product", or "geometric".
geo_mask_highfloatUsed when sequence_mask_metric="geometric". Recommended ~0.99--1.01; MoE models may need a wider range.
geo_mask_lowfloatUsed when sequence_mask_metric="geometric".
product_mask_highfloatUsed when sequence_mask_metric="product". Recommended ~0.5--2.0.
product_mask_lowfloatUsed when sequence_mask_metric="product".
outlier_token_is_threshold_lowOptional[float]Set to mask sequences with any token IS ratio below this threshold. Suggested: 1e-4. None to disable.
outlier_token_is_threshold_highOptional[float]Set to mask sequences with any token IS ratio above this threshold. Suggested: 100. None to disable.
token_mask_is_threshold_lowOptional[float]Set to mask per-token when IS ratio < token_mask_is_threshold_low. None to disable.
token_mask_is_threshold_highOptional[float]Set to mask per-token when IS ratio > token_mask_is_threshold_high. None to disable.
Source code in skyrl/train/config/config.py:581-607
@dataclass
class OffPolicyCorrectionConfig(BaseConfig):
    tis_ratio_type: Optional[str] = None
    """Importance sampling ratio type for PPO loss correction: ``None``, ``"token"``, or ``"sequence"``.
    The ratio is ``exp(logprobs_policy_old - logprobs_rollout_policy)``."""
    token_tis_ratio_clip_high: float = 2.0
    """Used when ``tis_ratio_type="token"``. Recommended range: 1.5--5.0."""
    sequence_tis_ratio_clip_high: float = 5.0
    """Used when ``tis_ratio_type="sequence"``. Recommended range: 2.0--10.0."""
    sequence_mask_metric: Optional[str] = None
    """Method for masking sequences with cumulative IS ratios outside cap: ``None``, ``"product"``, or ``"geometric"``."""
    geo_mask_high: float = 1.01
    """Used when ``sequence_mask_metric="geometric"``. Recommended ~0.99--1.01; MoE models may need a wider range."""
    geo_mask_low: float = 0.99
    """Used when ``sequence_mask_metric="geometric"``."""
    product_mask_high: float = 2.0
    """Used when ``sequence_mask_metric="product"``. Recommended ~0.5--2.0."""
    product_mask_low: float = 0.5
    """Used when ``sequence_mask_metric="product"``."""
    outlier_token_is_threshold_low: Optional[float] = None
    """Set to mask sequences with any token IS ratio below this threshold. Suggested: 1e-4. ``None`` to disable."""
    outlier_token_is_threshold_high: Optional[float] = None
    """Set to mask sequences with any token IS ratio above this threshold. Suggested: 100. ``None`` to disable."""
    token_mask_is_threshold_low: Optional[float] = None
    """Set to mask per-token when IS ratio < `token_mask_is_threshold_low`. ``None`` to disable."""
    token_mask_is_threshold_high: Optional[float] = None
    """Set to mask per-token when IS ratio > `token_mask_is_threshold_high`. ``None`` to disable."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr tis_ratio_type

tis_ratio_type: Optional[str] = None

Importance sampling ratio type for PPO loss correction: None, "token", or "sequence". The ratio is exp(logprobs_policy_old - logprobs_rollout_policy).

attr token_tis_ratio_clip_high

token_tis_ratio_clip_high: float = 2.0

Used when tis_ratio_type="token". Recommended range: 1.5--5.0.

attr sequence_tis_ratio_clip_high

sequence_tis_ratio_clip_high: float = 5.0

Used when tis_ratio_type="sequence". Recommended range: 2.0--10.0.

attr sequence_mask_metric

sequence_mask_metric: Optional[str] = None

Method for masking sequences with cumulative IS ratios outside cap: None, "product", or "geometric".

attr geo_mask_high

geo_mask_high: float = 1.01

Used when sequence_mask_metric="geometric". Recommended ~0.99--1.01; MoE models may need a wider range.

attr geo_mask_low

geo_mask_low: float = 0.99

Used when sequence_mask_metric="geometric".

attr product_mask_high

product_mask_high: float = 2.0

Used when sequence_mask_metric="product". Recommended ~0.5--2.0.

attr product_mask_low

product_mask_low: float = 0.5

Used when sequence_mask_metric="product".

attr outlier_token_is_threshold_low

outlier_token_is_threshold_low: Optional[float] = None

Set to mask sequences with any token IS ratio below this threshold. Suggested: 1e-4. None to disable.

attr outlier_token_is_threshold_high

outlier_token_is_threshold_high: Optional[float] = None

Set to mask sequences with any token IS ratio above this threshold. Suggested: 100. None to disable.

attr token_mask_is_threshold_low

token_mask_is_threshold_low: Optional[float] = None

Set to mask per-token when IS ratio < token_mask_is_threshold_low. None to disable.

attr token_mask_is_threshold_high

token_mask_is_threshold_high: Optional[float] = None

Set to mask per-token when IS ratio > token_mask_is_threshold_high. None to disable.

class FullyAsyncConfig

FullyAsyncConfig(enabled: bool = False, max_staleness_steps: int = 4, num_parallel_generation_workers: int = 768, sample_full_batch: bool = False, clear_kv_cache_on_weight_sync: bool = False, simulate_training: bool = False, simulate_training_step_seconds: float = 30.0, simulate_weight_sync_seconds: float = 0.0) -> None

Bases: BaseConfig

Knobs for fully async training. See https://docs.skyrl.ai/docs/tutorials/fully_async#step-2-config-knobs-to-tune-for-fully-async-training.

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
enabledboolIndicates whether fully async training is enabled
max_staleness_stepsintMaximum off-policy steps allowed. If a trajectory group is scheduled at step i and trained at step j,
num_parallel_generation_workersintNumber of generation workers to spawn. Should be >= policy_mini_batch_size and
sample_full_batchboolRequires zero_variance_filter=True. Drop zero-variance groups and keep pulling until the
clear_kv_cache_on_weight_syncboolWhether or not to clear the KV cache on weight sync. Defaults to False.
simulate_trainingboolIf True, run fully-async generation with a SIMULATED trainer (see
simulate_training_step_secondsfloatWall-clock seconds the simulated dummy training step sleeps (stands in for fwd/bwd/optim).
simulate_weight_sync_secondsfloatWall-clock seconds generation stays paused to stand in for the (skipped) weight broadcast.
Source code in skyrl/train/config/config.py:678-718
@dataclass
class FullyAsyncConfig(BaseConfig):
    """Knobs for fully async training.
    See https://docs.skyrl.ai/docs/tutorials/fully_async#step-2-config-knobs-to-tune-for-fully-async-training."""

    enabled: bool = False
    """Indicates whether fully async training is enabled"""
    max_staleness_steps: int = 4
    """Maximum off-policy steps allowed. If a trajectory group is scheduled at step *i* and trained at step *j*,
    then ``j - i <= max_staleness_steps``. Larger values increase throughput but also off-policy-ness."""
    num_parallel_generation_workers: int = 768
    """Number of generation workers to spawn. Should be >= ``policy_mini_batch_size`` and
    <= ``policy_mini_batch_size * (max_staleness_steps + 1)``."""
    sample_full_batch: bool = False
    """Requires ``zero_variance_filter=True``. Drop zero-variance groups and keep pulling until the
    mini-batch is full of non-zero-variance groups (async-native DAPO ``dynamic_sampling="filter"``).
    Dropped groups are marked consumed (not regenerated on resume), so the per-epoch step count becomes
    an upper bound: if the epoch's prompts run out mid mini-batch, the partial batch is discarded and
    the epoch ends."""
    clear_kv_cache_on_weight_sync: bool = False
    """Whether or not to clear the KV cache on weight sync. Defaults to False.
    If False, we reuse KV cache from stale policies during generation
    (avoids recomputation at the cost of using slightly stale KV cache).
    """

    # --- Trainer simulation (no real trainer components) ---
    simulate_training: bool = False
    """If True, run fully-async generation with a SIMULATED trainer (see
    ``FullyAsyncTrainerSim``): no policy/critic/ref models are instantiated and no weight
    broadcast happens. Each step consumes a mini-batch from the generation buffer, sleeps for
    ``simulate_training_step_seconds``, then issues pause/resume generation (as a real weight
    sync would) but skips ``broadcast_to_inference_engines``. Used to benchmark the
    generation/inference side (e.g. router load-balancing policies) on large models without
    paying for trainer GPUs — typically pointed at already-served endpoints via
    ``external_proxy_url`` / ``external_server_urls``. The generation-side dynamics (staleness
    control, rate limiting, pause/resume) remain faithful."""
    simulate_training_step_seconds: float = 30.0
    """Wall-clock seconds the simulated dummy training step sleeps (stands in for fwd/bwd/optim)."""
    simulate_weight_sync_seconds: float = 0.0
    """Wall-clock seconds generation stays paused to stand in for the (skipped) weight broadcast.
    0.0 = pause then immediately resume."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr enabled

enabled: bool = False

Indicates whether fully async training is enabled

attr max_staleness_steps

max_staleness_steps: int = 4

Maximum off-policy steps allowed. If a trajectory group is scheduled at step i and trained at step j, then j - i <= max_staleness_steps. Larger values increase throughput but also off-policy-ness.

attr num_parallel_generation_workers

num_parallel_generation_workers: int = 768

Number of generation workers to spawn. Should be >= policy_mini_batch_size and <= policy_mini_batch_size * (max_staleness_steps + 1).

attr sample_full_batch

sample_full_batch: bool = False

Requires zero_variance_filter=True. Drop zero-variance groups and keep pulling until the mini-batch is full of non-zero-variance groups (async-native DAPO dynamic_sampling="filter"). Dropped groups are marked consumed (not regenerated on resume), so the per-epoch step count becomes an upper bound: if the epoch's prompts run out mid mini-batch, the partial batch is discarded and the epoch ends.

attr clear_kv_cache_on_weight_sync

clear_kv_cache_on_weight_sync: bool = False

Whether or not to clear the KV cache on weight sync. Defaults to False. If False, we reuse KV cache from stale policies during generation (avoids recomputation at the cost of using slightly stale KV cache).

attr simulate_training

simulate_training: bool = False

If True, run fully-async generation with a SIMULATED trainer (see FullyAsyncTrainerSim): no policy/critic/ref models are instantiated and no weight broadcast happens. Each step consumes a mini-batch from the generation buffer, sleeps for simulate_training_step_seconds, then issues pause/resume generation (as a real weight sync would) but skips broadcast_to_inference_engines. Used to benchmark the generation/inference side (e.g. router load-balancing policies) on large models without paying for trainer GPUs — typically pointed at already-served endpoints via external_proxy_url / external_server_urls. The generation-side dynamics (staleness control, rate limiting, pause/resume) remain faithful.

attr simulate_training_step_seconds

simulate_training_step_seconds: float = 30.0

Wall-clock seconds the simulated dummy training step sleeps (stands in for fwd/bwd/optim).

attr simulate_weight_sync_seconds

simulate_weight_sync_seconds: float = 0.0

Wall-clock seconds generation stays paused to stand in for the (skipped) weight broadcast. 0.0 = pause then immediately resume.

Inference & Generation

class SamplingParams

SamplingParams(max_generate_length: int = 1024, repetition_penalty: float = 1.0, temperature: float = 1.0, top_p: float = 1.0, min_p: float = 0.0, top_k: int = -1, logprobs: Optional[int] = 1, stop: Optional[List[str]] = None, additional_kwargs: Optional[Dict[str, Any]] = None) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
max_generate_lengthint
repetition_penaltyfloat
temperaturefloat
top_pfloat
min_pfloat
top_kint
logprobsOptional[int]
stopOptional[List[str]]
additional_kwargsOptional[Dict[str, Any]]
Source code in skyrl/train/config/config.py:726-736
@dataclass
class SamplingParams(BaseConfig):
    max_generate_length: int = 1024
    repetition_penalty: float = 1.0
    temperature: float = 1.0
    top_p: float = 1.0
    min_p: float = 0.0
    top_k: int = -1
    logprobs: Optional[int] = 1
    stop: Optional[List[str]] = None
    additional_kwargs: Optional[Dict[str, Any]] = None

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr max_generate_length

max_generate_length: int = 1024

attr repetition_penalty

repetition_penalty: float = 1.0

attr temperature

temperature: float = 1.0

attr top_p

top_p: float = 1.0

attr min_p

min_p: float = 0.0

attr top_k

top_k: int = -1

attr logprobs

logprobs: Optional[int] = 1

attr stop

stop: Optional[List[str]] = None

attr additional_kwargs

additional_kwargs: Optional[Dict[str, Any]] = None

class ChatTemplateConfig

ChatTemplateConfig(source: str = 'name', name_or_path: Optional[str] = None) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
sourcestr
name_or_pathOptional[str]
Source code in skyrl/train/config/config.py:739-742
@dataclass
class ChatTemplateConfig(BaseConfig):
    source: str = "name"
    name_or_path: Optional[str] = None

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr source

source: str = 'name'

attr name_or_path

name_or_path: Optional[str] = None

class InferenceEngineConfig

InferenceEngineConfig(model_dtype: str = 'bfloat16', run_engines_locally: bool = True, num_engines: int = 1, backend: str = 'vllm', weight_sync_backend: str = 'nccl', weight_transfer_threshold_cuda_ipc_GB: float = 1.0, tensor_parallel_size: int = 1, pipeline_parallel_size: int = 1, expert_parallel_size: int = 1, data_parallel_size: int = 1, vllm_v1_disable_multiproc: bool = True, enable_prefix_caching: bool = True, enable_chunked_prefill: bool = True, enable_return_routed_experts: bool = False, max_num_batched_tokens: int = 8192, enforce_eager: bool = False, fully_sharded_loras: bool = False, enable_ray_prometheus_stats: bool = True, gpu_memory_utilization: float = 0.8, offload_kv_for_weight_sync: bool = False, use_expandable_segments: bool = False, max_num_seqs: int = 1024, served_model_name: Optional[str] = None, distributed_executor_backend: str = 'ray', language_model_only: bool = False, engine_init_kwargs: Dict[str, Any] = dict(), speculative_config: Optional[Dict[str, Any]] = None, external_proxy_url: Optional[str] = None, external_server_urls: Optional[List[str]] = None, enable_pd: bool = False, num_prefill: int = 0, router_init_kwargs: Dict[str, Any] = dict()) -> None

Bases: BaseConfig

Configuration for inference engine instantiation and management.

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
model_dtypestrShould match the dtype used by the inference engine.
run_engines_locallybool
num_enginesint
backendstr"vllm".
weight_sync_backendstr
weight_transfer_threshold_cuda_ipc_GBfloatWhen using cuda_ipc, send weights in batches of this size (GB).
tensor_parallel_sizeint
pipeline_parallel_sizeint
expert_parallel_sizeint
data_parallel_sizeint
vllm_v1_disable_multiprocboolSets VLLM_ENABLE_V1_MULTIPROCESSING=0 for reproducibility.
enable_prefix_cachingbool
enable_chunked_prefillbool
enable_return_routed_expertsbool
max_num_batched_tokensint
enforce_eagerboolDisable CUDA graphs for stability. Set to False for higher performance,
fully_sharded_lorasbool
enable_ray_prometheus_statsboolEnable Ray Prometheus stats logger for inference engine metrics (vLLM v1 only).
gpu_memory_utilizationfloat
offload_kv_for_weight_syncboolNon-colocated only. Sleep the engine (freeing the KV cache from GPU) during weight
use_expandable_segmentsboolSet PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True on the inference-engine
max_num_seqsint
served_model_nameOptional[str]Model name for HTTP endpoint validation. If set, must be used in the model field of
distributed_executor_backendstrDistributed executor backend for vLLM. Set to "ray" to use the Ray backend
language_model_onlyboolWhen True, pass language_model_only=True to the vLLM engine so that
engine_init_kwargsDict[str, Any]Pass-through kwargs for the vLLM engine. Names must match the engine's args.
speculative_configOptional[Dict[str, Any]]Speculative-decoding config passed through to vLLM for MTP drafter decoding.
external_proxy_urlOptional[str]Data-plane URL (load-balanced router) for the new inference layer.
external_server_urlsOptional[List[str]]Control-plane URLs (direct backend access) for the new inference layer.
enable_pdboolEnable prefill-decode disaggregation. Requires num_prefill > 0 and num_engines >= 2.
num_prefillintNumber of prefill engines when enable_pd=True. Decode engines = num_engines - num_prefill
router_init_kwargsDict[str, Any]Pass-through kwargs applied to RouterArgs for the vllm-router.
Source code in skyrl/train/config/config.py:750-823
@dataclass
class InferenceEngineConfig(BaseConfig):
    """Configuration for inference engine instantiation and management."""

    model_dtype: str = "bfloat16"
    """Should match the dtype used by the inference engine."""
    run_engines_locally: bool = True
    num_engines: int = 1
    backend: str = "vllm"
    """``"vllm"``."""
    weight_sync_backend: str = "nccl"
    weight_transfer_threshold_cuda_ipc_GB: float = 1.0
    """When using ``cuda_ipc``, send weights in batches of this size (GB)."""
    tensor_parallel_size: int = 1
    pipeline_parallel_size: int = 1
    expert_parallel_size: int = 1
    data_parallel_size: int = 1
    vllm_v1_disable_multiproc: bool = True
    """Sets ``VLLM_ENABLE_V1_MULTIPROCESSING=0`` for reproducibility."""
    enable_prefix_caching: bool = True
    enable_chunked_prefill: bool = True
    enable_return_routed_experts: bool = False
    max_num_batched_tokens: int = 8192
    enforce_eager: bool = False
    """Disable CUDA graphs for stability. Set to ``False`` for higher performance,
    but this may affect convergence for long-running or long-context training jobs."""
    fully_sharded_loras: bool = False
    enable_ray_prometheus_stats: bool = True
    """Enable Ray Prometheus stats logger for inference engine metrics (vLLM v1 only)."""
    gpu_memory_utilization: float = 0.8
    offload_kv_for_weight_sync: bool = False
    """Non-colocated only. Sleep the engine (freeing the KV cache from GPU) during weight
    sync so ``gpu_memory_utilization`` can be pushed higher without OOMing on the weight-
    transfer buffers. On the fully-async trainer, in-flight requests are frozen (KEEP
    pause) and, unless ``trainer.fully_async.clear_kv_cache_on_weight_sync`` is set, their
    KV cache is offloaded to CPU and restored so they resume with no abort or prefill
    recompute (at the cost of a GPU<->CPU copy of the KV pool each sync). Requires
    non-colocated and non-LoRA weight sync."""
    use_expandable_segments: bool = False
    """Set ``PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True`` on the inference-engine
    processes to reduce fragmentation. Independent of the trainer-side
    ``TrainerConfig.use_expandable_segments``. Default ``False``: it is a safe opt-in
    on vLLM >= 0.20.1, where the CuMemAllocator auto-disables expandable segments around
    its sleep/wake memory pool. On older vLLM, sleep mode + expandable segments is a hard
    error, so leave this off."""
    max_num_seqs: int = 1024
    served_model_name: Optional[str] = None
    """Model name for HTTP endpoint validation. If set, must be used in the ``model`` field of
    ``/chat/completions`` requests instead of the model path. If ``None``, the model path is used."""
    distributed_executor_backend: str = "ray"
    """Distributed executor backend for vLLM. Set to ``"ray"`` to use the Ray backend
    or ``"mp"`` to use the multiprocessing backend (single-node serving only). Per-engine 
    placement groups are created when ``"mp"`` is used."""
    language_model_only: bool = False
    """When True, pass ``language_model_only=True`` to the vLLM engine so that
    multimodal models (e.g. Qwen3.5) skip vision encoder initialization."""
    engine_init_kwargs: Dict[str, Any] = field(default_factory=dict)
    """Pass-through kwargs for the vLLM engine. Names must match the engine's args."""
    speculative_config: Optional[Dict[str, Any]] = None
    """Speculative-decoding config passed through to vLLM for MTP drafter decoding. 
    (needs ``policy.megatron_config.mtp_num_layers`` > 0 to train mtp). ``None`` disables it."""
    external_proxy_url: Optional[str] = None
    """Data-plane URL (load-balanced router) for the new inference layer."""
    external_server_urls: Optional[List[str]] = None
    """Control-plane URLs (direct backend access) for the new inference layer."""
    enable_pd: bool = False
    """Enable prefill-decode disaggregation. Requires ``num_prefill > 0`` and ``num_engines >= 2``."""
    num_prefill: int = 0
    """Number of prefill engines when ``enable_pd=True``. Decode engines = ``num_engines - num_prefill``

    NOTE: SkyRL counts data parallel workers separately, so the total number of prefill workers will be ``data_parallel_size * num_prefill``."""
    router_init_kwargs: Dict[str, Any] = field(default_factory=dict)
    """Pass-through kwargs applied to ``RouterArgs`` for the vllm-router.
    Names must match ``vllm_router.RouterArgs`` fields (e.g. ``policy``, ``request_timeout_secs``)."""

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr model_dtype

model_dtype: str = 'bfloat16'

Should match the dtype used by the inference engine.

attr run_engines_locally

run_engines_locally: bool = True

attr num_engines

num_engines: int = 1

attr backend

backend: str = 'vllm'

"vllm".

attr weight_sync_backend

weight_sync_backend: str = 'nccl'

attr weight_transfer_threshold_cuda_ipc_GB

weight_transfer_threshold_cuda_ipc_GB: float = 1.0

When using cuda_ipc, send weights in batches of this size (GB).

attr tensor_parallel_size

tensor_parallel_size: int = 1

attr pipeline_parallel_size

pipeline_parallel_size: int = 1

attr expert_parallel_size

expert_parallel_size: int = 1

attr data_parallel_size

data_parallel_size: int = 1

attr vllm_v1_disable_multiproc

vllm_v1_disable_multiproc: bool = True

Sets VLLM_ENABLE_V1_MULTIPROCESSING=0 for reproducibility.

attr enable_prefix_caching

enable_prefix_caching: bool = True

attr enable_chunked_prefill

enable_chunked_prefill: bool = True

attr enable_return_routed_experts

enable_return_routed_experts: bool = False

attr max_num_batched_tokens

max_num_batched_tokens: int = 8192

attr enforce_eager

enforce_eager: bool = False

Disable CUDA graphs for stability. Set to False for higher performance, but this may affect convergence for long-running or long-context training jobs.

attr fully_sharded_loras

fully_sharded_loras: bool = False

attr enable_ray_prometheus_stats

enable_ray_prometheus_stats: bool = True

Enable Ray Prometheus stats logger for inference engine metrics (vLLM v1 only).

attr gpu_memory_utilization

gpu_memory_utilization: float = 0.8

attr offload_kv_for_weight_sync

offload_kv_for_weight_sync: bool = False

Non-colocated only. Sleep the engine (freeing the KV cache from GPU) during weight sync so gpu_memory_utilization can be pushed higher without OOMing on the weight- transfer buffers. On the fully-async trainer, in-flight requests are frozen (KEEP pause) and, unless trainer.fully_async.clear_kv_cache_on_weight_sync is set, their KV cache is offloaded to CPU and restored so they resume with no abort or prefill recompute (at the cost of a GPU<->CPU copy of the KV pool each sync). Requires non-colocated and non-LoRA weight sync.

attr use_expandable_segments

use_expandable_segments: bool = False

Set PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True on the inference-engine processes to reduce fragmentation. Independent of the trainer-side TrainerConfig.use_expandable_segments. Default False: it is a safe opt-in on vLLM >= 0.20.1, where the CuMemAllocator auto-disables expandable segments around its sleep/wake memory pool. On older vLLM, sleep mode + expandable segments is a hard error, so leave this off.

attr max_num_seqs

max_num_seqs: int = 1024

attr served_model_name

served_model_name: Optional[str] = None

Model name for HTTP endpoint validation. If set, must be used in the model field of /chat/completions requests instead of the model path. If None, the model path is used.

attr distributed_executor_backend

distributed_executor_backend: str = 'ray'

Distributed executor backend for vLLM. Set to "ray" to use the Ray backend or "mp" to use the multiprocessing backend (single-node serving only). Per-engine placement groups are created when "mp" is used.

attr language_model_only

language_model_only: bool = False

When True, pass language_model_only=True to the vLLM engine so that multimodal models (e.g. Qwen3.5) skip vision encoder initialization.

attr engine_init_kwargs

engine_init_kwargs: Dict[str, Any] = field(default_factory=dict)

Pass-through kwargs for the vLLM engine. Names must match the engine's args.

attr speculative_config

speculative_config: Optional[Dict[str, Any]] = None

Speculative-decoding config passed through to vLLM for MTP drafter decoding. (needs policy.megatron_config.mtp_num_layers > 0 to train mtp). None disables it.

attr external_proxy_url

external_proxy_url: Optional[str] = None

Data-plane URL (load-balanced router) for the new inference layer.

attr external_server_urls

external_server_urls: Optional[List[str]] = None

Control-plane URLs (direct backend access) for the new inference layer.

attr enable_pd

enable_pd: bool = False

Enable prefill-decode disaggregation. Requires num_prefill > 0 and num_engines >= 2.

attr num_prefill

num_prefill: int = 0

Number of prefill engines when enable_pd=True. Decode engines = num_engines - num_prefill

NOTE: SkyRL counts data parallel workers separately, so the total number of prefill workers will be data_parallel_size * num_prefill.

attr router_init_kwargs

router_init_kwargs: Dict[str, Any] = field(default_factory=dict)

Pass-through kwargs applied to RouterArgs for the vllm-router. Names must match vllm_router.RouterArgs fields (e.g. policy, request_timeout_secs).

class GeneratorConfig

GeneratorConfig(inference_engine: InferenceEngineConfig = InferenceEngineConfig(), n_samples_per_prompt: int = 5, batched: bool = False, max_turns: int = 1, max_input_length: Optional[int] = None, chat_template: ChatTemplateConfig = ChatTemplateConfig(), chat_template_kwargs: Dict[str, Any] = dict(), sampling_params: SamplingParams = SamplingParams(), use_conversation_multi_turn: bool = True, append_eos_token_after_stop_str_in_multi_turn: bool = True, eval_sampling_params: Optional[SamplingParams] = None, eval_n_samples_per_prompt: int = 1, zero_reward_on_non_stop: bool = False, use_cache_salt: bool = True, apply_overlong_filtering: bool = False, step_wise_trajectories: bool = False, vision_language_generator: bool = False, merge_stepwise_output: bool = False) -> None

Bases: BaseConfig

Configuration for generation behavior.

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
inference_engineInferenceEngineConfig
n_samples_per_promptint
batchedbool
max_turnsint
max_input_lengthOptional[int]Max generator input length for multi-turn conversations. For single-turn, set equal to max_prompt_length.
chat_templateChatTemplateConfig
chat_template_kwargsDict[str, Any]Kwargs passed to tokenizer.apply_chat_template.
sampling_paramsSamplingParams
use_conversation_multi_turnboolIf True, each multi-turn model response and env observation is stored in a separate
append_eos_token_after_stop_str_in_multi_turnboolWhen use_conversation_multi_turn=True and sampling_params.stop is set, append
eval_sampling_paramsOptional[SamplingParams]Separate sampling params for evaluation. If None, then it defaults to SamplingParams(temperature=0.0, max_generate_length=generator.sampling_params.max_generate_length).
eval_n_samples_per_promptint
zero_reward_on_non_stopboolSet reward to 0 when stop_reason is not "stop" (i.e., generation was truncated or aborted).
use_cache_saltboolSalt vLLM's prefix cache with the policy version so cache blocks are only shared across trajectories that started
apply_overlong_filteringboolApply DAPO Overlong Filtering: mask out all tokens in the loss mask for trajectories that
step_wise_trajectoriesbool
vision_language_generatorboolIf True, use SkyRLVLMGymGenerator (multi-modal text+image rollouts)
merge_stepwise_outputboolWhen True (and step_wise_trajectories is True), apply prefix-aware merging
Source code in skyrl/train/config/config.py:831-876
@dataclass
class GeneratorConfig(BaseConfig):
    """Configuration for generation behavior."""

    inference_engine: InferenceEngineConfig = field(default_factory=InferenceEngineConfig)
    n_samples_per_prompt: int = 5
    batched: bool = False
    max_turns: int = 1
    max_input_length: Optional[int] = None
    """Max generator input length for multi-turn conversations. For single-turn, set equal to ``max_prompt_length``."""
    chat_template: ChatTemplateConfig = field(default_factory=ChatTemplateConfig)
    chat_template_kwargs: Dict[str, Any] = field(default_factory=dict)
    """Kwargs passed to ``tokenizer.apply_chat_template``."""
    sampling_params: SamplingParams = field(default_factory=SamplingParams)
    use_conversation_multi_turn: bool = True
    """If ``True``, each multi-turn model response and env observation is stored in a separate
    assistant/user message. If ``False``, they are appended to the original assistant response."""
    append_eos_token_after_stop_str_in_multi_turn: bool = True
    """When ``use_conversation_multi_turn=True`` and ``sampling_params.stop`` is set, append
    ``eos_token_id`` to generations that end with a matched stop string."""
    eval_sampling_params: Optional[SamplingParams] = None
    """Separate sampling params for evaluation. If ``None``, then it defaults to ``SamplingParams(temperature=0.0, max_generate_length=generator.sampling_params.max_generate_length)``."""
    eval_n_samples_per_prompt: int = 1
    zero_reward_on_non_stop: bool = False
    """Set reward to 0 when ``stop_reason`` is not ``"stop"`` (i.e., generation was truncated or aborted)."""
    use_cache_salt: bool = True
    """Salt vLLM's prefix cache with the policy version so cache blocks are only shared across trajectories that started
    with the same policy weight version. The salt is keyed on the engine's weight version, captured at the start of each
    ``generate`` call. Matters for fully-async RL; a no-op for synchronous training (which resets the
    cache each sync) and when prefix caching is off, so it is safe to leave on by default."""
    apply_overlong_filtering: bool = False
    """Apply DAPO Overlong Filtering: mask out all tokens in the loss mask for trajectories that
    exceed max length (truncated, no EOS token)."""
    step_wise_trajectories: bool = False
    vision_language_generator: bool = False
    """If True, use SkyRLVLMGymGenerator (multi-modal text+image rollouts)"""
    merge_stepwise_output: bool = False
    """When True (and step_wise_trajectories is True), apply prefix-aware merging
    to collapse multi-turn step-wise sequences into single sequences before training."""

    def __post_init__(self):

        if self.eval_sampling_params is None:
            self.eval_sampling_params = SamplingParams(
                temperature=0.0, max_generate_length=self.sampling_params.max_generate_length
            )

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr inference_engine

inference_engine: InferenceEngineConfig = field(default_factory=InferenceEngineConfig)

attr n_samples_per_prompt

n_samples_per_prompt: int = 5

attr batched

batched: bool = False

attr max_turns

max_turns: int = 1

attr max_input_length

max_input_length: Optional[int] = None

Max generator input length for multi-turn conversations. For single-turn, set equal to max_prompt_length.

attr chat_template

chat_template: ChatTemplateConfig = field(default_factory=ChatTemplateConfig)

attr chat_template_kwargs

chat_template_kwargs: Dict[str, Any] = field(default_factory=dict)

Kwargs passed to tokenizer.apply_chat_template.

attr sampling_params

sampling_params: SamplingParams = field(default_factory=SamplingParams)

attr use_conversation_multi_turn

use_conversation_multi_turn: bool = True

If True, each multi-turn model response and env observation is stored in a separate assistant/user message. If False, they are appended to the original assistant response.

attr append_eos_token_after_stop_str_in_multi_turn

append_eos_token_after_stop_str_in_multi_turn: bool = True

When use_conversation_multi_turn=True and sampling_params.stop is set, append eos_token_id to generations that end with a matched stop string.

attr eval_sampling_params

eval_sampling_params: Optional[SamplingParams] = None

Separate sampling params for evaluation. If None, then it defaults to SamplingParams(temperature=0.0, max_generate_length=generator.sampling_params.max_generate_length).

attr eval_n_samples_per_prompt

eval_n_samples_per_prompt: int = 1

attr zero_reward_on_non_stop

zero_reward_on_non_stop: bool = False

Set reward to 0 when stop_reason is not "stop" (i.e., generation was truncated or aborted).

attr use_cache_salt

use_cache_salt: bool = True

Salt vLLM's prefix cache with the policy version so cache blocks are only shared across trajectories that started with the same policy weight version. The salt is keyed on the engine's weight version, captured at the start of each generate call. Matters for fully-async RL; a no-op for synchronous training (which resets the cache each sync) and when prefix caching is off, so it is safe to leave on by default.

attr apply_overlong_filtering

apply_overlong_filtering: bool = False

Apply DAPO Overlong Filtering: mask out all tokens in the loss mask for trajectories that exceed max length (truncated, no EOS token).

attr step_wise_trajectories

step_wise_trajectories: bool = False

attr vision_language_generator

vision_language_generator: bool = False

If True, use SkyRLVLMGymGenerator (multi-modal text+image rollouts)

attr merge_stepwise_output

merge_stepwise_output: bool = False

When True (and step_wise_trajectories is True), apply prefix-aware merging to collapse multi-turn step-wise sequences into single sequences before training.

Environment

class EnvironmentConfig

EnvironmentConfig(env_class: str = 'gsm8k', skyrl_gym: SkyRLGymConfig = SkyRLGymConfig()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
env_classstr
skyrl_gymSkyRLGymConfig
Source code in skyrl/train/config/config.py:899-902
@dataclass
class EnvironmentConfig(BaseConfig):
    env_class: str = "gsm8k"
    skyrl_gym: SkyRLGymConfig = field(default_factory=SkyRLGymConfig)

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr env_class

env_class: str = 'gsm8k'

attr skyrl_gym

skyrl_gym: SkyRLGymConfig = field(default_factory=SkyRLGymConfig)

class SkyRLGymConfig

SkyRLGymConfig(max_env_workers: int = 32, text2sql: Text2SQLEnvConfig = Text2SQLEnvConfig(), llm_as_a_judge: GSM8kLLMJudgeEnvConfig = GSM8kLLMJudgeEnvConfig(), search: SearchEnvConfig = SearchEnvConfig()) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
max_env_workersint
text2sqlText2SQLEnvConfig
llm_as_a_judgeGSM8kLLMJudgeEnvConfig
searchSearchEnvConfig
Source code in skyrl/train/config/config.py:891-896
@dataclass
class SkyRLGymConfig(BaseConfig):
    max_env_workers: int = 32
    text2sql: Text2SQLEnvConfig = field(default_factory=Text2SQLEnvConfig)
    llm_as_a_judge: GSM8kLLMJudgeEnvConfig = field(default_factory=GSM8kLLMJudgeEnvConfig)
    search: SearchEnvConfig = field(default_factory=SearchEnvConfig)

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr max_env_workers

max_env_workers: int = 32

attr text2sql

text2sql: Text2SQLEnvConfig = field(default_factory=Text2SQLEnvConfig)

attr llm_as_a_judge

llm_as_a_judge: GSM8kLLMJudgeEnvConfig = field(default_factory=GSM8kLLMJudgeEnvConfig)
search: SearchEnvConfig = field(default_factory=SearchEnvConfig)

class GSM8kLLMJudgeEnvConfig

GSM8kLLMJudgeEnvConfig(model: str = 'gpt-4o-mini', base_url: Optional[str] = None) -> None

Bases: BaseConfig

Functions:

NameDescription
from_dict_configConstruct a typed BaseConfig from a Hydra DictConfig.

Attributes:

NameTypeDescription
modelstr
base_urlOptional[str]
Source code in skyrl/train/config/config.py:885-888
@dataclass
class GSM8kLLMJudgeEnvConfig(BaseConfig):
    model: str = "gpt-4o-mini"
    base_url: Optional[str] = None

from_dict_config

from_dict_config(cfg: DictConfig) -> BaseConfig

Construct a typed BaseConfig from a Hydra DictConfig.

attr model

model: str = 'gpt-4o-mini'

attr base_url

base_url: Optional[str] = None

On this page

Top-Level Configclass SkyRLTrainConfigfrom_dict_configattr dataattr trainerattr generatorattr environmentmethod classmethod from_cli_overridesmethod make_configmethod get_config_as_dictmethod get_config_as_yaml_strData & Modelclass DataConfigfrom_dict_configattr train_dataattr val_dataattr dataloaderclass ModelConfigfrom_dict_configattr pathattr loraattr fake_int4_qatclass SkyRLLoraConfigfrom_dict_configattr rankattr alphaattr dropoutattr lora_sync_pathattr target_modulesattr exclude_modulesattr init_methodattr max_lorasattr max_cpu_lorasTrainingclass TrainerConfigfrom_dict_configattr placementattr use_expandable_segmentsattr sequence_parallel_backendattr strategyattr policyattr refattr criticattr algorithmattr mtpattr fully_asyncattr gradient_checkpointingattr gradient_checkpointing_use_reentrantattr seedattr resume_modeattr resume_pathattr log_pathattr ckpt_pathattr max_ckpts_to_keepattr ckpt_intervalattr hf_save_intervalattr export_pathattr bf16attr epochsattr max_training_stepsattr update_epochs_per_batchattr train_batch_sizeattr policy_mini_batch_sizeattr critic_mini_batch_sizeattr micro_train_batch_size_per_gpuattr micro_forward_batch_size_per_gpuattr max_tokens_per_microbatchattr recompute_old_logprobs_per_minibatchattr update_ref_every_epochattr remove_microbatch_paddingattr eval_batch_sizeattr eval_before_trainattr eval_intervalattr max_prompt_lengthattr flash_attnattr disable_fast_tokenizerattr project_nameattr run_nameattr loggerattr enable_ray_gpu_monitorattr tagsattr dump_data_batchattr dump_eval_resultsattr print_example_intervalattr num_logger_eval_samplesattr num_logger_train_samplesattr log_example_intervalattr logprobs_chunk_sizeattr vocab_entropy_chunk_sizeattr vocab_entropy_chunk_memory_mbattr fused_lm_head_logprobattr fused_lm_head_logprob_backendclass OptimizerConfigfrom_dict_configattr lrattr adam_betasattr weight_decayattr max_grad_normattr offload_after_stepattr num_warmup_stepsattr schedulerclass MixedPrecisionConfigfrom_dict_configattr param_dtypeattr reduce_dtypeattr buffer_dtypeBackend Configclass FSDPConfigfrom_dict_configattr cpu_offloadattr reshard_after_forwardattr fsdp_sizeattr mixed_precisionattr wrap_policyclass MegatronConfigfrom_dict_configattr tensor_model_parallel_sizeattr pipeline_model_parallel_sizeattr context_parallel_sizeattr expert_model_parallel_sizeattr expert_tensor_parallel_sizeattr moe_token_dispatcher_typeattr moe_router_load_balancing_typeattr moe_aux_loss_coeffattr moe_grouped_gemmattr moe_router_score_functionattr moe_router_enable_expert_biasattr moe_enable_routing_replayattr moe_per_layer_loggingattr moe_router_dtypeattr ddp_configattr hf_export_configattr lora_configattr optimizer_config_kwargsattr transformer_config_kwargsattr empty_cuda_cacheattr model_config_kwargsattr dist_ckpt_optim_fully_reshardableattr freeze_moe_routerattr mtp_num_layersattr mtp_loss_weightattr mtp_loss_chunk_sizeattr mtp_loss_topkattr async_dist_ckpt_saveattr async_dist_ckpt_strategyclass MegatronDDPConfigfrom_dict_configattr grad_reduce_in_fp32attr overlap_grad_reduceattr overlap_param_gatherattr average_in_collectiveclass MegatronLoraConfigfrom_dict_configattr lora_typeattr merge_loraclass TorchProfilerConfigfrom_dict_configattr enableattr ranksattr save_pathattr skip_firstattr waitattr warmupattr activeattr repeatattr activitiesattr record_shapesattr profile_memoryattr with_stackattr with_flopsattr with_modulesattr export_typemethod validatePlacementclass PlacementConfigfrom_dict_configattr colocate_allattr colocate_policy_refattr policy_num_nodesattr policy_num_gpus_per_nodeattr critic_num_nodesattr critic_num_gpus_per_nodeattr ref_num_nodesattr ref_num_gpus_per_nodePolicy & Algorithmclass PolicyConfigfrom_dict_configattr modelattr optimizer_configattr fsdp_configattr sequence_parallel_sizeattr use_torch_compileattr record_memoryattr torch_profiler_configattr megatron_configattr model_config_kwargsattr language_model_onlyattr inference_only_initclass CriticConfigfrom_dict_configattr modelattr optimizer_configattr fsdp_configattr sequence_parallel_sizeattr model_config_kwargsclass RefConfigfrom_dict_configattr modelattr sequence_parallel_sizeattr fsdp_configattr megatron_configattr model_config_kwargsattr language_model_onlyclass AlgorithmConfigfrom_dict_configattr advantage_estimatorattr kl_ctrlattr kl_estimator_typeattr use_kl_in_rewardattr use_kl_lossattr kl_loss_coefattr use_entropy_lossattr entropy_loss_coefattr temperatureattr advantage_batch_normalizeattr value_head_prefixattr policy_loss_typeattr loss_reductionattr grpo_norm_by_stdattr zero_variance_filterattr zero_variance_filter_tolattr lambdattr gammaattr eps_clip_lowattr eps_clip_highattr clip_ratio_cattr tis_imp_ratio_capattr use_tisattr off_policy_correctionattr sapoattr value_clipattr dynamic_samplingattr clip_covattr kl_covattr cispoattr dppoattr max_seq_lenclass KLCtrlConfigfrom_dict_configattr typeattr kl_targetattr horizonAlgorithm Extensionsclass SAPOConfigfrom_dict_configattr tau_posattr tau_negclass DynamicSamplingConfigfrom_dict_configattr typeattr max_sample_batchesattr min_replace_ratioclass ClipCovConfigfrom_dict_configattr clip_ratioattr clip_cov_lbattr clip_cov_ubclass KLCovConfigfrom_dict_configattr kl_cov_fracattr ppo_kl_coefclass CISPOConfigfrom_dict_configattr cispo_eps_clip_lowattr cispo_eps_clip_highclass OffPolicyCorrectionConfigfrom_dict_configattr tis_ratio_typeattr token_tis_ratio_clip_highattr sequence_tis_ratio_clip_highattr sequence_mask_metricattr geo_mask_highattr geo_mask_lowattr product_mask_highattr product_mask_lowattr outlier_token_is_threshold_lowattr outlier_token_is_threshold_highattr token_mask_is_threshold_lowattr token_mask_is_threshold_highclass FullyAsyncConfigfrom_dict_configattr enabledattr max_staleness_stepsattr num_parallel_generation_workersattr sample_full_batchattr clear_kv_cache_on_weight_syncattr simulate_trainingattr simulate_training_step_secondsattr simulate_weight_sync_secondsInference & Generationclass SamplingParamsfrom_dict_configattr max_generate_lengthattr repetition_penaltyattr temperatureattr top_pattr min_pattr top_kattr logprobsattr stopattr additional_kwargsclass ChatTemplateConfigfrom_dict_configattr sourceattr name_or_pathclass InferenceEngineConfigfrom_dict_configattr model_dtypeattr run_engines_locallyattr num_enginesattr backendattr weight_sync_backendattr weight_transfer_threshold_cuda_ipc_GBattr tensor_parallel_sizeattr pipeline_parallel_sizeattr expert_parallel_sizeattr data_parallel_sizeattr vllm_v1_disable_multiprocattr enable_prefix_cachingattr enable_chunked_prefillattr enable_return_routed_expertsattr max_num_batched_tokensattr enforce_eagerattr fully_sharded_lorasattr enable_ray_prometheus_statsattr gpu_memory_utilizationattr offload_kv_for_weight_syncattr use_expandable_segmentsattr max_num_seqsattr served_model_nameattr distributed_executor_backendattr language_model_onlyattr engine_init_kwargsattr speculative_configattr external_proxy_urlattr external_server_urlsattr enable_pdattr num_prefillattr router_init_kwargsclass GeneratorConfigfrom_dict_configattr inference_engineattr n_samples_per_promptattr batchedattr max_turnsattr max_input_lengthattr chat_templateattr chat_template_kwargsattr sampling_paramsattr use_conversation_multi_turnattr append_eos_token_after_stop_str_in_multi_turnattr eval_sampling_paramsattr eval_n_samples_per_promptattr zero_reward_on_non_stopattr use_cache_saltattr apply_overlong_filteringattr step_wise_trajectoriesattr vision_language_generatorattr merge_stepwise_outputEnvironmentclass EnvironmentConfigfrom_dict_configattr env_classattr skyrl_gymclass SkyRLGymConfigfrom_dict_configattr max_env_workersattr text2sqlattr llm_as_a_judgeattr searchclass GSM8kLLMJudgeEnvConfigfrom_dict_configattr modelattr base_url