Skip to content
Articles
TechnicalFoundationsLLMsOptimization

How an LLM Finds a Lower-Loss Solution

A matrix-first look at logits, cross-entropy, gradients, AdamW, and where learning-rate schedulers actually enter the training loop.

Published Jun 24, 2026Updated Aug 4, 202618 min readDifficulty 5/5
In this article
Equation flow diagram showing LLM embeddings, attention, logits, loss, gradients, optimizer, and scheduler
A simplified view of LLM training: matrix operations make predictions, loss measures the error, gradients point to a lower-loss direction, and the scheduler controls how large each optimizer step is.

The short version

An LLM does not calculate one perfect global optimum in a clean closed-form equation. Training is too large, too noisy, and too non-convex for that. Instead, the model repeatedly moves toward lower loss on many batches of text. The practical target is a parameter region that predicts unseen text well, not proof that training found the deepest possible minimum.

The loop is simple in shape:

1. Run tokens through matrix operations.
2. Convert hidden states into next-token probabilities.
3. Measure error with cross-entropy loss.
4. Backpropagate gradients through the matrices.
5. Let an optimizer such as AdamW choose the parameter update.
6. Let a learning-rate scheduler scale the update over time.

Loss-landscape intuition

Think of the loss landscape as a foggy mountain range. The model is not handed a map to the deepest valley. It feels the local slope under its feet, takes a controlled step, checks again, and repeats this millions or billions of times.

What optimum means in practice

In classical optimization, an optimum is the parameter setting that minimizes an objective function. For an LLM, the parameters are all learned weights. We can gather them into one huge vector:

θ = [WE, WQ, WK, WV, WO, W1, W2, WU, b, ...]

θ* = arg minθ J(θ)

The training goal is to find parameters that produce lower expected next-token loss.

Notation quick key

In this article, θ means the trainable weights, J means the training objective, means gradient, η means learning rate, and describes the shape of a vector or matrix.

The objective Jis usually the expected next-token loss over the training data. We do not evaluate all possible text at once. We sample batches, calculate a noisy estimate of the loss, and update from that.

J(θ) = E(x,y)∼data [ L(fθ(x), y) ]

B(θ) = (1 / B) Σi=1B L(fθ(xi), yi)

The full objective is estimated with mini-batches because the whole data distribution is too large to evaluate at every step.

That is why people often say training is stochastic. Each batch is a small window into the whole data distribution. The optimizer is always steering from partial evidence.

A scheduler changes the path, not the destination formula

A gradient points downhill for the current batch. It does not say how far to travel. The learning rate supplies that distance, and the scheduler changes it over time.

Two gradient-descent paths on a toy loss surfaceA fixed large learning rate oscillates across the narrow direction while a warmup and decay schedule approaches the minimum more smoothly.minimumwarmup + decayfixed large step
This is a two-parameter quadratic illustration, not an LLM loss map. It isolates one real effect: the same local gradient directions can produce very different paths when the scheduler changes the step size.

The chart uses a simple two-parameter bowl so the path can be drawn. An LLM has billions of parameters and a much less regular surface, but the step-size problem remains. A learning rate that is too large can bounce across a narrow valley or diverge. A very small rate can make safe but painfully slow progress. Warmup and decay try to use different step sizes at different phases.

What the graph does and does not show

The blue and red paths use the same gradient rule on the same toy objective. Only the step-size schedule differs. This demonstrates optimizer dynamics, not the actual geometry of a trained LLM.

From tokens to matrices

Start with a tiny sequence of tokens. The tokenizer turns text into token IDs. The embedding table turns each token ID into a vector.

[t1, t2, t3, ..., tT]

E ∈ ℝV × d_model

X = E[token_ids]

X ∈ ℝT × d_model

The embedding table converts token IDs into learned vectors before the transformer blocks begin.

Here, V is the vocabulary size, Tis the sequence length, and d_modelis the width of each token representation.

Embedding intuition

The embedding table is a dictionary where every token gets coordinates. The word itself is no longer a word inside the model. It is a point in a learned space where nearby directions tend to carry related usage patterns.

The core matrix step: attention

A transformer block uses learned matrices to create queries, keys, and values. This simplified single-head view leaves out multi-head splitting, layer normalization, residual paths, and feed forward layers so the core matrix operation stays visible.

X ∈ ℝT × d_model

WQ ∈ ℝd_model × d_k, WK ∈ ℝd_model × d_k, WV ∈ ℝd_model × d_v

Q = XWQ, K = XWK, V = XWV

Queries, keys, and values are learned projections of the same token representations.

Attention compares every query with every key. The result is a square score matrix. For a decoder-style language model, a causal mask is added before softmax so each position can only use earlier positions and itself.

S = (QKT) / √dk + Mcausal

S ∈ ℝT × T

A = softmax(S)

H = AV

H ∈ ℝT × d_v

The causal mask blocks future-token information before softmax turns scores into attention weights.

The Transformer paper introduced this scaled dot-product attention form. The scaling bysqrt(d_k)keeps dot products from becoming too large, which helps the softmax stay in a useful gradient range.

From hidden state to loss

After several transformer blocks, the model has a hidden vector for each token position. To predict the next token, it maps each valid hidden vector into vocabulary-sized logits.

H ∈ ℝB × T × d_model

WU ∈ ℝd_model × V

Hflat ∈ ℝM × d_model

Z = HflatWU + b

P = softmax(Z)

The output projection maps valid hidden states into one score per vocabulary token.

With tiny numbers, that final projection might look like this:

H_flat = [[0.2, -0.1],
          [0.7,  0.3]]

W_U = [[1.0, -0.5,  0.2],
       [0.4,  0.8, -0.3]]

b = [0.1, 0.0, -0.2]

Z = H_flat W_U + b
Z = [[0.26, -0.18, -0.13],
     [0.92, -0.11, -0.15]]

A logit is an unnormalized score for a token. Softmax converts those scores into probabilities. Here, M is the number of valid next-token prediction positions after padding and ignored positions are removed.

Suppose the three vocabulary columns are [puppy, runs, .], and the two correct targets are [runs, puppy]. Softmax and cross-entropy give:

P = softmax(Z)
P = [[0.4308, 0.2775, 0.2917],
     [0.5882, 0.2100, 0.2018]]

L = -[log(0.2775) + log(0.5882)] / 2
L = 0.9063

Lm = -log P[m, ym]

L = -(1 / M) Σm=1M log P[m, ym]

L = -(1 / M) Σm=1M Σv=1V Y[m,v] log P[m,v]

Cross-entropy gets smaller when the model assigns higher probability to the correct next token.

Lower loss means the model assigned higher probability to the true next tokens in the training batch. The whole training loop exists to change the matrices so this number tends to go down.

A concrete gradient calculation

The cleanest place to see the gradient is the final vocabulary projection. For the flattened valid prediction positions, letY be the one-hot matrix of correct tokens. A useful cross-entropy plus softmax result is:

P = softmax(Z)

Y ∈ ℝM × V

dL / dZ = (P - Y) / M

For softmax plus cross-entropy, the logit gradient has a compact form.

If the correct token should have probability 1 but the model gives it 0.30, that token gets a negative correction. If the model gives too much probability to a wrong token, that wrong token gets a positive correction. The gradient says how the logits should move.

For the two-row example above, the numerical logit gradient is:

G_Z = (P - Y) / 2
G_Z = [[ 0.2154, -0.3613,  0.1458],
       [-0.2059,  0.1050,  0.1009]]

Now apply the matrix derivative for the output matrix:

Z = HflatWU + b

GZ = dL / dZ

dL / dWU = HflatTGZ

dL / db = sum_rows(GZ)

dL / dHflat = GZWUT

The output-layer gradients are matrix products because the forward pass was a matrix product.

This is the key mechanical idea. The model output was made by matrix multiplication, so the correction is also expressed through matrix multiplication. Backpropagation keeps applying the chain rule backward through every matrix, softmax, normalization, residual connection, and feed forward layer.

Applying that multiplication to the toy matrices produces:

dL/dW_U = H_flat^T G_Z

dL/dW_U = [[-0.1010,  0.0012, 0.0998],
           [-0.0833,  0.0676, 0.0157]]

dL/db = [0.0095, -0.2563, 0.2467]

Gradient intuition

The loss is the complaint. The gradient is the annotated route back through the factory, showing which machine settings contributed to the bad output and how each setting should shift.

The optimizer step

Once backpropagation has produced gradients for all parameters, collect them into one gradient object:

θt

gt = ∇θBt)

The gradient object collects the batch-derived update direction for every trainable parameter.

The simplest update is stochastic gradient descent:

θt+1 = θt - ηtgt

The learning rate η_tcontrols the step size. In large transformer training, Adam or AdamW is more common because it keeps moving averages of gradients and squared gradients.

mt = β1mt-1 + (1 - β1)gt

vt = β2vt-1 + (1 - β2)(gt ⊙ gt)

t = mt / (1 - β1t)

t = vt / (1 - β2t)

θt+1 = θt - ηtt / (√v̂t + ε)

Adam keeps first and second moment estimates so each parameter can get an adaptive step size.

Adam changes the effective step per parameter. If one weight has repeatedly noisy or large gradients, its squared-gradient estimate can reduce the step. If another weight has a cleaner direction, it can move more confidently.

AdamW adds decoupled weight decay. Instead of mixing weight decay into the adaptive gradient calculation, it applies parameter shrinkage as a separate part of the update.

θt+1 = (1 - ηtλ)θt - ηtt / (√v̂t + ε)

In AdamW, weight decay is applied separately from the adaptive gradient step.

The practical effect is that the model still follows the gradient, while the optimizer also discourages weights from growing without bound. The AdamW paper is specifically about why this decoupling matters for adaptive optimizers such as Adam.

Training code often excludes bias and normalization parameters from weight decay. AdamW does not decide that policy by itself. Parameter groups in the training recipe decide which tensors receive which learning rate and decay value.

Where schedulers come into play

In image generation, a sampler scheduler often controls a denoising trajectory. In LLM training, the common scheduler is different: it controls the learning rate over training steps.

θt+1 = OptimizerStep(θt, gt, ηt)

ηt = schedule(t)

In LLM training, the scheduler enters through the learning rate used by the optimizer.

The scheduler does not usually decide the gradient direction. Backpropagation does that. The scheduler decides how strongly the optimizer should trust that direction at this stage of training.

Learning-rate scheduler formulas and their training behavior
ScheduleFormula sketchTraining behavior
Constantηt = η0Simple, but can be too aggressive early or too high late.
Linear warmupηt = ηmax · t / w, for t ≤ wStarts cautiously while gradients and optimizer moments stabilize.
Inverse square rootηt ∝ 1 / √tUsed in the original Transformer schedule after warmup.
Linear decay to zeroηt = ηpeak(1 - p)Reduces the rate evenly after warmup and reaches zero at the planned end.
Cosine decayηt ∝ 1 + cos(πp)Stays higher early and bends gently toward a small final rate.
Warmup-stable-decaywarmup, plateau, cooldownKeeps a reusable high-rate training branch, then decays near a chosen endpoint.

After a warmup of wsteps in a run planned to end atT, define post-warmup progress as:

p(t) = (t - w) / (T - w), for w ≤ t ≤ T

ηlinear(t) = ηpeak(1 - p(t))

ηcosine(t) = ηmin + ½(ηpeak - ηmin)(1 + cos(πp(t)))

ηinverse-sqrt(t) = ηpeak√(w / t)

Common decay curves use normalized progress after warmup. The minimum learning rate can be zero or a chosen floor.

Warmup-stable-decay keepsη = η_peakthrough a stable middle phase, then applies a chosen cooldown curve over the final segment. The name describes the phases, not one mandatory cooldown equation.

The original Transformer paper used Adam with a warmup plus inverse-square-root schedule:

ηt = dmodel-0.5 · min(t-0.5, t · warmup_steps-1.5)

The minimum selects warmup behavior early and inverse-square-root decay after warmup.

Before warmup ends, the second term grows linearly with step. After warmup, the first term decays as training progresses. This gives the optimizer a gentle start and then smaller refinement steps.

Normalized learning-rate schedulesFour learning-rate schedules rise during warmup and then use inverse-square-root, cosine, linear, or stable-then-decay behavior.0.00.51.0Normalized training progressLearning rateWarmup + inverse square rootWarmup + cosineWarmup + linear to zeroWarmup-stable-decay
The curves are normalized so their shapes can be compared. Real runs choose a peak learning rate, warmup length, decay floor, and total training horizon.

There is no universally best curve. The original Transformer used inverse-square-root decay. Cosine decay became common in later training recipes. MiniCPM introduced warmup-stable-decay for a training horizon that can be extended before cooldown. A 2025 empirical study reported that, under its tested compute-optimal settings and tuned peak rates, linear decay to zero outperformed the compared tenfold-decay schedules. That result is evidence for a recipe, not a proof for every dataset, model size, optimizer, or fine-tuning run.

Training-speed intuition

The gradient is the steering wheel. AdamW is the suspension system that adapts to rough ground. The scheduler is the speed control: slow at the start, faster when stable, slower again when the car needs precision.

A tiny numerical example

We can now close the loop on the toy output matrix. Hold the hidden states fixed and apply one plain SGD update with learning rate 0.1 toW_U andb.

W_U' = W_U - 0.1(dL/dW_U)
b'   = b   - 0.1(dL/db)

W_U' = [[ 1.0101, -0.5001,  0.1900],
        [ 0.4083,  0.7932, -0.3016]]

b' = [0.0990, 0.0256, -0.2247]

Recompute the logits and probabilities with those updated values:

P' = [[0.4310, 0.2849, 0.2841],
      [0.5911, 0.2142, 0.1947]]

L_before = 0.9063
L_after  = 0.8907

The loss fell for this batch because the step followed its gradient and was small enough. This is a local demonstration, not a guarantee that every batch or validation example improves after every update. In a full model, backpropagation updates all trainable matrices, AdamW rescales the coordinate-wise update, and the scheduler changes the learning rate across training.

Why there is no simple closed-form answer

If this were ordinary linear regression, we could sometimes solve for the best weights with a compact matrix equation. LLMs are different:

  • The model contains many nonlinear operations, including softmax, activation functions, and normalization.
  • The training objective is non-convex, so there are many basins, saddles, and flat regions.
  • The data is sampled in batches, so each gradient is noisy.
  • The model is overparameterized, so many different parameter settings can behave similarly.
  • The goal is useful generalization, not only perfect memorization of the training set.

So the useful mental model is not one grand equation that produces the final LLM. It is an iterative machine: matrix prediction, loss measurement, gradient calculation, optimizer update, scheduled step size, repeat.

Training loss is also not the whole product objective. Teams monitor validation loss, downstream evaluations, safety behavior, calibration, and overfitting. A lower training loss can be mathematically real while the model becomes less useful on data it did not train on.

Sources

This article is a simplified explanation, but the core formulas are grounded in the standard transformer and optimizer literature.

Keep reading

Related articles

All guides
Diagram showing image frames stacking into an increasingly large space-time video payload
TechnicalVideo Models

Why AI Video Is So Much Heavier Than AI Images

Understand why AI video needs more GPU memory and compute than image generation, with tensor math, frame-resolution scaling, temporal attention, and practical cost controls.

14 min readDifficulty 3/5
Chart comparing the bit width and storage intuition of FP32, BF16, FP16, FP8, and INT4
TechnicalInfrastructure

VRAM, Precision, and Quantization: Fitting AI on a GPU

Learn what occupies GPU memory, how numeric precision and quantization change checkpoint size, why weights can fit while inference fails, and how to debug AI out-of-memory errors.

17 min readDifficulty 5/5
How an LLM Finds a Lower-Loss Solution | Movey