Shape
Wrong flattening, wrong gather dimension, or forgotten padding masks can make the loss look plausible while training the wrong target.
Module 01
The math you need to explain language modeling, loss curves, gradients, and model quality without hiding behind jargon.
Outcome
Language Modeling
A causal LLM estimates the probability of a token sequence by multiplying conditional probabilities. In practice we add log probabilities so the objective is numerically stable and decomposes token by token.
p(x_1, ..., x_T) = product_t p(x_t | x_1, ..., x_{t-1})
log p(sequence) = sum_t log p(x_t | prefix)
The model can train every position in parallel because each prediction receives the true prefix, not a sampled prefix from the model.
Pretraining Objective
The model reads tokens up to position t and is trained to
predict token t + 1. A hand-written PyTorch loop usually
shifts logits and labels explicitly before flattening into
cross_entropy. In many Hugging Face causal-LM model classes,
passing labels=input_ids delegates that shift to the model,
while ignored labels such as -100 remove padding or prompt
tokens from the loss.
import torch.nn.functional as F
def causal_lm_loss(logits, input_ids, ignore_index=-100):
# logits: [batch, time, vocab], input_ids: [batch, time]
# Predict token t+1 from the hidden state at token t.
shift_logits = logits[:, :-1, :].contiguous()
shift_labels = input_ids[:, 1:].contiguous()
return F.cross_entropy(
shift_logits.view(-1, shift_logits.size(-1)),
shift_labels.view(-1),
ignore_index=ignore_index,
)
-100 for padding, system prompts, or examples that should condition the model without contributing loss.cross_entropy expects class logits over the vocabulary and integer class-index labels, so preserve the vocab dimension as the last dimension before reshaping.Shifting labels in the dataset and then using a model that shifts labels internally can move the target two positions ahead, so the loss no longer matches the intended next-token objective.
Sources: Hugging Face causal language modeling guide, PyTorch CrossEntropyLoss docs.
Loss
For one token with class index y, cross entropy is the negative log of
the probability assigned to y. With one-hot labels, the gradient with
respect to logits is the simple and important expression
softmax(logits) - one_hot(y).
import torch
import torch.nn.functional as F
logits = torch.randn(2, 4, 32000) # batch, time, vocab
targets = torch.randint(0, 32000, (2, 4))
loss = F.cross_entropy(logits.view(-1, logits.size(-1)), targets.view(-1))
Cross entropy equals the true distribution entropy plus KL divergence from the true distribution to the model distribution, so minimizing cross entropy minimizes KL when the data distribution is fixed.
Optimization
Wrong flattening, wrong gather dimension, or forgotten padding masks can make the loss look plausible while training the wrong target.
Unstable logits, unscaled attention scores, bad learning rates, or missing warmup can make gradients explode or vanish.
Optimizer moments, scheduler steps, dropout mode, eval mode, and gradient accumulation must be kept consistent.