feat(ppo): decouple actor and critic training epochs - #3829
Conversation
c14539c to
6e8790c
Compare
73b6590 to
2199947
Compare
2199947 to
4918f54
Compare
4918f54 to
b008666
Compare
|
/ok to test b008666 |
bg51717
left a comment
There was a problem hiding this comment.
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
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>
|
/ok to test a39596a |
yuki-97
left a comment
There was a problem hiding this comment.
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.
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>
a39596a to
bf66a15
Compare
|
/ok to test bf66a15 |
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>
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>
bf66a15 to
a440755
Compare
|
/ok to test a440755 |
What does this PR do ?
Adds an independent
ppo.critic_ppo_epochssetting while preserving the existing behavior by defaulting it toppo_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
Before your PR is "Ready for review"
Pre checks:
Additional Information
ppo_epochs=2andcritic_ppo_epochs=3.