AsyncTensorRLHF / src /trainer /ppo_loss.py
tahamajs's picture
Initial release of AsyncTensorRLHF: High-Throughput Asynchronous RLHF with Tensor-Native Rewards
e791b16 verified
Raw History Blame Contribute Delete
2.2 kB
# PPO loss implementation with optional off‑policy correction (M2PO)
import torch
from torch.nn import functional as F
def compute_ppo_loss(
policy_log_probs: torch.Tensor, # (B, seq_len)
old_log_probs: torch.Tensor, # (B, seq_len)
advantages: torch.Tensor, # (B, seq_len)
clip_eps: float = 0.2,
use_m2po: bool = False,
m2_threshold: float = 2.0,
) -> torch.Tensor:
"""Compute PPO (or M2PO) loss.
Parameters
----------
policy_log_probs : torch.Tensor
Log‑probs of actions under the current policy.
old_log_probs : torch.Tensor
Log‑probs recorded during rollout.
advantages : torch.Tensor
Advantage estimates (reward‑to‑go minus baseline).
clip_eps : float, default 0.2
Standard PPO clipping epsilon.
use_m2po : bool, default False
If True, applies the second‑moment trust‑region (M2PO) instead of clipping.
m2_threshold : float, default 2.0
Maximum allowed value of (ratio ** 2) mean for M2PO.
"""
# ratio = pi(a|s) / pi_old(a|s)
ratio = torch.exp(policy_log_probs - old_log_probs)
if use_m2po:
# second‑moment constraint
m2 = (ratio ** 2).mean()
mask = ratio < m2_threshold
loss = -torch.min(
ratio * advantages,
torch.clamp(ratio, 1.0 - clip_eps, 1.0 + clip_eps) * advantages,
)
loss = (loss * mask.float()).sum() / mask.float().sum().clamp(min=1.0)
else:
# standard PPO clipping
clipped_ratio = torch.clamp(ratio, 1.0 - clip_eps, 1.0 + clip_eps)
loss = -torch.min(ratio * advantages, clipped_ratio * advantages).mean()
return loss
def compute_m2po_loss(
policy_log_probs: torch.Tensor,
old_log_probs: torch.Tensor,
advantages: torch.Tensor,
clip_eps: float = 0.2,
m2_threshold: float = 2.0,
) -> torch.Tensor:
"""Convenience wrapper: compute_ppo_loss with use_m2po=True.
Returns a scalar torch.Tensor.
"""
return compute_ppo_loss(
policy_log_probs,
old_log_probs,
advantages,
clip_eps=clip_eps,
use_m2po=True,
m2_threshold=m2_threshold,
)