Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/liger_kernel/chunked_loss/fused_linear_ppo.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def forward(
vllm_is_ratio=None,
delta=None,
use_bias_correction_kl=False,
entropy_coef=0.0,
):
# TODO: check torch compile matmul
"""Chunked forward pass for PPO loss computation.
Expand Down Expand Up @@ -125,6 +126,7 @@ def forward(
sapo_temperature_neg=sapo_temperature_neg,
delta=delta,
use_bias_correction_kl=use_bias_correction_kl,
entropy_coef=entropy_coef,
)

def fused_fwd_bwd(
Expand Down Expand Up @@ -327,6 +329,7 @@ def _compute_chunk_loss(
sapo_temperature_neg=1.05,
delta=None,
use_bias_correction_kl=False,
entropy_coef=0.0,
):
"""Compute loss for a single chunk."""
# Get policy log probabilities using chunk_forward
Expand Down Expand Up @@ -361,6 +364,7 @@ def _compute_chunk_loss(
vllm_is_ratio=vllm_is_ratio_chunk,
delta=delta,
use_bias_correction_kl=use_bias_correction_kl,
entropy_coef=entropy_coef,
)

return chunk_loss, chunk_metrics
Expand Down
16 changes: 16 additions & 0 deletions src/liger_kernel/chunked_loss/grpo_loss.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def ppo_loss_fn(
vllm_is_ratio=None, # vLLM importance sampling ratio (chunk_size, seq_len) or (chunk_size, 1) or None
delta=None, # Upper clamp for two-sided clipping (INTELLECT-2)
use_bias_correction_kl=False, # Importance-sampling-corrected KL (DeepSeek-V3.2)
entropy_coef=0.0, # Entropy regularization coefficient: loss -= entropy_coef * H
**kwargs,
):
"""GRPO Loss Function matching GRPOTrainer implementation."""
Expand Down Expand Up @@ -165,6 +166,15 @@ def ppo_loss_fn(
# Combine losses
per_token_loss = per_token_loss + beta * kl_div

# Entropy regularization (a.k.a. PPO entropy bonus): higher per-token entropy H lowers the loss,
# counteracting entropy collapse. H = -sum_v p_v * log p_v, computed from the
# chunk's full log_probs (already materialized for the policy term -> no extra
# logit pass). per_token_loss is (B, T) at token level; padding is masked out in
# the reduction below. NOTE: assumes importance_sampling_level == "token".
if entropy_coef != 0.0:
per_token_entropy = -(log_probs.exp() * log_probs).sum(dim=-1) # (B, T)
per_token_loss = per_token_loss - entropy_coef * per_token_entropy

# Note: We normalize by the number of tokens in the batch (using full_attention_mask),
# which is consistent with the DAPO loss implementation (https://arxiv.org/html/2503.14476v1)
# and TRL GRPO implementation
Expand Down Expand Up @@ -251,6 +261,7 @@ def forward(
vllm_is_ratio=None,
delta=None,
use_bias_correction_kl=False,
entropy_coef=0.0,
):
"""
Fused linear layer with GRPO loss.
Expand Down Expand Up @@ -317,6 +328,7 @@ def forward(
vllm_is_ratio=vllm_is_ratio,
delta=delta,
use_bias_correction_kl=use_bias_correction_kl,
entropy_coef=entropy_coef,
)

@staticmethod
Expand Down Expand Up @@ -352,6 +364,7 @@ def backward(ctx, grad_output, *grad_metrics):
None, # grad_vllm_is_ratio
None, # grad_delta
None, # grad_use_bias_correction_kl
None, # grad_entropy_coef
)


Expand All @@ -374,6 +387,7 @@ def __init__(
temperature: float = 1.0,
delta: Optional[float] = None,
use_bias_correction_kl: bool = False,
entropy_coef: float = 0.0,
):
"""
Args:
Expand Down Expand Up @@ -416,6 +430,7 @@ def __init__(
self.temperature = temperature
self.delta = delta
self.use_bias_correction_kl = use_bias_correction_kl
self.entropy_coef = entropy_coef

def forward(
self,
Expand Down Expand Up @@ -459,4 +474,5 @@ def forward(
vllm_is_ratio,
self.delta,
self.use_bias_correction_kl,
self.entropy_coef,
)
Loading