Linear algebra for LLMsPart 10: Capstone and reference

Llama 3 8B, end to end

14 min

The spec sheet

d=4096,L=32,dff=14336\displaystyle d = 4096, \quad L = 32, \quad d_{ff} = 14336
h=32,hkv=8,dh=128\displaystyle h = 32, \quad h_{kv} = 8, \quad d_h = 128
V=128,256,Tmax⁡=8192\displaystyle V = 128{,}256, \quad T_{\max} = 8192

Everything on the following cards follows from these seven numbers (from the model’s config and Meta’s model card). Copy them at the top of a fresh page; you’ll use every one.

Write

The seven numbers above.

1. Token ids → vectors

idsids → xx
E ⁣:128,256×4096=525,336,576 params\displaystyle E\!: 128{,}256 \times 4096 = 525{,}336{,}576 \text{ params}

Each id picks one row of the embedding table (Part 1). No arithmetic, just a lookup. This vector starts the residual stream (Part 6).

2. Normalize, then Q, K, V

Q=RMSNorm⁡(x) WQ\displaystyle Q = \operatorname{RMSNorm}(x)\, W_Q
WQ ⁣:W_Q\!:WK,WV ⁣:W_K, W_V\!:

RMSNorm divides each row by its root mean square and applies a gain (Part 6). Then three matrix products. WKW_K and WVW_V are narrower because of GQA: 8 key/value heads of 128 instead of 32 (Part 5).

Write

Q ⁣:(T,4096)Q\!: (T, 4096), K,V ⁣:(T,1024)K, V\!: (T, 1024).

3. Split into heads, rotate

Q ⁣:Q\!:K,V ⁣:K, V\!:

view then transpose(1, 2), never a bare reshape (Part 4). RoPE then rotates each pair of entries in QQ and KK by an angle that depends on the position (Part 6), so the scores will depend on relative position. Each K/V head serves 4 query heads.

4. Scores, mask, softmax

S=QK⊤128 ⁣:(32,T,T)\displaystyle S = \frac{QK^\top}{\sqrt{128}}\!: (32, T, T)
A=softmax⁡rows(S+mask)\displaystyle A = \operatorname{softmax}_{\text{rows}}(S + \text{mask})

A dot product for every (query, key) pair in every head, divided by dh≈11.3\sqrt{d_h} \approx 11.3 so the scores don’t saturate the softmax (Part 1). The causal mask puts −∞-\infty above the diagonal, and the softmax runs along each row (Part 5).

Write

S,A ⁣:(h,T,T)S, A\!: (h, T, T). Scale 1/dh1/\sqrt{d_h}, mask above the diagonal, softmax along rows.

5. Mix values, merge heads, project

AV ⁣:AV\!: →
x←x+(AV)merged WO,WO ⁣:4096×4096\displaystyle x \leftarrow x + (AV)_{\text{merged}}\, W_O, \qquad W_O\!: 4096 \times 4096

Each output row is a weighted average of value rows (Part 5). Transpose back, merge the heads into one 4096-wide row, multiply by WOW_O, and add to the residual stream.

6. The MLP

(SiLU⁡(xWgate)⊙xWup) Wdown\displaystyle (\operatorname{SiLU}(xW_{\text{gate}}) \odot xW_{\text{up}})\, W_{\text{down}}
(T,4096)→(T,14336)→(T,4096)\displaystyle (T, 4096) \to (T, 14336) \to (T, 4096)

Normalize again, widen to 14,336 twice, gate one with the other elementwise, and project back down (SwiGLU, Part 6). Add to the residual stream. That’s one block; there are 32.

Write

Block = x+=Attn⁡(norm⁡(x))x \mathrel{+}= \operatorname{Attn}(\operatorname{norm}(x)); x+=MLP⁡(norm⁡(x))x \mathrel{+}= \operatorname{MLP}(\operatorname{norm}(x)).

7. Logits and the next token

norm⁡(x) Wout ⁣:(T,4096)(4096,128256)=(T,128256)\displaystyle \operatorname{norm}(x)\, W_{\text{out}}\!: (T, 4096)(4096, 128256) = (T, 128256)
p=softmax⁡(zT,:)\displaystyle p = \operatorname{softmax}(z_{T,:})

A final norm, then one score per vocabulary token. When generating, only the last row matters: its softmax is the distribution the next token is sampled from. In training, every row is scored against the actual next token with cross-entropy (Part 8).

✏️ Your turn

Count it

per layer≈218.1M,vocab matrices≈525.3M each\displaystyle \text{per layer} \approx 218.1\text{M}, \quad \text{vocab matrices} \approx 525.3\text{M each}

Total parameters? (You did this in Part 6.)

Work it out on paper, then go to the next card to check.

Answer: 8.03 billion

32×218.1M+2×525.3M≈8.03B\displaystyle 32 \times 218.1\text{M} + 2 \times 525.3\text{M} \approx 8.03\text{B}

Exactly 8,030,261,248, counting the final norm.

✏️ Your turn

Memory to serve one full-length sequence

BF16 weights,T=8192\displaystyle \text{BF16 weights}, \quad T = 8192
KV per token=2⋅L⋅hkv⋅dh⋅2 bytes\displaystyle \text{KV per token} = 2 \cdot L \cdot h_{kv} \cdot d_h \cdot 2 \text{ bytes}

Weights plus KV cache, in GB?

Work it out on paper, then go to the next card to check.

Answer: about 17.1 GB

weights: 8.03×109×2=16.06 GB\displaystyle \text{weights: } 8.03 \times 10^9 \times 2 = 16.06 \text{ GB}
KV: 2⋅32⋅8⋅128⋅2=131,072 B/token\displaystyle \text{KV: } 2 \cdot 32 \cdot 8 \cdot 128 \cdot 2 = 131{,}072 \text{ B/token}
×8192=1.07 GB  (1 GiB)\displaystyle \times 8192 = 1.07 \text{ GB} \;(1 \text{ GiB})

Fits on one 80 GB GPU with plenty of room for a batch: each extra full-length sequence adds only 1 GiB of cache, thanks to GQA. Without GQA (32 K/V heads) it would be 4 GiB each.

✏️ Your turn

Decode speed at full context

bandwidth=3.35 TB/s (H100 SXM)\displaystyle \text{bandwidth} = 3.35 \text{ TB/s (H100 SXM)}

What’s the most tokens per second for that one sequence?

Work it out on paper, then go to the next card to check.

Answer: about 196

3.35×1012(16.06+1.07)×109≈196 tokens/s\displaystyle \frac{3.35 \times 10^{12}}{(16.06 + 1.07) \times 10^9} \approx 196 \text{ tokens/s}

Every token reads all the weights and the whole cache once (Part 9). Batching 32 sequences reads the weights once for all of them, so total throughput rises far more than the per-sequence speed falls.

Prefill: compute, not memory

matmuls: 2N⋅T=2×8.03×109×8192≈1.32×1014\displaystyle \text{matmuls: } 2N \cdot T = 2 \times 8.03 \times 10^9 \times 8192 \approx 1.32 \times 10^{14}
attention: 4 L T2d=4⋅32⋅81922⋅4096≈3.5×1013\displaystyle \text{attention: } 4\,L\,T^2 d = 4 \cdot 32 \cdot 8192^2 \cdot 4096 \approx 3.5 \times 10^{13}

Processing an 8,192-token prompt: the weight matmuls cost 2N2N per token. Scores QK⊤QK^\top and mixing AVAV each cost 2T2d2T^2 d per layer, on top. At full context, attention adds about 27% (half of it is masked, but simple kernels compute it anyway); at 1,000 tokens, about 3%. About 1.7×10141.7 \times 10^{14} FLOPs in all: at 989 TFLOP/s, at least 0.17 s.

Write

Prefill ≈ 2NT+4LT2d2NT + 4LT^2d FLOPs. The T2T^2 term matters only for long contexts.

✏️ Your turn

Training compute

N=8.03×109,D=15×1012 tokens\displaystyle N = 8.03 \times 10^9, \quad D = 15 \times 10^{12} \text{ tokens}

Estimate the training FLOPs. Meta reports 1.3 million H100 GPU-hours; what sustained FLOP/s per GPU does that imply?

Work it out on paper, then go to the next card to check.

Answer

C≈6ND=6×8.03×109×15×1012≈7.2×1023\displaystyle C \approx 6ND = 6 \times 8.03 \times 10^9 \times 15 \times 10^{12} \approx 7.2 \times 10^{23}
7.2×10231.3×106×3600 s≈1.5×1014 FLOP/s\displaystyle \frac{7.2 \times 10^{23}}{1.3 \times 10^6 \times 3600 \text{ s}} \approx 1.5 \times 10^{14} \text{ FLOP/s}

About 150 TFLOP/s of counted work per GPU, roughly 15% of the dense BF16 peak. 6ND6ND leaves out attention and everything that isn’t a training step, and Meta’s token count is “over 15T”, so read this as an order-of-magnitude check, not a utilization figure.

✏️ Your turn

A LoRA adapter on the MLP

r=16 on Wgate,Wup (4096→14336)\displaystyle r = 16 \text{ on } W_{\text{gate}}, W_{\text{up}}\ (4096 \to 14336)
and Wdown (14336→4096), all 32 layers\displaystyle \text{and } W_{\text{down}}\ (14336 \to 4096), \text{ all 32 layers}

Part 7 put adapters on WQW_Q and WVW_V. Now adapt the three MLP matrices instead. How many trainable parameters? What fraction of the model?

Work it out on paper, then go to the next card to check.

Answer: 28.3 million, 0.35%

each: 16 (4096+14336)=294,912\displaystyle \text{each: } 16\,(4096 + 14336) = 294{,}912
32×3×294,912=28,311,552\displaystyle 32 \times 3 \times 294{,}912 = 28{,}311{,}552
28.3M/8.03B≈0.35%\displaystyle 28.3\text{M} / 8.03\text{B} \approx 0.35\%

r(din+dout)r(d_{\text{in}} + d_{\text{out}}) per adapted matrix, the same for WdownW_{\text{down}} since only the sum of the sides matters. About 4× Part 7’s attention-only adapter, still tiny: 57 MB in BF16, small enough to keep one per customer and swap at serving time.

📌 Recap

The whole model on one page

  • Lookup → 32 × (norm, QKV, RoPE, scores, mask, softmax, mix, WOW_O, add; norm, SwiGLU, add) → norm → logits.
  • 8.03B parameters; 16 GB in BF16; KV 128 KiB per token.
  • Decode ≈ bandwidth / bytes per token; prefill ≈ 2NT+4LT2d2NT + 4LT^2 d; training ≈ 6ND6ND.
  • LoRA: r(din+dout)r(d_{\text{in}} + d_{\text{out}}) per matrix.

Write

The four lines above. You can now size any transformer from its config.

Sources

  • Meta Llama 3 model card (github.com/meta-llama/llama3, MODEL_CARD.md): 8B and 70B, context 8k, GQA in all models, pretrained on over 15 trillion tokens, 1.3M H100-80GB GPU-hours for 8B.
  • Meta-Llama-3-8B config.json: hidden size 4,096, 32 layers, 32 attention heads, 8 key/value heads, intermediate size 14,336, vocabulary 128,256.
  • NVIDIA H100 datasheet: 3.35 TB/s (SXM), about 989 TFLOPS dense BF16.