Concepts / Cross-Entropy Loss for Language Models

Cross-Entropy Loss for Language Models

Padding positions in a batch are excluded from the training loss by assigning them the placeholder value -100 in the target lists.

  • Programming

Filler That Should Not Teach

When training sequences in a batch have different lengths, the shorter ones are filled out with extra padding tokens so that every row has the same size. The tensors have to be rectangular for the computation to work, but the filler carries no information about the language the model should learn. The problem this article addresses is how to keep that filler from influencing the training signal, specifically the loss that the optimizer uses to adjust the weights.

The approach is to assign a special placeholder value, -100, to every padding position in the target lists. The loss function is then configured to skip any position that carries that value. Padded rows keep their place in the tensor, so the shape never changes, but they contribute nothing to the average. Before explaining the mechanism, it helps to watch the placeholder in action and predict what it does.

What do you think happens?

You have a valid two-row loss. You add a third row of logits and set its target to -100 instead of a real token index. Does the overall loss change?

  • Yes, the extra row raises the loss

  • Yes, the extra row lowers the loss

  • No, the loss stays the same as the two-row loss

Reveal answer
Answer:

No, the loss stays the same as the two-row loss.

The third row still exists in the logits, but cross-entropy ignores the entry whose target is -100. The position is removed from the calculation without changing the shape of any tensor.

Tracing the Loss Over Three Rows

Start with a small self-contained example. Each row of the logits tensor holds one score per vocabulary entry for a single predicted position, and the targets tensor holds the index of the correct entry for each row. The example uses two positions and a two-entry vocabulary, which keeps every number easy to check by hand.

Now add a genuine third position with a real target. A correct token ID at that position is supposed to influence the loss. Adding a valid third target changes the loss from 1.1269 to 0.7936. The loss is an average over the positions that count, so a position with a real target shifts the result. The key question is what happens when the third target is a placeholder instead of a real index.

python
Notes on the code
  • The logits tensor has one row per predicted position and one column per vocabulary entry.
  • The targets tensor holds the correct column index for each row.
  • The third target is -100, so PyTorch's cross-entropy skips that row.
  • Both printed values should be identical, because the ignored row adds nothing to the average.

The loss over the three rows equals the loss over the two original rows. Run the code above and compare the two printed values. The third row is still present in the logits, so the tensor shape is unchanged. Only its contribution to the loss is removed. This is the mechanism that lets padded batches be used safely.

How a -100 Target Leaves the Average

PyTorch's cross-entropy loss ignores any target equal to -100. A padded row therefore contributes nothing to the average, even though the tensor shape is unchanged. Each position is checked in turn: if its target is a real index, its loss is computed and counted; if its target is -100, that position is skipped entirely and is not part of the averaged result.

Next positionTarget is -100?Compute loss forpositionreal target indexAverage over countedpositionsSkip positioncontributes nothingnoyes
What happens to each position's loss when its target is a real index versus -100, and how the final averaged loss is formed.

The denominator of the average changes with the ignored positions. The loss is averaged only over the positions that are not ignored. A batch with many padded positions therefore does not dilute the loss with rows that were never meant to count.

Which End-of-Text Tokens Survive

Padding in target lists is usually the end-of-text token, ID 50256. Replacing every instance with -100 would look tidy, but it would remove information the model needs. The first end-of-text token in each target list is kept, so the model gets a training target at the stopping point and learns when to generate an end-of-text token in response to an instruction. The model treats that token as the signal that its generated response is complete. Only the later copies, which serve purely as padding, are replaced with -100.

464kept464kept818kept3290kept2068kept50256first end-of-text, kept3797kept50256first end-of-text, kept-100padding replaced318kept-100padding replaced-100padding replaced50256first end-of-text, kept-100padding replaced-100padding replaced
For three target lists of different real lengths, which positions keep their token IDs and which are replaced with -100. The first end-of-text token in each row is kept.
First 50256marks where real contentendsLater 50256serves only as paddingModel learns to stoptraining target at stoppingpoint-100skipped by the lossgivesbecomes
How the first end-of-text token differs from the later copies in the same target list, and why only one of them is kept.
Worked example

Applying the end-of-text rule to one row

A target list of length 5 is 464, 2068, 50256, 50256, 50256. Which positions keep their IDs and which become -100?

  1. 1
    Find the first end-of-text token

    The first 50256 is at position 2, counting from 0.

  2. 2
    Keep it and everything before it

    Positions 0, 1 and 2 keep their IDs, so the model still gets a training target at the stopping point.

  3. 3
    Replace the later copies

    Positions 3 and 4 are later end-of-text tokens that only serve as padding, so each becomes -100.

  4. 4
    Check the effect on the loss

    Positions 3 and 4 are skipped, so only positions 0 to 2 are counted in the averaged loss.

Result

The target list becomes 464, 2068, 50256, -100, -100.

Pipeline From Targets to Loss

The batching process prepares the target sequence by shifting token IDs one position to the right and appending an end-of-text token. The padding replacement is the last step before those targets reach the loss. The first two stages decide what the target list contains, and the replacement stage decides which positions the loss may see. Only the final stage performs the actual skipping.

This separation matters when you debug a training run. A problem in the padding step will show up later as a loss that looks wrong, even though the loss function itself is working as designed. When a loss looks suspicious, check the target lists before blaming the loss function.

  • Common mistake

    Replacing every end-of-text token with -100

    Why it fails

    Removing the first end-of-text token deletes the training signal that teaches the model when to stop.

    Do this instead

    Keep the first end-of-text token in each target list and replace only the later padding copies.

  • Common mistake

    Assuming -100 changes the tensor shape

    Why it fails

    The padded row is still in the logits and targets, so the shape is unchanged. Only its contribution to the loss is removed.

    Do this instead

    Expect the same shapes and a loss averaged over the counted positions only.

  • Common mistake

    Using allowed_max_length to exclude padding

    Why it fails

    allowed_max_length limits how long each sample may be. It does not decide which positions count toward the loss.

    Do this instead

    Use the -100 placeholder in the target lists to exclude padding positions from the loss.

  • Common mistake

    Expecting a padded position to change the weights through the loss

Check Your Batch

EASY

A batch has two target lists of length 4. Row A is 818, 2068, 50256, 50256. Row B is 818, 50256, 50256, 50256. Write the target lists after the padding replacement, then state which positions are counted in the averaged loss.

Hints
  • Find the first 50256 in each row and keep it.
  • Every later 50256 becomes -100.
  • Counted positions are the ones whose targets are not -100.

Key Takeaways

  1. 1
    Padding positions are excluded from the training loss by setting their target to -100.
  2. 2
    PyTorch's cross-entropy ignores targets equal to -100, so the padded row keeps its place in the tensor but adds nothing to the average.
  3. 3
    The first end-of-text token, ID 50256, in each target list is kept so the model learns when to stop; later copies become -100.
  4. 4
    allowed_max_length limits sample length and is a separate control from the -100 placeholder.

At a glance

  • Padding positions are excluded from the training loss by setting their target to -100.
  • PyTorch's cross-entropy ignores targets equal to -100, so a padded row adds nothing to the average even though the shape is unchanged.
  • The first end-of-text token, ID 50256, in each target list is kept so the model learns when to stop; later copies become -100.
  • allowed_max_length controls sample length and is separate from the -100 placeholder that controls which positions count toward the loss.

Related concepts

More concepts starting with C