6.1.8 · D1Scaling & Efficient Architectures

Foundations — Data parallelism and ZeRO optimization

1,973 words9 min readBack to topic

Before you can read the parent note Data Parallelism and ZeRO, you need to earn every symbol it throws at you. This page builds each one from nothing, in an order where each idea leans on the one before it. Nothing here assumes you have seen distributed training before.


1. What is a "model" and what is a "parameter"?

Picture a giant control panel covered in millions of little dials. Each dial is one number. Turning the dials is training. A modern model can have hundreds of billions of dials.

Why does the topic need ? Because everything about memory is measured in "how many bytes per parameter." If we know and know how many bytes each dial costs, we can compute the total memory. is the ruler the whole topic measures with.

Figure — Data parallelism and ZeRO optimization

Look at the figure: the same panel of dials is copied onto GPU 0 and GPU 1. That duplication is the villain of the entire topic.


2. Bytes — how memory is actually counted

Two number formats matter here:

Why does the topic care? Because memory = (number of dials) × (bytes per dial). A dial stored in fp16 costs bytes, so all parameters in fp16 cost bytes. That is exactly where the parent's comes from. This precision trade-off is explored fully in Mixed Precision Training.


3. Gradient — the "which way to turn each dial" arrow

Because there is exactly one gradient number per parameter, gradients also take numbers → in fp16 that is another bytes. That is the parent's second term.

The symbol:


4. , , and the learning rate

Why must be small, and why that matters later: tiny steps mean the change to a dial can be a very small number. If we stored dials in fp16, such a tiny change might round to zero and get lost. That is the whole reason the topic keeps an fp32 "master copy" — see §7.


5. The optimizer and its extra memory (Adam)

To be smart, Adam stores two extra numbers per parameter:

Both are kept in fp32 (4 bytes each) for stability. Plus a fp32 master copy of the parameters. So Adam's bookkeeping costs:

This is the parent's mysterious . More frugal versions are covered in Memory-Efficient Optimizers. Adding it all up gives the famous :

Figure — Data parallelism and ZeRO optimization

The bar chart shows why the optimizer states (the tall block), not the parameters, dominate memory — this is exactly what ZeRO attacks first.


6. GPU, rank, and — the cast of machines

Why the topic needs these: the entire memory-saving trick is "divide by ." Every time you see in the parent note, it literally means "each of the GPUs keeps only its share." And lets us say which share belongs to which GPU.


7. Why an fp32 master copy exists (the underflow picture)

Recall from §4 that a step is , often a minuscule number. In fp16 the smallest gaps between representable numbers are large; a tiny update lands between two fp16 values and rounds away to nothing — the dial never moves. Keeping the master weights in fp32 (finer gaps) lets those tiny nudges accumulate. This is why includes a full fp32 copy. Full detail lives in Mixed Precision Training.


8. Talking between GPUs — collective operations

The GPUs must share their gradient arrows. The messaging patterns are named "collectives." Full treatment is in AllReduce and Collective Communication; here are just the three the parent uses.

Figure — Data parallelism and ZeRO optimization

The averaging formula the parent writes, is just AllReduce in symbols: means "add up over all GPUs ," and averages them. It works because the gradient of the whole dataset equals the average of gradients over its parts.


9. Partitioning — the one word that IS ZeRO

This is why the reduction factor climbs toward : cut everything into pieces, hold one piece each.


Prerequisite map

Parameter and Phi

Bytes fp16 and fp32

Memory 16 Phi per GPU

Gradient nabla

Optimizer Adam states 12 Phi

Redundancy across N GPUs

N GPUs and rank r

Collectives AllReduce ReduceScatter AllGather

Partitioning divide by N

ZeRO 1 2 3

Related deeper topics that build on this same foundation: Gradient Accumulation, Activation Checkpointing, Pipeline Parallelism, and the big picture in Large Language Models Training.


Equipment checklist

Cover the right side and test yourself. If any answer surprises you, re-read that section above.

What does the symbol count?
The total number of parameters (dials) in the model.
How many bytes is one fp16 number? one fp32 number?
fp16 = 2 bytes, fp32 = 4 bytes.
Why do gradients take the same bytes as fp16 parameters?
There is exactly one gradient number per parameter, stored in fp16.
Where does the come from?
Adam stores momentum + variance + fp32 master weights, each .
What is the total model-state memory per GPU in standard data parallelism?
bytes.
What does say in plain words?
New dials = old dials minus (learning rate × downhill arrow).
Why keep an fp32 master copy of weights?
Tiny fp16 updates round to zero (underflow); fp32 has finer steps so they accumulate.
What does AllReduce leave on every GPU?
The full averaged (summed) result — everyone gets everything.
How does ReduceScatter differ from AllReduce?
It sums, then gives each GPU only its own slice of the result.
What does AllGather do?
Glues everyone's slices so every GPU ends up holding all slices.
In one word, what is the core trick of ZeRO?
Partitioning — cut the stored state into pieces, one per GPU.
What does mean everywhere in the parent note?
Each of the GPUs keeps only its share.