nemo_rl.algorithms.opd#
On-policy distillation (OPD) helpers for async GRPO.
Teacher routing, config helpers, and teacher worker group creation. Advantage computation lives in advantage_estimator.OPDAdvantageEstimator. IS truncation lives in loss_functions.ClippedPGLoss (ICE-POP mode).
Module Contents#
Classes#
Per-teacher resourcing for a non-colocated teacher worker group. |
|
Non-colocated (separate-GPU) teacher resourcing for on-policy distillation. |
|
Full-vocabulary MOPD ( |
|
User-facing config for the top-level |
|
Enrich SingleController rollout rows with teacher logprobs through TQ. |
Functions#
Return the on_policy_distillation sub-config as a plain dict. |
|
Whether on-policy distillation is enabled in the config. |
|
Whether OPD is enabled with non-colocated (separate-GPU) teachers. |
|
Return the validated |
|
Return the data-plane column name carrying this run’s teacher payload. |
|
Return the per-sample teacher-identity column, or |
|
Deduplicated teacher configs in |
|
Checkpoint path per |
|
Whether the training loop will zero |
|
Raise if OPD is enabled but the config would zero |
|
Raise if TROPD knobs are set on a path that never reads the advantage. |
|
Map each agent_ref to a teacher alias. |
|
Compute teacher-routing diagnostics. |
|
Sequence divisor to pre-pad teacher logprob inputs to. |
|
Validate the fallback teacher alias before reserving resources. |
|
Create and reserve topology-aware clusters for non-colocated teachers. |
|
Create TeacherWorkerGroup instances for non-colocated teachers. |
API#
- class nemo_rl.algorithms.opd.TeacherResourceConfig#
Bases:
pydantic.BaseModelPer-teacher resourcing for a non-colocated teacher worker group.
extra="allow"keeps the escape hatch for arbitrary megatron settings: any unknown top-level key is folded intomegatron_cfg_overrides.- tensor_model_parallel_size: int#
1
- pipeline_model_parallel_size: int#
1
- context_parallel_size: int#
1
- expert_model_parallel_size: int#
1
- num_nodes: int#
1
- gpus_per_node: int#
8
- precision: str#
‘bf16’
- micro_batch_size: int#
4
- megatron_cfg_overrides: dict[str, Any]#
‘Field(…)’
- class nemo_rl.algorithms.opd.NonColocatedTeachersConfig#
Bases:
pydantic.BaseModelNon-colocated (separate-GPU) teacher resourcing for on-policy distillation.
- enabled: bool#
False
- default_teacher_cfg: nemo_rl.algorithms.opd.TeacherResourceConfig#
‘Field(…)’
- teacher_overrides: dict[str, nemo_rl.algorithms.opd.TeacherResourceConfig]#
‘Field(…)’
- class nemo_rl.algorithms.opd.OnPolicyDistillationFullConfig#
Bases:
pydantic.BaseModelFull-vocabulary MOPD (
opd_full).The student matches the teacher’s entire next-token distribution through an exact reverse KL instead of the sampled-token log-probability gap – the K=V limit of the top-k estimator, with no score-function tail term.
The policy-gradient knobs on
ClippedPGLossConfig(ratio clipping, CISPO, importance-sampling correction, truncated IS) have no code path here and are rejected at construction. The OPD advantage estimator still runs: its output is unused, butadvantagesis a required training column.- enabled: bool#
False
- teacher_payload: Literal[hidden_states, logits]#
‘hidden_states’
- divergence: Literal[reverse_kl]#
‘reverse_kl’
- payload_dtype: Literal[bfloat16, float16, float32]#
‘bfloat16’
- chunk_size: Optional[int]#
None
- teacher_lm_head_lifecycle: Literal[none, offload, evict]#
‘offload’
- validate_decomposition: bool#
False
- validate_positive_sizes() nemo_rl.algorithms.opd.OnPolicyDistillationFullConfig#
Reject a chunk size that would make the divergence kernels useless.
- class nemo_rl.algorithms.opd.OnPolicyDistillationConfig#
Bases:
pydantic.BaseModelUser-facing config for the top-level
on_policy_distillationblock.- enabled: bool#
False
- teacher_model_by_agent_name: dict[str, str]#
‘Field(…)’
- default_teacher_alias: Optional[str]#
None
- strict_agent_name_match: bool#
False
True
- non_colocated_teachers: Optional[nemo_rl.algorithms.opd.NonColocatedTeachersConfig]#
None
- full: Optional[nemo_rl.algorithms.opd.OnPolicyDistillationFullConfig]#
None
- nemo_rl.algorithms.opd._opd_cfg(master_config: Any) dict[str, Any]#
Return the on_policy_distillation sub-config as a plain dict.
Accepts a MasterConfig (where the field is an OnPolicyDistillationConfig BaseModel), a plain dict, or a config object missing the field (non-OPD recipes like math). Downstream code reads the result dict-style.
- nemo_rl.algorithms.opd.is_opd_enabled(master_config: Any) bool#
Whether on-policy distillation is enabled in the config.
- nemo_rl.algorithms.opd.is_non_colocated_teachers_enabled(master_config: Any) bool#
Whether OPD is enabled with non-colocated (separate-GPU) teachers.
- nemo_rl.algorithms.opd.get_opd_full_config(
- master_config: Any,
Return the validated
opd_fullsub-config when the feature is enabled.- Parameters:
master_config – Full training configuration, a plain dict, or any object without the field (non-OPD recipes).
- Returns:
The full-vocabulary config when both OPD and
full.enabledare on, otherwiseNone.
- nemo_rl.algorithms.opd.opd_full_payload_field( ) str#
Return the data-plane column name carrying this run’s teacher payload.
- nemo_rl.algorithms.opd.opd_full_teacher_index_field( ) Optional[str]#
Return the per-sample teacher-identity column, or
Noneif unneeded.Only the
hidden_statespayload needs it: the student loads a teacher LM-head shard per unique checkpoint and must know which one projects each row. Thelogitspayload ships an already-projected distribution, so no per-sample routing is needed at training time.
- nemo_rl.algorithms.opd.teacher_configs_by_index(
- teacher_configs: collections.abc.Iterable[nemo_rl.models.policy.teacher_worker_group.TeacherConfig],
Deduplicated teacher configs in
teacher_indexorder.
- nemo_rl.algorithms.opd.opd_full_teacher_checkpoints_by_index(
- master_config: Any,
Checkpoint path per
teacher_index, or None when rows carry no tag.A list, not a map: the metadata round trips through JSON.
- nemo_rl.algorithms.opd._skip_prev_logprobs(master_config: Any) bool#
Whether the training loop will zero
prev_logprobsinstead of computing it.Mirrors the predicate in
grpo_train:force_on_policy_ratiowith noseq_logprob_error_thresholdskips the student logprob pass. GRPO can also evaluate that threshold in the training loss without this pass.
- nemo_rl.algorithms.opd.assert_prev_logprobs_available(master_config: Any) None#
Raise if OPD is enabled but the config would zero
prev_logprobs.OPD’s advantage is
teacher_logprobs - prev_logprobs, so it needs a real student logprob.
- nemo_rl.algorithms.opd.assert_trust_region_supported(master_config: Any) None#
Raise if TROPD knobs are set on a path that never reads the advantage.
Full-vocabulary MOPD replaces the policy-gradient objective with an exact reverse KL and ignores
advantages, so a proximal teacher or a global baseline would be silently dropped there.
- nemo_rl.algorithms.opd.resolve_reference_aliases(
- agent_refs: list[dict],
- teacher_model_by_agent_name: dict[str, str],
- default_teacher_alias: Optional[str] = None,
- strict_agent_name_match: bool = False,
Map each agent_ref to a teacher alias.
Unmapped agents fall back to
default_teacher_alias; withstrict_agent_name_matchan unmapped agent raises instead.
- nemo_rl.algorithms.opd.get_teacher_routing_metrics(
- reference_aliases: list[str],
- teacher_model_by_agent_name: dict[str, str],
Compute teacher-routing diagnostics.
Reports unique aliases, unique underlying models, and the alias→model compression ratio (how many aliases share each underlying teacher model).
- class nemo_rl.algorithms.opd.TQTeacherLogprobCoordinator(
- *,
- dp_client: nemo_rl.data_plane.interfaces.DataPlaneClient,
- teacher_worker_groups: dict[str, Any],
- alias_to_group_alias: dict[str, str],
- on_policy_distillation_cfg: dict[str, Any],
Enrich SingleController rollout rows with teacher logprobs through TQ.
A prompt group is already present in the data plane when :meth:
enrichis called. The coordinator sends its metadata to the inference-only teacher; teacher workers fetch their own DP shards and write the token column back under the same sample IDs. The controller materializes only the final row when unique temporary rows are needed for DP divisibility. Calls targeting the same deduplicated teacher group are serialized to keep NCCL collective ordering identical across that group’s workers; distinct teachers remain independent and can run concurrently.Initialization
- teacher_logprobs_field#
‘teacher_reference_logprobs’
- _resolve_teacher( ) tuple[str, str]#
- _enrich_sync(
- meta: nemo_rl.data_plane.interfaces.KVBatchMeta,
- group_alias: str,
Run the blocking TQ-read, teacher inference, and TQ-write sequence.
- async enrich(
- meta: nemo_rl.data_plane.interfaces.KVBatchMeta,
- record: nemo_rl.experience.interfaces.PromptGroupRecord,
Write teacher logprobs before the replay-buffer slot becomes ready.
- drain_metrics() dict[str, float]#
Return and reset teacher activity accumulated since the last drain.
- teacher_checkpoints_by_index() Optional[list[str]]#
Checkpoint path per
teacher_index, or None when rows carry no tag.Read off the live worker groups, so it records what actually tagged the rows rather than what the config would produce now.
- nemo_rl.algorithms.opd.teacher_seq_pad_multiple(
- teacher_worker_groups: dict[str, Any],
- policy_make_seq_div_by: int,
Sequence divisor to pre-pad teacher logprob inputs to.
Packed teachers re-pad internally, so no pre-pad is needed (1). Non-packed teachers need the
[B, S]forward pre-padded to the policy divisor, which must be a multiple of every teacher’ssequence_length_pad_multiple. All teachers must share one packing mode.
- nemo_rl.algorithms.opd._validate_default_teacher_alias(
- opd_cfg: dict[str, Any],
Validate the fallback teacher alias before reserving resources.
- nemo_rl.algorithms.opd.reserve_teacher_clusters(
- master_config: Any,
- *,
- segment_size: Optional[int] = None,
- teacher_segment_topology: Optional[dict[str, tuple[str, int]]] = None,
Create and reserve topology-aware clusters for non-colocated teachers.
This reserves the teachers’ Ray placement groups without starting teacher workers or loading model checkpoints. Call it before starting other opportunistically placed GPU services, then pass the result to
- Func:
create_teacher_worker_groupsafter policy initialization.- Parameters:
master_config – Full training configuration containing the OPD settings.
segment_size – NVLink-domain segment size from the cluster config. When set, every teacher is constrained to one NVLink domain.
teacher_segment_topology – Topology remaining after policy and inference placement.
- Returns:
A mapping from each deduplicated teacher alias to its reserved cluster.
- Raises:
ValueError – If the configured fallback teacher alias is invalid.
ResourceInsufficientError – If the requested topology segments cannot be formed.
TimeoutError – If Ray cannot reserve a teacher placement group.
- nemo_rl.algorithms.opd.create_teacher_worker_groups(
- master_config: Any,
- policy_config: dict[str, Any],
- tokenizer: Any,
- *,
- teacher_clusters: dict[str, nemo_rl.distributed.virtual_cluster.RayVirtualCluster],
Create TeacherWorkerGroup instances for non-colocated teachers.
- Parameters:
master_config – Full training configuration containing the OPD settings.
policy_config – Student policy configuration used as the teacher worker configuration template.
tokenizer – Tokenizer passed to every teacher worker.
teacher_clusters –
Clusters already reserved by
- func:
reserve_teacher_clusters, keyed by teacher alias.
- Returns:
A tuple containing the worker groups by primary teacher alias and the mapping from every configured alias to its primary group alias.
- Raises:
ValueError – If teacher routing or the supplied cluster aliases are invalid, or teacher sequence-packing settings are incompatible.
RuntimeError – If any teacher worker fails during initialization.