Upload training/train_grpo.py with huggingface_hub
Browse files- training/train_grpo.py +13 -9
training/train_grpo.py
CHANGED
|
@@ -782,19 +782,23 @@ def train(cfg: TrainConfig) -> None:
|
|
| 782 |
# so on the first opt step the ratio == 1; the clip becomes
|
| 783 |
# active only across multiple opt steps per batch. We still
|
| 784 |
# apply it for stability when group_size is large.
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
|
| 788 |
-
|
|
|
|
| 789 |
ratio, 1.0 - cfg.ppo_clip, 1.0 + cfg.ppo_clip
|
| 790 |
-
)
|
| 791 |
-
|
| 792 |
-
|
| 793 |
-
# but bounded for stability.
|
| 794 |
|
| 795 |
-
kl_term = cfg.kl_coef * (cur_lp - ref_lp.detach()).pow(2)
|
| 796 |
|
| 797 |
loss = pg_term + kl_term
|
|
|
|
|
|
|
|
|
|
|
|
|
| 798 |
loss.backward()
|
| 799 |
|
| 800 |
total_loss_val += float(loss.detach().item())
|
|
|
|
| 782 |
# so on the first opt step the ratio == 1; the clip becomes
|
| 783 |
# active only across multiple opt steps per batch. We still
|
| 784 |
# apply it for stability when group_size is large.
|
| 785 |
+
# Stable PPO surrogate: clamp log-ratio before exp to avoid
|
| 786 |
+
# overflow/underflow from very large policy deltas.
|
| 787 |
+
log_ratio = (cur_lp - ref_lp.detach()).clamp(-20.0, 20.0)
|
| 788 |
+
ratio = torch.exp(log_ratio)
|
| 789 |
+
clipped_ratio = torch.clamp(
|
| 790 |
ratio, 1.0 - cfg.ppo_clip, 1.0 + cfg.ppo_clip
|
| 791 |
+
)
|
| 792 |
+
adv_t = torch.tensor(float(adv), device=device, dtype=cur_lp.dtype)
|
| 793 |
+
pg_term = -torch.min(ratio * adv_t, clipped_ratio * adv_t)
|
|
|
|
| 794 |
|
| 795 |
+
kl_term = cfg.kl_coef * (cur_lp - ref_lp.detach()).pow(2)
|
| 796 |
|
| 797 |
loss = pg_term + kl_term
|
| 798 |
+
if not torch.isfinite(loss):
|
| 799 |
+
# Skip pathological pairs instead of poisoning optimizer
|
| 800 |
+
# state with inf/nan gradients.
|
| 801 |
+
continue
|
| 802 |
loss.backward()
|
| 803 |
|
| 804 |
total_loss_val += float(loss.detach().item())
|