Scaling: Parameters, FLOPs, Memory and Time¶
Before training anything big, four questions can be answered with arithmetic: how many
parameters, how much compute, how much memory, and how long. scripts/model_report.py does it
for any preset or config. It builds the model on PyTorch's meta device (shapes, no memory), so
even the 3B config is instant on a laptop:
python scripts/model_report.py --preset 77m
python scripts/model_report.py --preset student --arch modern --tokens 50e6
python scripts/model_report.py --config configs/base.json --tflops 989 --mfu 0.4 --gpus 8
Model: 77m (classic) | vocab 50304, n_embed 512, 8 blocks, 8 heads, context 512
Parameters
total 77,031,552 (77.03M)
embedding tables 26,017,792 (34% of the total)
per block 3,150,848
Compute
training FLOPs per token 331.25MFLOP (at 512-token windows)
Chinchilla-optimal data 1.54G tokens (20 per parameter)
training on 1.54G tokens = 510.33PFLOP
at 100 TFLOP/s x 1 device(s) and 40% utilization: 3.5 hours (0.1 days)
Memory
weights (bf16, inference) 0.14 GiB
AdamW training state 1.15 GiB (fp32 weights + grads + 2 moments, 16 B/param)
activations, batch 24 ~3.47 GiB (bf16; gradient checkpointing cuts most)
KV cache per token 16.0 KiB (bf16), 0.01 GiB for one full 512-token context
The rest of this page explains where each line comes from.
Counting parameters¶
With d = n_embed, a classic block has four d x d matrices in attention (query, key, value,
output) and two in the MLP (d x 4d and 4d x d):
Biases and norm scales add a few thousand more. For the 3B config (d = 2048), 12 d^2 is
50,331,648 and the exact count is 50,352,128. Outside the blocks, the token embedding and the
output layer each hold vocab_size x d numbers, which is why they dominate small models (34% of
the 77M model, 71% of the tiny one) and almost vanish in big ones (3% of the 3B model).
Compute: about 6 FLOPs per parameter per token¶
A matrix multiply costs 2 FLOPs (a multiply and an add) per weight per token. The backward pass costs about twice the forward pass: one product for the gradient of the input and one for the gradient of the weight. So training costs
where N counts the weights a token is multiplied by (embeddings are lookups, not
multiplies; with Mixture of Experts only the active experts count), and the second term is
attention itself: L layers, each comparing the token with T others
(PaLM, appendix B). Since N is about 12 L d^2, attention
matches the weights when T reaches 6d, about 12,000 tokens for d = 2048. Below that, the
6N term is the whole story, which is why "6 times parameters times tokens" is the standard
back-of-the-envelope estimate.
Data: about 20 tokens per parameter¶
Chinchilla trained hundreds of models and found that, for a
fixed compute budget, loss is lowest when parameters and training tokens grow together, at
roughly 20 tokens per parameter. The report uses that as its default --tokens.
It is a statement about the cheapest way to train a given loss, not a rule. A model that will serve many users is cheaper overall if it is smaller and trained much longer: Llama 3 8B saw 15 trillion tokens, about 1,900 per parameter.
Time: FLOPs over achieved throughput¶
MFU (model FLOPs utilization) is the fraction of the hardware's peak that training actually achieves. 30% to 50% is typical for large, well-tuned runs. Small models do much worse because each operation is too small to keep the GPU busy. The 77M run in the README is a real example: about 140,000 tokens per second times 331 MFLOP per token is 46 TFLOP/s, on two L40 GPUs with 181 TFLOP/s of bf16 each, an MFU of about 13%.
A few estimates side by side (Chinchilla-optimal data, 40% MFU):
| Model | Training compute | One H100 (989 TFLOP/s) | Eight H100s |
|---|---|---|---|
| 77M | 510 PFLOP | 22 minutes | 3 minutes |
355M modern (configs/base.json) |
17.3 EFLOP | 12 hours | 1.5 hours |
3B (the original config.py) |
1,370 EFLOP | 40 days | 5 days |
And on a laptop CPU: the tiny preset trained on 6.1M tokens (14.8 TFLOP) in 5 minutes 17 seconds, about 47 GFLOP/s. The student preset, with wider matrices, ran its first 400 steps (58 TFLOP) in 6 minutes 50 seconds, about 140 GFLOP/s: bigger models keep the CPU busier. Even at that speed the 3B model would take around 300 years, which is the honest reason the student track exists.
Memory¶
- Inference: 2 bytes per parameter in bf16, plus the KV cache. A 3B model needs 6.4 GiB.
- Training with AdamW: about 16 bytes per parameter: fp32 weights (4), gradients (4) and Adam's two moments (4 + 4). The 3B model needs 51 GiB before activations, more than any single consumer GPU. Sharding that state across GPUs (FSDP, ZeRO) is how big runs fit.
- Activations: what the backward pass needs from the forward pass. Per layer, about
T * batch * d * (34 + 5 * n_head * T / d)bytes in bf16 (Korthikanti et al., 2022). It grows with batch and window, not with the parameter count, and gradient checkpointing (--grad-checkpointing) trades it for about one extra forward pass. - KV cache: what generation stores per token; see attention.
Use it before you train¶
# will the 3B model fit on my GPU, and how long would it take?
python scripts/model_report.py --preset 3b --tflops 989 --mfu 0.4 --gpus 8
# how long will the student preset take on my laptop?
python scripts/model_report.py --preset student --arch modern --tokens 32.8e6 --tflops 0.14 --mfu 1
The second command uses the student preset's measured rate from above (0.14 TFLOP/s) as the
"peak", with an MFU of 1, and prints 1.2 hours. For your own machine, time a short run of the
preset you plan to use (--steps 200), divide its training FLOPs by the seconds it took, and
pass that number. Use the same preset for the measurement: on our laptop the student preset
reached three times the tiny preset's FLOP/s.