@@ -372,12 +372,24 @@ def __init__(self, config: Config, *, compile_config: CompileConfig | None = Non
372372def compute_logprobs (
373373 logits : torch .Tensor ,
374374 labels : torch .Tensor ,
375- ) -> torch .Tensor :
376- """Compute per-position logprobs from logits and labels.
375+ * ,
376+ return_entropy : bool = False ,
377+ ) -> torch .Tensor | tuple [torch .Tensor , torch .Tensor ]:
378+ """Per-position logprobs from logits and labels, optionally with entropy.
377379
378380 Output shape matches input: ``[batch, seq_len]``. Any DTensor placement
379381 handling is centralized here so RL losses that call ``compute_logprobs`` do
380382 not need to duplicate the vocab-gather logic.
383+
384+ When ``return_entropy`` is set, also returns per-token Shannon entropy
385+ ``H(p) = logsumexp(logits) - sum(softmax(logits) * logits)``, shape
386+ ``[batch, seq_len]``. Both share the single vocab gather + fp32 upcast.
387+ Entropy is a metric only, so it is computed under ``no_grad``: it never
388+ contributes gradient and must not build an autograd graph over the [B, L, V]
389+ softmax.
390+
391+ Returns ``logprobs`` when ``return_entropy`` is False, else
392+ ``(logprobs, entropy)``.
381393 """
382394 if isinstance (logits , DTensor ):
383395 # TODO: pass `grad_placements=[Replicate(), ...]` to make the autograd
@@ -406,13 +418,22 @@ def compute_logprobs(
406418 dst = spmd .I ,
407419 )
408420
421+ # Single bf16->fp32 upcast, reused by both logprobs and (optionally) entropy.
422+ logits = logits .float ()
409423 B , L , V = logits .shape
410- return - F .cross_entropy (
411- logits .float (). reshape (B * L , V ),
424+ logprobs = - F .cross_entropy (
425+ logits .reshape (B * L , V ),
412426 labels .reshape (B * L ),
413427 reduction = "none" ,
414428 ignore_index = IGNORE_INDEX ,
415429 ).reshape (B , L )
430+ if not return_entropy :
431+ return logprobs
432+ with torch .no_grad ():
433+ entropy = torch .logsumexp (logits , dim = - 1 ) - (
434+ torch .softmax (logits , dim = - 1 ) * logits
435+ ).sum (dim = - 1 )
436+ return logprobs , entropy
416437
417438
418439class GradAccumulator :
0 commit comments