forked from rohitg00/ai-engineering-from-scratch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquiz.json
More file actions
78 lines (78 loc) · 3.3 KB
/
Copy pathquiz.json
File metadata and controls
78 lines (78 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{
"lesson": "77-data-parallel-ddp",
"title": "Data Parallel DDP From Scratch",
"questions": [
{
"stage": "pre",
"question": "Why does DDP broadcast parameters at construction instead of relying on the same seed across ranks?",
"options": [
"Broadcast is faster than seeding",
"Same-seed init drifts by float epsilon across ranks; broadcast guarantees byte-equal weights before training starts",
"PyTorch forbids same-seed init",
"Broadcast saves memory"
],
"correct": 1,
"explanation": "Float ops on different hardware (or even different process orders) can differ at the bit level. A broadcast from rank 0 is the only way to get byte-equal weights everywhere."
},
{
"stage": "pre",
"question": "What does DDP do after backward and before optimizer.step?",
"options": [
"Nothing",
"Saves a checkpoint",
"Allreduce-SUM every parameter's gradient and divide by world_size to get the mean gradient",
"Broadcasts logits"
],
"correct": 2,
"explanation": "The mean gradient is invariant to world_size so a learning rate tuned at one rank works at N ranks."
},
{
"stage": "check",
"question": "Why divide by world_size after allreduce-SUM instead of using allreduce-MEAN?",
"options": [
"Allreduce-MEAN does not exist in gloo",
"Division by world_size on each rank is a local op; allreduce-MEAN would be implemented the same way under the hood",
"Division produces NaN",
"world_size is unknown"
],
"correct": 1,
"explanation": "Both approaches yield the same arithmetic. NCCL ships allreduce-AVG since 2.10; gloo does not, so divide locally after SUM."
},
{
"stage": "check",
"question": "What does gradient bucketing in production DDP achieve?",
"options": [
"Quantises gradients to int8",
"Coalesces many small allreduces into one large allreduce, amortising the per-call latency floor",
"Frees gradient memory",
"Skips backward"
],
"correct": 1,
"explanation": "A 1B-parameter model has thousands of grad tensors; one allreduce per tensor pays gloo or NCCL latency thousands of times."
},
{
"stage": "check",
"question": "Why does no_sync() exist in PyTorch DDP?",
"options": [
"To turn off DDP",
"Gradient accumulation over K microbatches needs to skip the post-backward allreduce for K-1 of them; no_sync wraps that pause",
"To switch backends",
"To debug"
],
"correct": 1,
"explanation": "Without no_sync the allreduce fires K times per accumulated step and throughput drops to the floor."
},
{
"stage": "post",
"question": "Why does this lesson's reference implementation walk every rank's micro-batch sequentially in one process?",
"options": [
"Single-process is faster",
"It gives a byte-equal baseline: the sequential mean gradient must equal DDP's allreduced mean gradient at every step",
"It is the only way to use gloo",
"It saves memory"
],
"correct": 1,
"explanation": "Equivalence to the reference loop is the load-bearing correctness test; without it gradient sync bugs hide until step 10000."
}
]
}