ml-models / Language models / Pretraining and scaling laws advanced

Pretraining and scaling laws

Before a language model can follow instructions it reads trillions of tokens and learns to predict them. This page covers the three pretraining objectives, how the training data is mixed and deduplicated, why training costs about 6 FLOPs per parameter per token, the Kaplan and Chinchilla scaling laws, how to size a model for a compute budget, and why "emergent" abilities need care.

On this page
  1. Problem
  2. Intuition
  3. Mechanics
  4. Pretraining objectives
  5. Data mixtures and deduplication
  6. Compute: C ≈ 6 · N · D, derived
  7. The Kaplan scaling laws
  8. The Chinchilla scaling laws
  9. Beyond compute-optimal
  10. Emergent abilities, and caveats
  11. Worked example
  12. How many targets each objective gets
  13. Six FLOPs per parameter per token
  14. Sizing a model for Chinchilla's budget
  15. A mixture and its epochs
  16. Finding near-duplicates with MinHash
  17. A smooth metric that looks emergent
  18. Implementation
  19. Tradeoffs
  20. Connections
  21. Read first
  22. Read next
  23. References

Problem

A decoder-only language model is a stack of transformer blocks with a next-token head. Its architecture is settled in a page; what makes it useful is pretraining: running it over a huge unlabelled corpus with a self-supervised objective, so that the targets come from the text itself and no human labels are needed. Everything later, fine-tuning, preference training and prompting, starts from the weights pretraining produces.

Pretraining is also by far the most expensive step: months on thousands of accelerators. Before spending that, a team must decide how big the model should be, how many tokens to train it on, and what text those tokens come from. Getting the split between parameters and tokens wrong wastes a large share of the budget, and the only way to decide it in advance is to measure how loss falls on small runs and extrapolate. Those measurements are the scaling laws.

Intuition

Predicting the next word of arbitrary text well requires knowing grammar, facts, arithmetic, code and how arguments go, so a model that gets good at it learns all of those as a side effect. The loss is just cross-entropy on the next token, averaged over every position of every document.

That loss falls smoothly and predictably as the model, the data and the compute grow, following a power law: each tenfold increase buys roughly the same fractional improvement. Because it is so regular, a few small training runs can predict the loss of a run a thousand times larger. The open question is how to spend a fixed budget. A bigger model learns more per token but costs more per token; at a fixed number of FLOPs, more parameters means fewer tokens. There is a best size for every budget, and the two landmark papers on it disagree about where it is.

Three pretraining objectives on one sentence The sentence "Thank you for inviting me to your party last week ." as 11 tokens, three ways. Causal LM: every token is input and the target under each position is the next token, 10 targets in all. Masked LM: "for" and "last" are replaced by a mask token and are the only targets, and the model sees words on both sides. Span corruption: the spans "for inviting" and "last" are each replaced by one sentinel, giving the input "Thank you <X> me to your party <Y> week .", and the target is "<X> for inviting <Y> last <Z>". causal LM Thank you you for for inviting inviting me me to to your your party party last last week week . . input target masked LM Thank you [MASK] for inviting me to your party [MASK] last week . input target span corruption Thank you <X> me to your party <Y> week . <X> for inviting <Y> last <Z> encoder in decoder out causal: 10 targets · masked: 15% of positions · span: 3 corrupted tokens, a 6-token target

Mechanics

Pretraining objectives

Causal language modelling is what GPT-style models use. Under a causal attention mask, position i sees tokens 1…i and predicts token i + 1, so one forward pass over n tokens yields n − 1 training targets, every token but the first. The loss is the mean cross-entropy over them; its exponential is the perplexity. Because the model only ever looks left, the same network generates text one token at a time with no change.

Masked language modelling is BERT's objective for encoder-only models. 15% of positions are picked; of those, 80% are replaced by a [MASK] token, 10% by a random token and 10% left unchanged, so that the model cannot rely on [MASK] appearing at fine-tuning time. The loss covers only the picked positions. The model sees both sides of every gap, which gives better representations for classification and retrieval, but it learns from only 15% of the tokens it reads and cannot generate text left to right.

Span corruption is T5's objective for encoder-decoder models. Contiguous spans covering about 15% of tokens are each replaced by one sentinel token; the decoder outputs each sentinel followed by the tokens it hid. With an average span length of 3, inputs and targets are both shorter than the original text, which makes the objective cheap. Later work such as UL2 mixes several such denoisers with causal LM; today's largest models almost all use plain causal LM because one objective then serves both pretraining and generation.

Data mixtures and deduplication

A pretraining corpus is a mixture of sources: filtered web crawl, code, books, scientific papers, encyclopedias, forums. Each gets a sampling weight, chosen by small ablation runs, and the weight times the token budget sets how many times each source is read. Small high-quality sources are typically upweighted and so repeated for several epochs while the web is not even read once. Muennighoff and colleagues found that repeating data up to about 4 epochs is almost as good as fresh data, with returns falling quickly after that.

Web text is full of duplicates: mirrors, boilerplate, templated pages. Duplicates waste compute, increase memorization of the repeated text, and leak test sets into training. Exact deduplication hashes each document, or each long substring, and drops repeats. Near-duplicate detection uses MinHash: split each document into overlapping word n-grams (shingles) and measure similarity as the Jaccard index |A ∩ B| / |A ∪ B| of the shingle sets. For a random hash function, the probability that two sets have the same minimum hash equals their Jaccard index, so k hash functions give a k-number signature whose agreement rate estimates the similarity. Comparing every pair is still quadratic, so locality-sensitive hashing cuts each signature into b bands of r rows and only compares documents that match exactly on some band. A pair with similarity s becomes a candidate with probability 1 − (1 − sr)b, an S-shaped curve whose threshold sits near (1/b)1/r. Quality filters (language ID, heuristics, classifiers trained to spot reference-quality text) and removal of personal data and benchmark text run alongside.

Compute: C ≈ 6 · N · D, derived

Almost all of a transformer's arithmetic is matrix multiplication by its weights. Take one linear layer with a weight W of shape fin × fout applied to D tokens. Multiplying an (D × fin) input by W takes D · fin · fout multiply-adds, which is 2 · D · fin · fout FLOPs: 2 FLOPs per parameter per token in the forward pass. Backpropagation needs two more products of the same size: the gradient with respect to the input, ∂L/∂X = ∂L/∂Y · Wᵀ, to pass back to the previous layer, and the gradient with respect to the weight, ∂L/∂W = Xᵀ · ∂L/∂Y, for the update. That is 4 more FLOPs per parameter per token, 6 in total. Summed over every weight matrix:

C ≈ 6 · N · D FLOPs (N parameters, D training tokens)

Kaplan and colleagues add the attention scores, which multiply activations by activations rather than by weights: about 2 · nlayer · nctx · dmodel extra forward FLOPs per token, small next to 2N unless the context is much longer than dmodel. Embedding lookups are not multiplications and are usually excluded from N, as is the optimizer's elementwise update. The formula ignores activation recomputation (which adds another forward pass) and counts useful work only; dividing it by hardware peak gives a lower bound on time, and the achieved fraction of peak is the model FLOPs utilization, or MFU.

For a GPT-style block with model width d, attention has four d × d projections (Q, K, V, output), 4d2 parameters, and an MLP with hidden width 4d has 8d2: about 12 · nlayer · d2 non-embedding parameters in all.

The Kaplan scaling laws

Kaplan and colleagues (OpenAI, 2020) trained models from under a million to over a billion parameters and found that test loss follows a power law in each resource when the others are not the bottleneck:

L(N) = (N_c / N)^{α_N}, α_N ≈ 0.076, N_c ≈ 8.8 × 1013    L(D) = (D_c / D)^{α_D}, α_D ≈ 0.095, D_c ≈ 5.4 × 1013

with N counting non-embedding parameters, D in tokens and L in nats per token on their WebText2 data. The shape of the architecture (depth versus width) mattered far less than N. Fitting how the best model for each compute budget grows, they found that model size should grow much faster than data, Nopt ∝ C0.73, so most of any extra compute should go into a bigger model trained on relatively few more tokens. GPT-3, with 175B parameters trained on about 300B tokens, followed that advice.

The Chinchilla scaling laws

Hoffmann and colleagues (DeepMind, 2022) trained over 400 models from 70M to 16B parameters and reached a different answer. One key difference: Kaplan's runs used a learning-rate schedule of the same length regardless of how many tokens a run would actually use, which understates what small models reach on long training. Chinchilla tuned the cosine schedule to each run's length, and used three methods to locate the best size. The third fits one formula for loss as a function of both N and D:

L(N, D) = E + A / N^α + B / D^β, E = 1.69, A = 406.4, B = 410.7, α = 0.34, β = 0.28

E is the irreducible loss of the data, the entropy of text that no model can remove; the other two terms are the penalties for a finite model and finite data. To find the best size for a budget, substitute D = C/(6N) and set the derivative with respect to N to zero. That gives αA/Nα = βB/Dβ, and solving:

N_opt = G · (C/6)^a, D_opt = G⁻¹ · (C/6)^b, a = β/(α + β), b = α/(α + β), G = (αA / (βB))^{1/(α+β)}

With the fitted values, a = 0.45 and b = 0.55; the other two methods gave a and b both close to 0.5. Either way, parameters and tokens should grow at about the same rate, roughly equally for each tenfold more compute. The widely used summary is about 20 tokens per parameter, which turns C = 6 · N · 20N into N = √(C / 120). By that measure GPT-3 and Gopher were far too large for their data, and Chinchilla, at 70B parameters on 1.4T tokens with the budget of 280B-parameter Gopher, beat it on almost every benchmark.

Beyond compute-optimal

Chinchilla-optimal minimizes training compute for a target loss, but a deployed model's cost is dominated by inference, which scales with N and the number of tokens served. A smaller model trained on far more tokens than 20 per parameter costs more to train but less to run, so current open models are deliberately "over-trained": Llama 3's 8B model was trained on over 15T tokens, close to 2,000 tokens per parameter. Loss keeps falling with more data, just more slowly than the compute-optimal recipe would buy.

Emergent abilities, and caveats

Wei and colleagues catalogued tasks where small models score at chance and, past some scale, accuracy jumps: multi-digit arithmetic, some reasoning benchmarks. They called these emergent abilities, abilities that cannot be predicted by extrapolating smaller models. Schaeffer, Miranda and Koyejo argued that many of these jumps come from the metric, not the model. Exact-match accuracy gives credit only if every token of the answer is right, so with per-token accuracy p and a k-token answer it behaves like pk: a smooth rise in p looks like a sudden jump. Measured with a continuous metric such as per-token log-likelihood, the same models improve smoothly. Some capabilities do appear abruptly on any metric, and small benchmarks add noise, so the honest summary is: the loss is predictable, specific downstream abilities much less so, and a claimed jump should be checked against a smoother metric before it is believed.

ComponentShape/ParamsMeaningSource
nn.CrossEntropyLoss(weight=None, ignore_index=-100, reduction="mean", label_smoothing=0.0)logits (B·T, V), targets (B·T,)The pretraining loss for every objective: mean −log p of the target tokenloss.py
F.cross_entropy(input, target, ..., ignore_index=-100, reduction="mean", label_smoothing=0.0)sameThe functional form used inside most training loopsfunctional.py
ignore_indexdefault −100Positions with this target add nothing to the loss: padding, and every unmasked position in masked LMloss.py
torch.triu(input, diagonal=0)(T, T)Builds the causal mask that hides future tokens_torch_docs.py
torch.bernoulli(input, *, generator)same shape as input probabilitiesPicks the 15% of positions to mask, and the 80/10/10 split_torch_docs.py
torch.multinomial(input, num_samples, replacement=False)(num_samples,) indicesDraws which source each training sequence comes from, by mixture weight_torch_docs.py
Non-embedding parameters N≈ 12 · nlayer · d2The N in the scaling laws and in C ≈ 6NDKaplan et al., Table 1
Compute CFLOPs ≈ 6 · N · DForward 2N, backward 4N per tokenKaplan et al., Table 1
Chinchilla fitE, A, B, α, β = 1.69, 406.4, 410.7, 0.34, 0.28Predicted loss for any N and DHoffmann et al., Approach 3

PyTorch v2.15.0 supplies the loss and the sampling operations; data pipelines, deduplication and scaling-law fits live in separate tools.

Worked example

How many targets each objective gets

On the 11-token sentence in the diagram, causal LM trains on 10 targets. Span corruption hides 3 tokens in two spans and produces a 10-token input and a 6-token target. For masked LM on a 512-token sequence, 15% means 76.8 positions on average: 61.44 become [MASK], 7.68 a random token and 7.68 stay as they are. A causal model gets 511 targets from the same sequence, about 6.7 times as many, which is part of why causal LM won for large models.

Six FLOPs per parameter per token

One MLP up-projection with fin = 4096 and fout = 16384 has 67,108,864 weights. On a batch of 4096 tokens:

ProductShapesFLOPs
Forward Y = XW(4096 × 4096) · (4096 × 16384)5.498 × 1011
∂L/∂X = ∂L/∂Y · Wᵀ(4096 × 16384) · (16384 × 4096)5.498 × 1011
∂L/∂W = Xᵀ · ∂L/∂Y(4096 × 4096) · (4096 × 16384)5.498 × 1011
Total1.649 × 1012

The total divided by parameters times tokens is exactly 6. For a whole GPT-style model with 32 layers and dmodel = 4096, 12 · 32 · 40962 gives N = 6.44B non-embedding parameters, plus 0.131B in a 32,000-token embedding. Per token the forward pass is 2N = 1.288 × 1010 FLOPs through the weights and 2 · 32 · 4096 · 4096 = 1.074 × 109 for attention at a 4096-token context, 7.7% of the forward total.

Sizing a model for Chinchilla's budget

Chinchilla trained N = 70B parameters on D = 1.4T tokens: C = 6 · 7.0 × 1010 · 1.4 × 1012 = 5.88 × 1023 FLOPs. Gopher's 280B parameters on 300B tokens give 5.04 × 1023 by the same count; the paper's more careful FLOP count puts both at the same budget. The 20-tokens rule recovers Chinchilla exactly: √(5.88 × 1023 / 120) = 70B parameters, 1.4T tokens.

ModelNDTokens per parameterC = 6NDFitted L(N, D)
Chinchilla70B1.4T20.05.88 × 10231.9366
Gopher280B0.3T1.15.04 × 10231.9933
Approach 3 optimum at Chinchilla's C32.5B3.02T92.85.88 × 10231.9300

The fitted law predicts Gopher's loss 0.057 nats higher than Chinchilla's while using slightly less compute by this count: Gopher pays a big model's cost with too few tokens, and its data term B/Dβ dominates. Plugging the published constants into the closed form gives a smaller optimum still, 32B parameters on 3.0T tokens, because this fit's a = 0.45 is below the other two methods' 0.5. The predicted gain over Chinchilla's actual choice is only 0.0067 nats: the loss is very flat near the optimum, which is why a rule of thumb works.

Across budgets the fitted optimum drifts toward more tokens per parameter, while the rule keeps 20:

C (FLOPs)Approach 3 NoptDoptTokens per parameter20-tokens N20-tokens DPredicted loss
1 × 10200.6B0.026T400.9B0.018T2.600
1 × 10211.8B0.091T502.9B0.058T2.329
1 × 10225.2B0.323T639.1B0.183T2.139
1 × 102314.6B1.142T7828.9B0.577T2.005
1 × 102441.3B4.036T9891.3B1.826T1.911
1 × 1025116.8B14.267T122288.7B5.774T1.845

Each tenfold more compute multiplies the optimal N by 10a = 2.83 and D by 10b = 3.53 under this fit. Kaplan's N ∝ C0.73 would put 5.37× into the model and only 1.86× into the data. Under Kaplan's L(N), doubling N multiplies loss by 2−0.076 = 0.9487, a 5.1% cut, and doubling D by 2−0.095 = 0.9363.

At 1000 GPUs with a dense BF16 peak of 989 TFLOP/s each (an H100 SXM) and 40% MFU, Chinchilla's 5.88 × 1023 FLOPs take 17.2 days.

IsoFLOP curves from the Chinchilla fit Model size N on a log axis from 10⁸ to 10¹² parameters, and predicted loss from 1.85 to 2.65. Four U-shaped curves, one per compute budget from 10²¹ to 10²⁴ FLOPs, each with every N trained on D = C/(6N) tokens. Each curve's minimum is marked: about 1.8B at loss 2.329, 5.2B at loss 2.139, 14.6B at loss 2.005, 41.3B at loss 1.911. The minima move right and down as compute grows. Chinchilla and Gopher, whose budgets of about 5–6 × 10²³ fall between the two lowest curves, are marked as squares: Chinchilla at 70B and loss 1.937, within 0.007 of its budget's minimum, and Gopher at 280B and loss 1.993, far to the right. 10⁸ 10⁹ 10¹⁰ 10¹¹ 10¹² 1.9 2.1 2.3 2.5 parameters N (log scale), each trained on D = C / 6N tokens predicted loss Chinchilla Gopher 10²¹ 10²² 10²³ 10²⁴ FLOPs

A mixture and its epochs

An illustrative mixture spending Chinchilla's 1.4T-token budget over five sources:

SourceAvailable tokensWeightTokens trainedEpochs
Web3000B0.70980B0.33
Code400B0.14196B0.49
Books60B0.0684B1.40
Papers50B0.0570B1.40
Wikipedia20B0.0570B3.50

The web supplies 70% of training tokens yet only a third of it is ever read, while Wikipedia, at 5% of the mix, is read 3.5 times, close to the roughly 4-epoch point where repetition stops being nearly as good as new data.

Finding near-duplicates with MinHash

Three short documents, split into word 3-grams:

  1. "the cat sat on the mat and looked out of the window at the rain" (13 shingles)
  2. "the cat sat on the mat and looked out of the window at the snow" (13 shingles)
  3. "a dog ran across the park chasing a red ball in the sun" (11 shingles)

Documents 1 and 2 differ in the last word, which changes one shingle each: they share 12 of 14 distinct shingles, a Jaccard similarity of 0.8571. With 128 hash functions (BLAKE2b keyed by the function's index), the two signatures agree in 111 places, an estimate of 0.8672. Document 3 shares no shingle with either, and its signature agrees with theirs nowhere. Cutting the signatures into 16 bands of 8 rows gives a threshold near (1/16)1/8 = 0.707; the chance that a pair becomes a candidate is:

Jaccard s0.30.50.70.80.90.857 (docs 1, 2)
1 − (1 − s8)160.00100.06070.61330.94700.99990.9960

Pairs above about 0.8 are almost always caught and pairs below 0.5 almost never compared, and each document only has to be hashed into 16 buckets instead of compared with every other.

A smooth metric that looks emergent

Seven models whose per-token accuracy on a task rises evenly, scored by exact match on a 10-token answer (all tokens right, treated as independent):

Model1234567
Per-token accuracy p0.500.600.700.800.900.950.99
Exact match p100.0010.0060.0280.1070.3490.5990.904

The first four models score 10.7% or less on exact match, then the score climbs to 90%: on a log-scale size axis this reads as an ability switching on, though nothing about the model changed abruptly.

Per-token accuracy against exact match Seven models on the horizontal axis and score from 0 to 1 on the vertical axis. Per-token accuracy rises in a nearly straight line from 0.50 to 0.99. Exact match on a 10-token answer stays near zero for the first four models and then rises steeply to 0.90. 0 0.5 1 1 2 3 4 5 6 7 model, smallest to largest per token exact match
You have a fixed budget of 1022 FLOPs. About how large a model should you train, and on how many tokens?

By the 20-tokens rule, N = √(1022 / 120) ≈ 9.1B parameters on about 183B tokens. The Approach 3 fit says 5.2B on 323B; the loss differs little between them. If the model will serve heavy traffic, go smaller and train longer.

Implementation

The causal-LM loss with padding ignored, masked-LM corruption, and the sizing arithmetic. model is any decoder that returns logits of shape (B, T, V).

import math
import torch
import torch.nn.functional as F

def causal_lm_loss(model, tokens, pad_id):
    logits = model(tokens[:, :-1])                       # position i predicts token i + 1
    targets = tokens[:, 1:].masked_fill(tokens[:, 1:] == pad_id, -100)
    return F.cross_entropy(logits.reshape(-1, logits.size(-1)), targets.reshape(-1), ignore_index=-100)

def mask_for_mlm(tokens, mask_id, vocab_size, rate=0.15, generator=None):
    labels = tokens.clone()
    picked = torch.bernoulli(torch.full(tokens.shape, rate), generator=generator).bool()
    labels[~picked] = -100                               # loss only on picked positions
    roll = torch.rand(tokens.shape, generator=generator)
    inputs = tokens.clone()
    inputs[picked & (roll < 0.8)] = mask_id
    swap = picked & (roll >= 0.8) & (roll < 0.9)
    inputs[swap] = torch.randint(vocab_size, tokens.shape, generator=generator)[swap]
    return inputs, labels                                # the last 10% keep their token

def chinchilla_size(compute, tokens_per_param=20):
    n = math.sqrt(compute / (6 * tokens_per_param))
    return n, tokens_per_param * n

print(chinchilla_size(6 * 70e9 * 1.4e12))               # (7e10, 1.4e12)

Real pretraining code packs documents end to end into fixed-length sequences separated by an end-of-text token rather than padding, so almost no positions are wasted; the attention mask may also stop tokens attending across document boundaries. The loss is usually computed in float32 even under mixed precision, because the softmax over a large vocabulary is sensitive to rounding. A scaling-law study trains a ladder of small models at several budgets, fits the curves, and only then commits to the large run.

Tradeoffs

  • Causal vs masked vs span objectives. Causal LM learns from every token and generates natively; masked LM gives bidirectional representations suited to classification and retrieval but learns from 15% of tokens; span corruption is cheap per token and suits encoder-decoder models for translation and summarization.
  • Compute-optimal vs inference-optimal. Chinchilla sizing minimizes training cost for a given loss; a model that will serve billions of tokens is cheaper overall if it is smaller and trained far longer.
  • Repeating data. High-quality data is finite. A few epochs over it costs little; many epochs mean diminishing returns and more memorization, which pushes teams toward better filtering and synthetic data.
  • Deduplication strength. Aggressive near-dedup removes boilerplate and test leakage but can also remove legitimately similar documents such as licences and standard code; the band and row settings choose where to cut.
  • Trusting a fit. Scaling laws are fits on one data distribution, tokenizer and architecture; the constants do not transfer, the exponents only roughly, and Kaplan and Chinchilla reached different allocations from different training choices.
Why does the backward pass cost about twice the forward pass?

For every weight matrix it does two matrix products of the forward's size: one for the gradient with respect to the layer's input, passed back to earlier layers, and one for the gradient with respect to the weight, used in the update. 2N forward plus 4N backward is the 6N in C ≈ 6ND.

A paper shows a capability that jumps from 0% to 60% between two model sizes. What would you check?

Whether the metric is all-or-nothing, such as exact match on a multi-token answer. Score the same models with per-token log-likelihood or partial credit; if that improves smoothly, the jump is a property of the metric. Also check the benchmark's size, since a few dozen questions make large jumps by chance.

Why do masked-LM labels use −100 at unpicked positions?

CrossEntropyLoss and F.cross_entropy default to ignore_index=-100: targets with that value contribute nothing to the loss or its gradient, and the mean is taken over the remaining positions only.

Connections

Read first

Read next

No page builds on this one yet.

References

  • Kaplan, McCandlish, Henighan, Brown, Chess, Child, Gray, Radford, Wu and Amodei. Scaling Laws for Neural Language Models. 2020. arXiv:2001.08361
  • Hoffmann, Borgeaud, Mensch et al. Training Compute-Optimal Large Language Models. NeurIPS 2022. arXiv:2203.15556
  • Devlin, Chang, Lee and Toutanova. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. NAACL 2019. arXiv:1810.04805
  • Raffel, Shazeer, Roberts et al. Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. JMLR 2020. arXiv:1910.10683
  • Muennighoff, Rush, Barak et al. Scaling Data-Constrained Language Models. NeurIPS 2023. arXiv:2305.16264
  • Wei, Tay, Bommasani et al. Emergent Abilities of Large Language Models. TMLR 2022. arXiv:2206.07682
  • Schaeffer, Miranda and Koyejo. Are Emergent Abilities of Large Language Models a Mirage? NeurIPS 2023. arXiv:2304.15004
  • Broder. On the Resemblance and Containment of Documents. Compression and Complexity of Sequences, 1997.
  • PyTorch v2.15.0: nn.CrossEntropyLoss, F.cross_entropy, torch.bernoulli, torch.multinomial.