> This page is for version 0.5.0 · 26.06.
> For other versions, use one of these documentation indexes:
> - Nightly (default): https://docs.nvidia.com/nemo/automodel/nightly/llms.txt
> - Latest: https://docs.nvidia.com/nemo/automodel/latest/llms.txt
> - 0.5.0 · 26.06: https://docs.nvidia.com/nemo/automodel/v0.5/llms.txt
> - 0.4.0 · 26.04: https://docs.nvidia.com/nemo/automodel/v0.4/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/automodel/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/automodel/_mcp/server.

# nemo_automodel.components.loss.soft_ce

Loss utilities for EAGLE-3 training.

## Module Contents

### Functions

| Name                                                                                             | Description                               |
| ------------------------------------------------------------------------------------------------ | ----------------------------------------- |
| [`masked_soft_cross_entropy`](#nemo_automodel-components-loss-soft_ce-masked_soft_cross_entropy) | Compute masked soft-target cross entropy. |

### API

```python
nemo_automodel.components.loss.soft_ce.masked_soft_cross_entropy(
    logits: torch.Tensor,
    target_probs: torch.Tensor,
    position_mask: torch.Tensor
) -> torch.Tensor
```

Compute masked soft-target cross entropy.

Important implementation notes:

1. The target alignment should still follow the original EAGLE-3 training
   flow: target logits / input ids are shifted in target preparation, as in
   the reference SpecForge implementation.
2. We intentionally do *not* preserve the original loss reduction from the
   EAGLE / SpecForge code. The reference implementation averages over
   `batch * seq_len` even when only a small subset of positions is valid.
   That reduction is not a sound masked-loss definition because the loss
   scale changes with padding / sparse supervision density. Here we
   normalize by the number of valid supervised positions, which is the
   correct masked objective.

**Parameters:**

**`logits`** `torch.Tensor`

Draft logits of shape `[batch, seq_len, draft_vocab_size]`.

---

**`target_probs`** `torch.Tensor`

Target distributions aligned to the draft vocabulary.

---

**`position_mask`** `torch.Tensor`

Boolean/0-1 mask of shape `[batch, seq_len, 1]`.

---

**Returns:** `torch.Tensor`

Scalar loss normalized by the number of valid positions.