How Models Are Actually Trained

Scaling laws and compute-optimal training

With a fixed compute budget you must choose between a bigger model and more training data, and there is a measurable best split between the two.

On this page 9
  1. The short answer
  2. The analogy you have already lived
  3. Why it exists
  4. How it works
  5. The twist that changed practice again
  6. Where you have already seen this
  7. What is honestly hard here
  8. Remember this
  9. What to learn next

One lesson, three depths. Pick the one that fits you today — you can switch any time.

Beginner — No maths. Plain English.

The short answer

With a fixed budget you can build a bigger model or train on more text, not both. Scaling laws tell you the best split.

The analogy you have already lived

You have thirty hours left before an exam and no more. You can spend them reading new chapters, or doing past papers. Nothing else.

Read every chapter and skip all the papers, and you know a lot but cannot apply it. Do papers all thirty hours without reading, and you have nothing to apply.

Somewhere in between is the split that scores highest. Finding that split for language models is what scaling laws do.

Why it exists

Training a large model costs an enormous amount of money and electricity. You get one shot. Choosing badly wastes months.

Before 2022, the accepted answer was "build the biggest model you can afford". Teams poured almost the whole budget into model size and trained on comparatively little text.

Then a team at DeepMind measured it properly. They trained over four hundred models of different sizes on different amounts of text. Then they plotted where the best results actually sat.

The answer surprised everyone. The big models of that era were badly undertrained. They were too large for the amount of text they had read.

How it works

The famous result is a rule of thumb. For each unit of model size, train on roughly twenty units of text.

   the old way (2020)               the measured way (2022)

   HUGE model                       smaller model
   |||||||||||||||||                |||||||
   +                                +
   a little text                    a lot of text
   ....                             ................................

   same cost, worse result          same cost, better result

The team then built a model to test the claim. It was under a third the size of the largest model of that day. It read four times as much text, at equal cost.

It beat the larger model on almost everything. That model was called Chinchilla, and the rule has carried its name since.

The twist that changed practice again

There is a cost the rule ignores. Training happens once. Answering happens forever.

A smaller model is cheaper every single time somebody uses it. If your model will answer a billion questions, a small model that took longer to train is far cheaper overall.

So modern models are deliberately trained on far more text than the rule says. They pay extra at training time to be cheap for the rest of their lives.

That is why a small model today reads trillions of words. The rule asks for a fraction of that.

Where you have already seen this

  • Choosing between a bigger fridge and a cheaper electricity bill.
  • Buying a costlier LED bulb because it saves money every month.
  • Any decision where the one-time price and the running cost pull in opposite directions.

What is honestly hard here

These are measured patterns, not laws of nature. They were fitted to one architecture, one dataset and one training recipe.

Change the data quality and the best split moves. Change the architecture and it moves again. A rule fitted in 2022 is a starting point for 2026, not an answer.

Read that twice. People quote these numbers as though they were physics. They are careful measurements of one setup.

Remember this

  • A fixed budget forces a choice between model size and amount of text.
  • Roughly twenty units of text per unit of model size was the measured best split.
  • Real models today train far past that, because a smaller model is cheaper to run forever.

What to learn next

Developer — Code and libraries.

Setup

bash
python3 --version

Standard library only. Runs instantly.

The compute rule

Training cost in floating-point operations is approximately

C = 6 × N × D

where N is the parameter count and D the number of training tokens. The 6 is 2 for the forward pass and 4 for the backward pass, per parameter per token. Everything below sits on that one equation.

Both published fits, side by side

scaling_laws.py
"""Compute-optimal model size and token count from two published fits of
   L(N, D) = E + A/N^alpha + B/D^beta ."""

# Hoffmann et al. 2022, "Approach 3" (values from the paper's TeX source)
CHINCHILLA = dict(E=1.6934, A=406.4, alpha=0.3392, B=410.7, beta=0.2849)
# Besiroglu et al. 2024, re-fit of the same reconstructed data
EPOCH = dict(E=1.8172, A=482.01, alpha=0.3478, B=2085.43, beta=0.3658)


def loss(N, D, f):
    return f["E"] + f["A"] / N ** f["alpha"] + f["B"] / D ** f["beta"]


def best_split(compute, f):
    """C = 6ND, so sweep N and take D = C/(6N). Return (loss, N, D)."""
    best, n = None, 1e6
    while n < 1e13:
        cand = (loss(n, compute / (6 * n), f), n, compute / (6 * n))
        if best is None or cand[0] < best[0]:
            best = cand
        n *= 1.01
    return best


for name, f in [("Hoffmann et al. 2022 (Approach 3)", CHINCHILLA),
                ("Besiroglu et al. 2024 (re-fit)", EPOCH)]:
    print(f"\n{name}")
    print(f"{'compute':>10} {'params':>11} {'tokens':>12} {'tokens/param':>13} {'loss':>7}")
    for exp in (20, 22, 24, 26):
        L, N, D = best_split(10.0 ** exp, f)
        print(f"{10.0**exp:>10.0e} {N:>11.3g} {D:>12.3g} {D / N:>13.1f} {L:>7.3f}")

print("\n--- how flat is the optimum? (C = 1e23 FLOPs, Chinchilla fit) ---")
C = 1e23
Lopt, Nopt, Dopt = best_split(C, CHINCHILLA)
for mult in (0.1, 0.25, 0.5, 1.0, 2.0, 4.0, 10.0):
    N = Nopt * mult
    D = C / (6 * N)
    print(f"  N = {mult:>5.2f} x optimal -> {N:>9.3g} params, {D:>9.3g} tokens, "
          f"loss {loss(N, D, CHINCHILLA):.4f}  (+{loss(N, D, CHINCHILLA) - Lopt:.4f})")

print("\n--- the inference argument for training a smaller model longer ---")
target = loss(Nopt, Dopt, CHINCHILLA)
for mult in (1.0, 0.5, 0.25):
    N = Nopt * mult
    d, step = 1e10, 1.01                       # grow D until this N matches the target loss
    while loss(N, d, CHINCHILLA) > target and d < 1e16:
        d *= step
    print(f"  N = {N:>9.3g}: needs D = {d:>9.3g} tokens ({d / N:>6.0f}/param), "
          f"train cost {6 * N * d / C:>5.2f}x, each generated token costs {mult:.2f}x")
Output
Hoffmann et al. 2022 (Approach 3)
   compute      params       tokens  tokens/param    loss
     1e+20     7.7e+08     2.16e+10          28.1   2.553
     1e+22    6.35e+09     2.62e+11          41.3   2.115
     1e+24    5.18e+10     3.22e+12          62.0   1.900
     1e+26    4.23e+11     3.94e+13          93.1   1.795

Besiroglu et al. 2024 (re-fit)
   compute      params       tokens  tokens/param    loss
     1e+20    8.51e+08     1.96e+10          23.0   2.553
     1e+22    9.09e+09     1.83e+11          20.2   2.141
     1e+24    9.61e+10     1.74e+12          18.1   1.960
     1e+26    1.02e+12     1.64e+13          16.2   1.880

--- how flat is the optimum? (C = 1e23 FLOPs, Chinchilla fit) ---
  N =  0.10 x optimal ->  1.81e+09 params,  9.23e+12 tokens, loss 2.0711  (+0.0826)
  N =  0.25 x optimal ->  4.51e+09 params,  3.69e+12 tokens, loss 2.0172  (+0.0287)
  N =  0.50 x optimal ->  9.03e+09 params,  1.85e+12 tokens, loss 1.9955  (+0.0070)
  N =  1.00 x optimal ->  1.81e+10 params,  9.23e+11 tokens, loss 1.9885  (+0.0000)
  N =  2.00 x optimal ->  3.61e+10 params,  4.62e+11 tokens, loss 1.9952  (+0.0067)
  N =  4.00 x optimal ->  7.22e+10 params,  2.31e+11 tokens, loss 2.0154  (+0.0270)
  N = 10.00 x optimal ->  1.81e+11 params,  9.23e+10 tokens, loss 2.0638  (+0.0754)

--- the inference argument for training a smaller model longer ---
  N =  1.81e+10: needs D =  9.25e+11 tokens (    51/param), train cost  1.00x, each generated token costs 1.00x
  N =  9.03e+09: needs D =  2.24e+12 tokens (   248/param), train cost  1.21x, each generated token costs 0.50x
  N =  4.51e+09: needs D =   1.1e+13 tokens (  2442/param), train cost  2.98x, each generated token costs 0.25x

Pure arithmetic — deterministic and identical on any machine.

This output contains the whole subject

The two published fits disagree, and the disagreement matters. Hoffmann's Approach-3 coefficients imply the tokens-per-parameter ratio grows with budget: 28, then 41, then 62, then 93. That contradicts the same paper's headline conclusion, drawn from its other two methods, that model size and tokens should scale equally.

Besiroglu et al. re-fitted the same reconstructed data and got a near-constant ratio: 23, 20, 18, 16. That is the "scale equally" conclusion, and it is where the familiar "20 tokens per parameter" comes from.

The lesson is not that one is wrong. It is that "the Chinchilla law" refers to three different estimates in one paper, and the widely-copied coefficients are the ones that reproduce worst. If you are quoting them, quote which.

The optimum is remarkably flat. Halve the model and hold compute fixed, and the loss rises by 0.007. Even a 4× error in model size costs 0.027. That flatness is why a large amount of published disagreement about the exact ratio has almost no practical consequence.

The final block is why nobody trains at the optimum any more. Halving the model needs 1.21× the training compute to reach the same loss — and then costs half as much for every token it will ever generate. Quarter the model, pay 2.98× at training, pay a quarter forever. For a model serving real traffic that trade is worth making, and every deployed model reflects it.

Applying it to your own budget

python
def plan(gpu_hours, gpu_flops_per_sec, utilisation=0.4, tokens_per_param=20):
    C = gpu_hours * 3600 * gpu_flops_per_sec * utilisation
    # C = 6 * N * D  with  D = r * N   gives   N = sqrt(C / (6r))
    N = (C / (6 * tokens_per_param)) ** 0.5
    return C, N, tokens_per_param * N

C, N, D = plan(gpu_hours=1000, gpu_flops_per_sec=3.0e14)   # ~one H100-week, bf16
print(f"budget {C:.2e} FLOPs -> {N/1e6:.0f}M params on {D/1e9:.1f}B tokens")
Output
budget 4.32e+20 FLOPs -> 1897M params on 37.9B tokens

The utilisation=0.4 is doing real work in that number. Model FLOPs utilisation of 40–50% is a good real-world figure for a well-tuned run; assuming 100% overstates your budget by more than double.

Common mistakes

Counting embedding parameters in N. Chinchilla's N is non-embedding parameters. For a small model with a large vocabulary, embeddings can be a third of the total, and including them shifts your plan badly.

Treating the ratio as universal. DeepSeek (Bi et al., 2024) found the optimal ratio depends on data quality — higher-quality data favours a smaller ratio. Your corpus is not their corpus.

Ignoring memory. Scaling laws say nothing about whether the model fits. A compute-optimal 70B model needs roughly 1.1 TB of GPU memory for weights, gradients and Adam states in mixed precision. See GPU memory anatomy.

Extrapolating a fit far outside its range. Chinchilla's models spanned 70M to 16B parameters. Predictions at 1T are extrapolations of two orders of magnitude.

Assuming loss predicts capability. The law predicts loss. It does not predict whether the model can do arithmetic. See perplexity for why that link is weaker than it looks.

Try it yourself

Set tokens_per_param=200 in plan() and recompute. That is roughly where a modern open-weights model sits. Notice how much smaller N becomes for the same budget — and that this is a deliberate choice, not a mistake.

What to learn next

Researcher — Mathematics and papers.

The parametric form

$$ L(N, D) = E + \frac{A}{N^{\alpha}} + \frac{B}{D^{\beta}} $$

$N$ is non-embedding parameter count, $D$ training tokens. $E$ is the irreducible loss — the entropy of natural text under this tokeniser, which no model can beat. $A/N^\alpha$ is the penalty for finite capacity; $B/D^\beta$ the penalty for finite data. The additive separable form is an assumption, not a derivation, and it is the form's main weakness.

Kaplan et al., 2020 (Scaling Laws for Neural Language Models) established the power-law behaviour and concluded model size should grow far faster than data: $N \propto C^{0.73}$, $D \propto C^{0.27}$.

Hoffmann et al., 2022 (Training Compute-Optimal Large Language Models) corrected this with over 400 runs and three independent methods, finding $N \propto C^{0.50}$, $D \propto C^{0.50}$. The discrepancy was traced largely to Kaplan et al. using a fixed cosine schedule length across all token counts, and to counting embedding parameters — both of which bias against long training runs.

Under the Hoffmann analysis the optimal allocation satisfies

$$ N_{\text{opt}} \propto C^{a},\quad D_{\text{opt}} \propto C^{b},\quad a = \frac{\beta}{\alpha+\beta},\quad b = \frac{\alpha}{\alpha+\beta} $$

so the tokens-per-parameter ratio is constant in $C$ only when $\alpha = \beta$. This is the crux of the replication dispute below.

The replication problem, in numbers

Besiroglu et al., 2024 (Chinchilla Scaling: A replication attempt, Epoch AI) reconstructed the data from Hoffmann's Figure 4 and refitted Approach 3:

Fit$E$$A$$\alpha$$B$$\beta$$D/N$ behaviour
Hoffmann Approach 31.6934406.40.3392410.70.2849grows with $C$
Besiroglu re-fit1.8172482.010.34782085.430.3658roughly constant ≈ 20

Their three findings: Hoffmann's Approach-3 estimates are inconsistent with its own Approaches 1 and 2; they fit the reconstructed data poorly; and the reported confidence intervals are implausibly narrow — tight enough to require over 600,000 runs against roughly 400 actually performed. They attribute the discrepancy to an optimiser stopping short of convergence and to rounding in the published coefficients.

The practical takeaway: use the Besiroglu coefficients if you want a fit consistent with the paper's own headline conclusion, and treat any downstream theory built on the original Approach-3 exponents with care.

Overtraining, and the inference-aware law

Compute-optimal minimises training FLOPs for a target loss. Sardana et al., 2024 (Beyond Chinchilla-Optimal: Accounting for Inference in Language Model Scaling Laws) minimise training plus lifetime inference instead. With $D_{\text{inf}}$ tokens expected to be generated over the model's life, the objective becomes

$$ \min_{N, D_{\text{tr}}} \; 6 N D_{\text{tr}} + 2 N D_{\text{inf}} \quad \text{s.t.} \quad L(N, D_{\text{tr}}) = \ell $$

The $2N$ per inference token is the forward-pass cost. For realistic serving volumes the solution is substantially smaller and substantially more overtrained than Chinchilla — matching what Llama 3 8B (15T tokens, ~1900 tokens/param) and similar models actually do.

Distillation shifts the same trade further, and knowledge distillation scaling laws (Busbridge et al., 2025) give the analogous frontier for teacher–student pairs. See distilling a large model into a small one.

Data-constrained scaling

The additive form implies unlimited benefit from unlimited data. Data is finite. Muennighoff et al., 2023 (Scaling Data-Constrained Language Models) trained on repeated data up to 900B tokens and found:

  • Up to roughly 4 epochs, repeated tokens are nearly as valuable as fresh ones.
  • Beyond that, the marginal value decays quickly toward zero.
  • Their extension replaces $D$ with an effective token count $D'$ that saturates in the number of repetitions.

This is the standard reference for anyone whose corpus is smaller than their compute budget.

Where the framework is weakest

  • Fitted to one setup. One architecture family, one tokeniser, one optimiser, one data mixture. Changing the mixture changes $E$ directly.
  • Data quality is unmodelled. Bi et al., 2024 (DeepSeek LLM) show the optimal allocation shifts toward smaller models as data quality rises. There is no quality term in the equation.
  • Loss is not capability. The law predicts $L$; downstream accuracy is a separate, noisier mapping. See Schaeffer et al., 2023 on the metric artefacts in that mapping.
  • MoE breaks the parameter count. For a mixture-of-experts model, active parameters and total parameters differ, and $6ND$ needs the active count while capacity tracks the total. Separate scaling laws exist for MoE and the dense law does not transfer.
  • The optimum is flat. As the code showed, a 2× error costs under 0.01 nats. Precision in these coefficients is worth far less than it appears.

Papers

What to learn next