Index Ai Academy
Phase 5 · Transformers · Scale & inference

Scaling laws

How loss falls predictably with size, data and compute.

About 35 minutes · A free account opens the whole lesson

Create a free account Try part of it here

Already have an account? Sign in to open this lesson

Why it matters

Scaling laws are a big part of why AI moved so fast. They showed that bigger models trained on more data get better by an amount you can predict in advance. That made it reasonable to spend hundreds of millions of dollars on a single training run. They also explain choices behind the models you can buy. They show why small models trained on huge amounts of text are so capable and cheap to run. And they hint at what could slow progress down.

What you'll be able to do

  • Explain what a scaling law is: loss falling as a power law in parameters, data and compute
  • Use the Chinchilla result to split a compute budget between model size and training tokens
  • Fit a power law to small runs and extrapolate it, the way labs plan large runs
  • Explain why today's models are often trained far past the 'compute-optimal' point

What it covers

  1. Bigger, better, by a predictable amount
  2. The Chinchilla formula
  3. The real numbers
  4. Spending a compute budget
  5. Worked example: plan a run with the 20-to-1 rule
  6. Predicting a big run from small ones
  7. Beyond compute-optimal

Bigger, better, by a predictable amount

Think about learning to type. Your first hour of practice makes a big difference. Your tenth hour helps less. By your hundredth hour, each extra hour adds only a little. You keep improving, but each step of progress costs more than the last.

Language models improve in a similar way, and the pattern is strikingly regular. In 2020, a team at OpenAI (Kaplan and colleagues) trained hundreds of language models. They changed three things from run to run:

  • the number of parameters, written NN: the adjustable numbers inside the model;
  • the number of training tokens, written DD: how much text the model reads;
  • the compute, written CC: the total work spent on training, counted in FLOPs (floating-point operations, from the last lesson).

Each time, they measured the test loss. That's the cross-entropy you met earlier: how surprised the model is by text it hasn't seen. Lower is better. The loss fell along a smooth curve as each of the three grew. It held across a huge range of sizes, as long as none of the three was holding the others back. A rule like this is called a scaling law.

Power laws

The curve they found has a name: a power law. Here is its simplest form:

y=axby = \frac{a}{x^{b}}

Here xx is the thing you add more of, such as parameters. The letter yy is what you measure, such as loss. The number aa sets the starting size. The exponent bb sets how fast yy falls. You'll also see this written as y=ax−by = a x^{-b}, which means the same thing.

In plain words: each time you multiply xx by the same amount, yy shrinks by the same fraction.

Try it with small numbers. Take a=100a = 100 and b=0.5b = 0.5. Raising a number to the power 0.5 means taking its square root, so yy is 100 divided by the square root of xx.

  • At x=1x = 1: 100 ÷ 1 = 100.
  • At x=4x = 4: 100 ÷ 2 = 50.
  • At x=16x = 16: 100 ÷ 4 = 25.

Every 4× in xx cuts yy in half. The first 4× saves 50. The next 4× saves only 25. Equal steps, smaller and smaller gains: that's diminishing returns in one formula.

a, b = 100, 0.5
for x in [1, 4, 16, 64]:
    print(x, a / x**b)
It runs right here in your browser, with nothing to install.

On an ordinary chart this curve swoops down, then flattens out. Researchers usually draw it on a log-log plot instead. On both axes, each step is ten times the one before: 1, 10, 100, 1,000. On a log-log plot a power law is a straight line. That makes it easy to spot and easy to extend.

Go deeper Why a power law is a straight line on a log-log plot

Take the logarithm of both sides of y=ax−by = a x^{-b}. Logs turn multiplying into adding, and powers into multiplying (from the exponentials and logarithms lesson):

log⁡y=log⁡a−blog⁡x\log y = \log a - b \log x

Read it as: log⁡y\log y equals a fixed starting value, log⁡a\log a, minus bb times log⁡x\log x. That's the equation of a straight line with slope −b-b. A log-log plot draws log⁡x\log x across and log⁡y\log y up, so you see that line. It's also how you'll fit a power law in the exercise: fit a straight line to the logs, and the slope gives you the exponent.

Quick check
A power law has a = 100 and b = 0.5. What does this print?
a, b = 100, 0.5
print(a / 100**b)
  1. 1.0
  2. 10.0
  3. 50.0
  4. 0.5
Show the answer

10.0

100 to the power 0.5 is the square root of 100, which is 10. Then 100 ÷ 10 = 10.0. Going from x = 1 to x = 100 cut y from 100 to 10.

The Chinchilla formula

In 2022, a team at DeepMind (Hoffmann and colleagues) wrote one formula for loss that covers both model size and data. Their best model was called Chinchilla, and the formula usually goes by that name too:

L(N,D)=E+ANα+BDβL(N, D) = E + \frac{A}{N^{\alpha}} + \frac{B}{D^{\beta}}

Take it one piece at a time.

  • L(N,D)L(N, D) is the loss for a model with NN parameters trained on DD tokens.
  • EE is the irreducible loss: the floor. Some text is unpredictable however good the reader is, so no model can get below it.
  • ANα\frac{A}{N^{\alpha}} is the size penalty: extra loss because the model is too small. AA is a number fitted from the experiments. The exponent α\alpha (the Greek letter alpha) sets how fast the penalty shrinks as the model grows.
  • BDβ\frac{B}{D^{\beta}} is the data penalty: extra loss because the model saw too little text. BB is another fitted number. The exponent β\beta (beta) sets how fast this penalty shrinks as the data grows.

In plain words: loss = the floor + a penalty for too few parameters + a penalty for too little data. Each penalty is a power law. It shrinks as you add more, but never quite reaches zero.

Here's a worked example with made-up, easy numbers. Say E=2E = 2, A=10A = 10 and B=20B = 20, and both exponents are 0.5. Take a model with 100 parameters trained on 400 tokens.

  • Size penalty: 10 ÷ √100 = 10 ÷ 10 = 1.
  • Data penalty: 20 ÷ √400 = 20 ÷ 20 = 1.
  • Loss: 2 + 1 + 1 = 4.

Now make the model 100 times bigger, with 10,000 parameters. The size penalty drops to 10 ÷ 100 = 0.1. The data penalty stays at 1, so the loss is 3.1. Most of what's left above the floor is now the data penalty. Adding more parameters can't fix that.

E = 2
A, alpha = 10, 0.5
B, beta = 20, 0.5
D = 400
data_penalty = B / D**beta
for N in [100, 10_000]:
    size_penalty = A / N**alpha
    print(N, size_penalty, data_penalty, E + size_penalty + data_penalty)
Try it now

The Chinchilla advice is about 20 tokens per parameter. Slide the ratio: the same budget buys a bigger model trained on less, or a smaller one trained on more.

The real numbers

The values below come from a 2024 re-check of the Chinchilla analysis by Epoch AI. The loss is in nats per token (the unit from the cross-entropy lesson), measured on the paper's own dataset. So compare these numbers with each other, not with other models.

import matplotlib.pyplot as plt
import numpy as np

E, A, B, alpha, beta = 1.82, 482.01, 2085.43, 0.3478, 0.3658

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

print("model size (data fixed at 1.4 trillion tokens)")
for N in [1e8, 1e9, 1e10, 1e11, 1e12]:
    print(f"  {N:7.0e} parameters   loss {loss(N, 1.4e12):.3f}")
print("training data (model fixed at 70 billion parameters)")
for D in [1e10, 1e11, 1e12, 1e13, 1e14]:
    print(f"  {D:7.0e} tokens       loss {loss(70e9, D):.3f}")

N = np.logspace(8, 12, 50)
plt.loglog(N, A / N**alpha, label="size penalty A / N^α")
plt.loglog(N, loss(N, 1.4e12) - E, label="loss above the floor (D = 1.4T)")
plt.xlabel("parameters")
plt.ylabel("loss above E")
plt.legend()

In the printout, 1e+09 means 1 followed by 9 zeros: a billion. Read the first table from the top. Each 10× in model size helps less than the one before. The loss drops by 0.44, then 0.20, then 0.09, then 0.04. Each 10× cuts the size penalty to about 45% of what it was.

On the chart, the size penalty alone is a straight line: a power law. The total loss above the floor bends flat on the right. There, the fixed data penalty is most of what's left. The numbers teach two things. Each 10× of size or data buys a smaller gain than the last. And growing only one of them stalls.

Quick check
In the real Chinchilla formula, keep the data fixed at 1.4 trillion tokens and keep making the model bigger. What happens to the loss?
  1. It keeps falling by the same amount for every 10×
  2. It falls to exactly E, 1.82
  3. It levels off near 1.9: the floor E plus the data penalty that stays put
  4. It falls all the way to zero
Show the answer

It levels off near 1.9: the floor E plus the data penalty that stays put

A bigger model only shrinks the size penalty. With 1.4 trillion tokens the data penalty is about 0.075, so the loss can't go below about 1.82 + 0.075 ≈ 1.9.

Spending a compute budget

Compute is the real limit. It costs money and time on GPUs, the chips that train models. From the last lesson, training compute is roughly:

C≈6NDC \approx 6ND

In plain words: training compute is about 6 × parameters × tokens. Each parameter does about 6 calculations for every token the model trains on.

For example, a tiny model with 1,000 parameters trained on 50 tokens needs about 6 × 1,000 × 50 = 300,000 FLOPs. The worked example further down does the same sum for a real model.

So with a fixed budget, a bigger model means fewer tokens. It's like a fixed tank of fuel for a road trip: a bigger car goes fewer miles. Which split of the budget gives the lowest loss?

The code below tries 6,001 model sizes, from 10 million to 10 trillion parameters. It gives each one the tokens the budget can pay for, then keeps the size with the lowest loss.

import numpy as np

E, A, B, alpha, beta = 1.82, 482.01, 2085.43, 0.3478, 0.3658

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

def compute_optimal(C):
    N = np.logspace(7, 13, 6001)          # candidate model sizes
    D = C / (6 * N)                        # the tokens each one can afford
    best = loss(N, D).argmin()
    return N[best], D[best]

for C in [1e21, 1e23, 1e25]:
    N, D = compute_optimal(C)
    print(f"budget {C:.0e} FLOPs: {N:.1e} parameters, {D:.1e} tokens ({D / N:.0f} tokens per parameter)")

print("\nSame budget, two choices:")
print(f"  Gopher:     280B parameters, 300B tokens   loss {loss(280e9, 300e9):.3f}")
print(f"  Chinchilla:  70B parameters, 1.4T tokens   loss {loss(70e9, 1.4e12):.3f}")

The answer: grow size and data together, at roughly 20 tokens per parameter. The best split is called compute-optimal.

Before Chinchilla, labs had been making models bigger without adding much data. DeepMind's own Gopher had 280 billion parameters and read 300 billion tokens. It was badly undertrained. Chinchilla was a quarter of the size and read 4.7× as much data, for about the same compute. It beat Gopher across the board, and it was cheaper to run.

Worked example

Worked example: plan a run with the 20-to-1 rule

Gopher's budget was 6 × 280 billion parameters × 300 billion tokens. Keep that budget, but follow the rule of about 20 tokens per parameter. How big should the model be, and how many tokens should it read?

import math

C = 6 * 280e9 * 300e9        # Gopher's budget: 6 × parameters × tokens
N = math.sqrt(C / 120)       # the size that gets 20 tokens per parameter
D = 20 * N                   # tokens
print(f"budget {C:.1e} FLOPs")
print(f"{N:.1e} parameters, {D:.1e} tokens")
print(f"check: 6 × N × D = {6 * N * D:.1e}")
In the lesson you can change this and run it.

If the tokens are 20 × the parameters, the budget is 6 × N × 20N, which is 120 × N × N. So N is the square root of the budget divided by 120. That gives about 65 billion parameters and 1.3 trillion tokens. The last line confirms it spends the whole budget. Chinchilla itself used 70 billion parameters and 1.4 trillion tokens, very close. The rule of 20 is a rule of thumb: the exact best ratio shifts a little with the budget. The budget printout above found 17 to 22 tokens per parameter.

Quick check
A lab has a fixed compute budget. According to Chinchilla, what's a better plan than doubling the model size?
  1. Keep the data fixed and make the model as large as the budget allows
  2. Grow model size and training tokens together, around 20 tokens per parameter
  3. Use as much data as possible with the smallest model
  4. Train the same model for more epochs on the same data
Show the answer

Grow model size and training tokens together, around 20 tokens per parameter

Both penalty terms matter, so the best split grows N and D together.

Predicting a big run from small ones

A baker trying a new cake for a wedding bakes a few small test cakes first. Labs do the same with scaling laws. They train a series of small models and fit the curve to the results. Then they predict how a run 1,000 times larger will turn out, before paying for it. OpenAI's GPT-4 technical report says its final loss was predicted from runs that used up to 10,000 times less compute.

Here is the idea with six pretend small runs. The code makes up their final losses from a hidden law, plus a little random noise. The law has the same shape as before: a floor plus a power-law penalty, now in terms of compute CC. (Dividing by 101810^{18} keeps the numbers a handy size.) Then curve_fit, from the SciPy library, finds the floor, the size and the exponent that best match the six losses.

import numpy as np
from scipy.optimize import curve_fit

def law(C, E, a, b):
    return E + a * (C / 1e18) ** (-b)

# pretend these are the final losses of six small training runs (a hidden law plus noise)
rng = np.random.default_rng(0)
small = np.logspace(17, 19, 6)
measured = law(small, 1.9, 1.2, 0.15) * (1 + rng.normal(0, 0.005, len(small)))

(E, a, b), _ = curve_fit(law, small, measured, p0=[2, 1, 0.1])
print(f"fitted law: loss = {E:.2f} + {a:.2f} × (C / 10^18)^-{b:.3f}")
for C in [1e19, 1e21, 1e23]:
    print(f"compute {C:.0e}: predicted {law(C, E, a, b):.3f}   true {law(C, 1.9, 1.2, 0.15):.3f}")

The fit only saw runs up to 101910^{19} FLOPs. Even so, it predicts the loss at 102310^{23}, 10,000 times further out, to within 0.01. Real predictions are noisier than this, but the method is the same.

Beyond compute-optimal

"Compute-optimal" gives the lowest loss for a given training budget. But a model is trained once and then used billions of times. A smaller model is cheaper for every one of those requests. So labs now overtrain small models, far past 20 tokens per parameter. Meta trained Llama 3's 8-billion-parameter model on about 15 trillion tokens. That's nearly 2,000 tokens per parameter. Its loss kept improving long past the Chinchilla point, only more slowly.

Some caveats worth knowing:

  • Loss isn't ability. Scaling laws predict loss. But specific skills can seem to switch on suddenly at some size. These are called "emergent abilities". Researchers still debate how much of that suddenness comes from scoring. Many benchmarks mark an answer fully right or fully wrong, with no partial credit.
  • Data may run out. Some estimates suggest high-quality public text could be largely used up within a few years at current growth. That's why labs invest in synthetic data, better filtering and other sources.
  • Other things scale too. Reasoning models (Phase 1's thinking effort) show that spending more compute at answer time also improves results predictably. Thinking longer is a second way to scale, on top of training.

For marketers: when a vendor's small model matches last year's large one, overtraining is often the reason. It's the same design, trained on far more data per parameter, at a much lower price per call.

Quick check
Llama 3's 8-billion-parameter model read about 15 trillion tokens. What does this print, and how does it compare with Chinchilla's 20 tokens per parameter?
print(round(15e12 / 8e9))
  1. 1875: roughly 90 times the compute-optimal ratio
  2. 187500: about 10,000 times the compute-optimal ratio
  3. 2: far less data than compute-optimal
  4. 20: exactly compute-optimal
Show the answer

1875: roughly 90 times the compute-optimal ratio

15 trillion ÷ 8 billion = 1,875 tokens per parameter, which prints as 1875, and 1,875 ÷ 20 is about 94, roughly 90 times the compute-optimal ratio. That's overtraining: extra training compute buys a small model that's cheap to run.

Practice what you just read

  • 6 code examples you can edit and run
  • a practice exercise that checks your code
  • a 5-question quiz
  • 5 review cards for spaced repetition

Create a free account

Try a quiz question

What does the E term in L(N, D) = E + A/N^α + B/D^β represent?

  1. The irreducible loss: unpredictability in the text that no model can remove
  2. The error from having too few parameters, which shrinks as N grows
  3. The error from having too little data, which shrinks as D grows
  4. The learning rate, which sets how fast the other terms can shrink

Answer it at the end of the lesson to see if you're right, and why.

Before this lesson