Skip to content

feat(ppo): decouple actor and critic training epochs - #3829

Merged
yuki-97 merged 5 commits into
mainfrom
biguo/sc-critic-ppo-epochs
Sep 1, 2026
Merged

feat(ppo): decouple actor and critic training epochs#3829
yuki-97 merged 5 commits into
mainfrom
biguo/sc-critic-ppo-epochs

Conversation

@bg51717

@bg51717 bg51717 commented Aug 25, 2026

Copy link
Copy Markdown
Member

What does this PR do ?

Adds an independent ppo.critic_ppo_epochs setting while preserving the existing behavior by defaulting it to ppo_epochs.

Critic updates are grouped before policy updates so each colocated model stays resident across its epochs instead of being repeatedly moved between CPU and GPU. The policy and critic Megatron scheduler budgets are sized independently.

Issues

None closed.

Usage

ppo:
  ppo_epochs: 2
  critic_ppo_epochs: 3

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you run the unit tests and functional tests locally?
  • Did you add or update any necessary documentation?

Additional Information

  • Tests: 177 targeted unit tests passed with 7 GPU-only skips.
  • A two-step GB300 functional smoke completed with ppo_epochs=2 and critic_ppo_epochs=3.

@copy-pr-bot

copy-pr-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label Aug 25, 2026
@bg51717 bg51717 added CI:L1 Run doctests, unit tests, and functional tests and removed CI:L1 Run doctests, unit tests, and functional tests labels Aug 25, 2026
@yuki-97
yuki-97 force-pushed the yukih/sc-warm-start-critic branch from c14539c to 6e8790c Compare August 26, 2026 02:11
@yuki-97
yuki-97 force-pushed the biguo/sc-critic-ppo-epochs branch 2 times, most recently from 73b6590 to 2199947 Compare August 28, 2026 08:13
@github-actions github-actions Bot added the CI Relating to CI label Aug 28, 2026
@yuki-97
yuki-97 changed the base branch from yukih/sc-warm-start-critic to main August 28, 2026 08:13
@github-actions

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: 2199947 (PR #3829 from biguo/sc-critic-ppo-epochs)

✅ Submodules that are properly updated:

Megatron-Bridge: ✅ PR branch is ahead of yukih/sc-warm-start-critic branch (fast-forward)

All submodule changes look good! ✨

@bg51717
bg51717 force-pushed the biguo/sc-critic-ppo-epochs branch from 2199947 to 4918f54 Compare August 28, 2026 15:10
@github-actions github-actions Bot removed the CI Relating to CI label Aug 28, 2026
@bg51717
bg51717 force-pushed the biguo/sc-critic-ppo-epochs branch from 4918f54 to b008666 Compare August 28, 2026 17:23
@bg51717 bg51717 added the CI:L0 Run doctests and unit tests label Aug 28, 2026
@bg51717

bg51717 commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

/ok to test b008666

@bg51717 bg51717 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with a 4-agent pass (rl-expert, test-agent, bug-finder, devil's-advocate) covering config validation fail-fast paths, GPU residency correctness across all 3 restructured PPO epoch loops (sync/async/single-controller), 3-way consistency between them, and the two independent Megatron train_iters formulas (cross-checked against Megatron-Bridge's scheduler consumption at the pinned submodule SHA).

No bugs found. 4 low/medium-severity suggestions below (2 test-coverage gaps, 1 docstring gap, 1 process ask around memory-fragmentation evidence) survived an adversarial devil's-advocate pass that disputed and discarded a 5th (a doc-page omission that turned out to match that page's own established convention).

Generated by Claude Code

Comment thread tests/unit/algorithms/test_ppo.py
Comment thread tests/unit/algorithms/test_ppo.py Outdated
Comment thread nemo_rl/algorithms/single_controller.py Outdated
bg51717 added a commit that referenced this pull request Aug 28, 2026
Address review feedback on #3829.

Add test_ppo_train_critic_keeps_extra_epochs_during_policy_warmup, which
pins the interaction between critic_ppo_epochs and
policy_training_start_step at the mock-call-order level. Both knobs were
covered individually, but nothing held the critic loop unconditional
while the actor loop stays gated behind warmup.

Add test_ppo_config_rejects_zero_ppo_epochs. The ppo_epochs < 1 guard is
now centralized in PPOConfig.validate_settings, but was only exercised
through model_construct, which bypasses pydantic validation entirely.

Restore the Returns: section on _value_train_epochs, dropped when it
replaced _value_train. Its sibling helpers (_value_stage,
_advantage_stage, _sync_weights) all document their return value.

Signed-off-by: bg51717 <biguo@nvidia.com>
@bg51717

bg51717 commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

/ok to test a39596a

@bg51717
bg51717 marked this pull request as ready for review August 28, 2026 18:40
@bg51717
bg51717 requested review from a team as code owners August 28, 2026 18:40
@bg51717
bg51717 requested a review from yuki-97 August 28, 2026 18:41

@yuki-97 yuki-97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the epoch-decoupling change across ppo.py, single_controller.py, the SC setup/config validators, the docs and the tests, along four lenses: correctness of the regrouped train loop, the scheduler-budget contract, config/doc parity, and test coverage. The regrouping itself looks numerically equivalent to the old interleaving (advantages and returns are computed once before the block and the policy loss never reads the critic), and the offload lifecycle is preserved.

Comment thread examples/configs/ppo_math_1B.yaml Outdated
Comment thread nemo_rl/algorithms/ppo.py Outdated
Comment thread nemo_rl/algorithms/ppo.py Outdated
Comment thread nemo_rl/algorithms/ppo.py Outdated
Comment thread nemo_rl/algorithms/single_controller.py
Comment thread nemo_rl/algorithms/single_controller.py Outdated
Comment thread nemo_rl/algorithms/single_controller.py Outdated
Comment thread docs/guides/ppo.md
bg51717 added a commit that referenced this pull request Aug 29, 2026
Address review feedback on #3829.

Add test_ppo_train_critic_keeps_extra_epochs_during_policy_warmup, which
pins the interaction between critic_ppo_epochs and
policy_training_start_step at the mock-call-order level. Both knobs were
covered individually, but nothing held the critic loop unconditional
while the actor loop stays gated behind warmup.

Add test_ppo_config_rejects_zero_ppo_epochs. The ppo_epochs < 1 guard is
now centralized in PPOConfig.validate_settings, but was only exercised
through model_construct, which bypasses pydantic validation entirely.

Restore the Returns: section on _value_train_epochs, dropped when it
replaced _value_train. Its sibling helpers (_value_stage,
_advantage_stage, _sync_weights) all document their return value.

Signed-off-by: bg51717 <biguo@nvidia.com>
@bg51717
bg51717 force-pushed the biguo/sc-critic-ppo-epochs branch from a39596a to bf66a15 Compare August 29, 2026 14:46
@bg51717

bg51717 commented Aug 29, 2026

Copy link
Copy Markdown
Member Author

/ok to test bf66a15

Comment thread nemo_rl/algorithms/ppo.py Outdated
Comment thread nemo_rl/algorithms/ppo.py Outdated
Comment thread nemo_rl/algorithms/single_controller_utils/config.py Outdated
Comment thread tests/unit/single_controller/test_single_controller_actor.py
Comment thread docs/guides/ppo.md
Comment thread nemo_rl/algorithms/ppo.py Outdated
Group critic updates before actor updates so colocated models stay resident across epochs. Add critic_ppo_epochs and separate Megatron scheduler budgets for legacy and single-controller PPO.

Signed-off-by: bg51717 <biguo@nvidia.com>
Signed-off-by: bg51717 <biguo@nvidia.com>
bg51717 and others added 3 commits August 31, 2026 15:58
Address review feedback on #3829.

Add test_ppo_train_critic_keeps_extra_epochs_during_policy_warmup, which
pins the interaction between critic_ppo_epochs and
policy_training_start_step at the mock-call-order level. Both knobs were
covered individually, but nothing held the critic loop unconditional
while the actor loop stays gated behind warmup.

Add test_ppo_config_rejects_zero_ppo_epochs. The ppo_epochs < 1 guard is
now centralized in PPOConfig.validate_settings, but was only exercised
through model_construct, which bypasses pydantic validation entirely.

Restore the Returns: section on _value_train_epochs, dropped when it
replaced _value_train. Its sibling helpers (_value_stage,
_advantage_stage, _sync_weights) all document their return value.

Signed-off-by: bg51717 <biguo@nvidia.com>
Signed-off-by: bg51717 <biguo@nvidia.com>
Split PPOConfig's combined validator into validate_epoch and
validate_async_warmup, and let critic_ppo_epochs implicitly follow
ppo_epochs unless explicitly set. Restore the single-controller
warmup test's ability to catch a critic/actor epoch mix-up by giving
it a critic_ppo_epochs distinct from ppo_epochs, and drop the
now-redundant epoch guard in single_controller_utils/config.py along
with the two tests that only exercised it.

Signed-off-by: ruit <ruit@nvidia.com>
@RayenTian
RayenTian force-pushed the biguo/sc-critic-ppo-epochs branch from bf66a15 to a440755 Compare August 31, 2026 23:00
@RayenTian

Copy link
Copy Markdown
Contributor

/ok to test a440755

@RayenTian
RayenTian requested a review from yuki-97 August 31, 2026 23:22
@yuki-97
yuki-97 enabled auto-merge (squash) September 1, 2026 00:13
@yuki-97
yuki-97 merged commit 3a0a625 into main Sep 1, 2026
68 checks passed
@yuki-97
yuki-97 deleted the biguo/sc-critic-ppo-epochs branch September 1, 2026 01:19
@tdene tdene mentioned this pull request Sep 1, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI:L0 Run doctests and unit tests Documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants