Repository navigation
Add BAPO policy loss with adaptive clipping bounds - #644
Open
Kingpython123 wants to merge 1 commit into
Open
Kingpython123 wants to merge 1 commit into
Kingpython123 wants to merge 1 commit into
Conversation
Add BAPOPolicyLossFn (arXiv:2510.18927), which keeps the PPO-clip surrogate but searches the clipping bounds for every call. Starting from [a-, a+], the upper bound is raised by delta_1 up to b+ and then the lower bound by delta_2 up to b-, until positive-advantage tokens contribute at least rho_0 of the policy gradient (Eq. 8, Algorithm 1). Bounds are explicit importance-ratio values. All candidate bounds are evaluated in one vectorized pass, so the search costs a single host sync. - Register the loss as bapo and add a bapo algorithm preset (GRPO advantage, no critic) - Log the selected bounds and the positive contribution ratio - Add unit tests against a literal transcription of Algorithm 1, edge cases and equivalence to PPO with fixed bounds - Add a GSM8K example and list BAPO in the README and docs (en/zh)
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Closes #621. BAPO is one of the algorithms listed in #470.
BAPO (Balanced Policy Optimization with Adaptive Clipping) targets off-policy / stale-data training (experience reuse, partial rollouts, async mode). With stale data, negative-advantage tokens tend to dominate the policy gradient, and a fixed clip range blocks the updates from low-probability positive tokens. BAPO keeps the PPO-clip surrogate but picks the clipping bounds for every update, which fits Trinity's async and off-policy modes.
Implementation
BAPOPolicyLossFnintrinity/algorithm/policy_loss_fn/bapo_policy_loss.py, following the structure ofPPOPolicyLossFn/SAPOPolicyLossFn. It is registered asbapoinPOLICY_LOSS_FN, with abapoalgorithm preset inALGORITHM_TYPEthat mirrors the SAPO preset (GRPO advantage, no critic).Bound search (Algorithm 1). Starting from
c_low = a-,c_high = a+, raisec_highbyδ1up tob+, thenc_lowbyδ2up tob-, until the positive contribution ratioρ ≥ ρ0. If the target is never met, the widest bounds reached are used. The bounds are explicit importance-ratio values (e.g.0.6/1.2), not1 ± clip_rangeepsilons, and the argument names say so:lower_bound_start/lower_bound_max/lower_bound_stepupper_bound_start/upper_bound_max/upper_bound_steptarget_positive_ratioclip_ratio_cDefaults follow the paper's Algorithm 1 order and Sec. 5.1 hyperparameters (the reference code uses a different order and a pos/neg ratio target of 1; both are reachable through the arguments except the order).
Definition of ρ (Eq. 8). ρ is the share of the policy gradient that comes from positive-advantage tokens. Each token contributes
ratio * |advantage|(the magnitude of its gradient coefficient onlog π) when it is not clipped and nothing otherwise: a positive token is clipped whenratio > c_high, a negative token whenratio < c_loworratio > clip_ratio_c. With this definition raisingc_highadmits more positive tokens and raisingc_lowdrops low-ratio negative tokens, so both steps of Algorithm 1 move ρ towards the target. Measuring the clipped surrogate values instead would make raisingc_lowincrease the negative share, which defeats the second step. When no negative token contributes, ρ = 1.Cost. The schedule of candidate
(c_low, c_high)pairs is fixed at construction (52 pairs with the defaults). All candidates are evaluated in one vectorized pass over the valid tokens, so the search needs a single host sync per call instead of one per loop iteration.Scope. The search runs per call, i.e. per micro-batch on each rank (option (a) in the issue), so the policy-loss interface is unchanged. Synchronizing the contribution sums across DP ranks would need
dp_groupto be forwarded to the policy loss and can be a follow-up.Metrics. In addition to the PPO metrics (
pg_clipfrac,pg_clipfrac_lower,ppo_kl,pg_loss), the loss logsbapo_clip_low,bapo_clip_highandbapo_positive_ratio.Example and docs
examples/bapo_gsm8k/(config + README), derived from the CISPO GSM8K example.README.md,README_zh.md,docs/sphinx_doc/source{,_zh}/main.md, and to the example lists inexample_dataset_perspective.md(en/zh).Tests
tests/algorithm/bapo_policy_loss_test.py(CPU-only, 11 tests, no verl import needed):(0.9, 3.0);PPOPolicyLossFn(clip_range_low=0.2, clip_range_high=0.28);bapo.The example config also loads and passes
AlgorithmConfigValidator, andpre-commit runpasses on all changed files. I have not run an end-to-end GPU training job.