~/fba-lab/lab/speedrun/journey/keller-84-lab

FBALab

Code · architecture · study mode

AboutRoadmapSpeedrun
FBALab

Study mode — no GPU required.

Interactive LLM training & inference lab.

Qwen CAboutContactTermsPrivacyCookiesCommunity

© 2026 FBA Lab

Contact · contact@bubblspace.com · +91 75061 55016

Speedrun›Speedrun milestones›#84 · FP8 Precision
Act 1Model Training FundamentalsAct 2AI Systems OptimizationAct 3World-Record Training Optimization
Step 28 of 28Skill: World-Record Training Optimization
← #62 · Bigram Hash
TRAINING SIMULATION

#84 · FP8 Precision

running
◷train_gpt.py▸mm_t_op — FP8 matmul◎learner$no GPU
1/2
Blocks
Quick summary

A custom Torch operator wraps _scaled_mm with E4M3 (4 exponent, 3 mantissa) quantization for the forward pass. Weights…

Full explanation below the code →

fba-lab — train_gpt.py · mm_t_op — FP8 matmulexecuting
// block: mm_t_op — FP8 matmul · lines 60–95$ study train_gpt.py --block fp8-mm-opA custom Torch operator wraps _scaled_mm with E4M3 (4 exponent, 3 mantissa) quantization for the for… ✓
Explanation

A custom Torch operator wraps _scaled_mm with E4M3 (4 exponent, 3 mantissa) quantization for the forward pass. Weights are divided by a learned scale before quantizing — this prevents exponent overflow. The transposed layout (.T.contiguous().T) tricks _scaled_mm into using the column-major path it needs for fast H100 FP8 Tensor Cores.

Think about

Why does quantizing to E4M3 (float8) speed up training rather than just reducing memory?

// architecture

Live diagram

100%
Record #84 · PR #306 · FP8 MLP up-projection · −0.8 s
Hardware precision

H100 has dedicated FP8 tensor cores — half the bits, double the throughput

H100 GPUs contain separate hardware units for different floating-point precisions. BF16 tensor cores process 16-bit numbers. FP8 tensor cores process 8-bit numbers — and run at roughly 2× the throughput. The catch: FP8 has only 3 mantissa bits (vs 7 in BF16) and a tiny dynamic range. Without careful scaling, model weights quantized to FP8 would lose too much precision and diverge.

PR #306 targets the MLP up-projection — the widest matmul in the transformer block. Weights are quantized to E4M3 FP8 format with a learned per-layer scale factor that keeps values in the representable range. The BF16 master weights live in the optimizer; only the compute copy is FP8. After each optimizer step, the BF16 weights are re-quantized to FP8 and cached for the next forward pass.

BF16 S exp ×8 mant ×7 = 16 bits FP8 S e×4 m×3 = 8 bits Matmul throughput on H100 BF16 ~990 TFLOPS FP8 ~2× ↑
# lines 60–95 — E4M3 quantized matmul for MLP up-projection
w_fp8 = w_bf16.to(torch.float8_e4m3fn) / scale
y = torch._scaled_mm(x, w_fp8, scale_a, scale_b)

# lines 158–172 — cache FP8 copy; re-quantize after each opt step
model._mlp_up_proj_f8 = quantize_weights_fp8(model)
Why not train entirely in FP8?

Optimizer state (momentum buffers) and weight updates need high precision to accumulate correctly across thousands of steps. FP8 has only 8 representable exponent values — rounding errors compound and the model diverges. The standard solution: BF16 master weights for the optimizer, FP8 compute copies for the forward pass matmuls only.

Why only the MLP up-projection?

The MLP up-projection is the largest matmul in the transformer (d_model → 4×d_model). It dominates matmul time. Attention QKV projections and the down-projection are smaller and more sensitive to quantization error — particularly attention where small numeric differences can shift which tokens receive focus. FP8 is applied surgically where the gain is largest and the risk lowest.

What changed vs #62

-
-
- w_f8.T,