Skip to content

Commit 3a42c02

Browse files
committed
fix(ci): unblock pre-commit after cascade of latent regressions
Every hook now passes on `pre-commit run --all-files` (exit 0 after one auto-fix pass + one verification pass — the standard pre-commit contract). Unblocks book-validate-dev, which has been red on various hooks since the mlsysim.core import failure finally cleared. Fixes applied (source-traced, not suppressed): 1. codespell: 'OT' in mlperf-edu/reference/cloud/micro_lstm.py is the column name for Oil Temperature in the ETTh1 dataset (Zhou et al., AAAI 2021), not a typo for 'to/of/or/not/it'. Added 'ot' to .codespell-ignore-words.txt (case-insensitive, covers OT). 2. bib-lint §5 bibliography hygiene: 12 entries in mlperf-edu/paper/refs.bib missing required publisher/journal per the canonical mapping in book-prose-merged.md §5. Added canonical publishers (MLSys → mlsys.org, ICLR → OpenReview.net, CVPR → IEEE, NAACL → ACL, etc.); promoted krizhevsky2009cifar from @Article to @TechReport with institution = University of Toronto. banbury2021mlperf uses Curran Associates Inc. (pre-2022 NeurIPS rule); flagged banbury2024wakevision for author review since the booktitle says CVPR but web verification suggests it is still an arXiv preprint. 3. Over-eager 'vs.' style sweep corrupted anchor IDs: 77 instances of -vs.- inside {#sec-...}, {#tbl-...}, {#fig-...} definitions and their @-references across 27 QMDs. Anchor IDs must be literal strings without periods per the repo's own section-ID naming rule; stripped the period from all anchor tokens while preserving 'vs.' in visible prose. 4. 4 broken SVG filename references from the same sweep (pam4-vs.-nrz, traditional-vs.-ml-fleet, tco-build-vs.-buy, centralized-vs.-decentralized) — filenames on disk use vs- (no period) so refs restored to match. 5. Malformed XML declaration in bathtub-curve.svg: '<?xml version="utf-8"?>' → '<?xml version="1.0" encoding="utf-8"?>'. 6. 21 quad-asterisks (****term****) in training.qmd collapsed to **term**. 7. bibtex-tidy auto-reformatted mlperf-edu/paper/refs.bib (alphabetical order + consistent indentation + wrapped author lists) and pipe-table prettifier realigned columns across ~20 QMDs. These are all cosmetic formatter output — no content changes. Verified: pre-commit run --all-files run #1 modified files (exit 1), run #2 exit 0 with 61 Passed / 0 Failed.
1 parent 853dc90 commit 3a42c02

45 files changed

Lines changed: 868 additions & 797 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codespell-ignore-words.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,4 @@ shs
7272
MulFunction
7373
3Nd
7474
relevants
75+
ot

book/quarto/contents/vol1/backmatter/appendix_dam.qmd

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ Note that common industry labels map to DAM components as follows: **Memory Boun
227227

228228
Once you identify the bottleneck, @tbl-bottleneck-actions tells you what to do—and what NOT to do:
229229

230-
| **If You are...** | **Dominant Term** | **Optimization That Works** | **Optimization That is Wasted** |
230+
| **If You are...** | **Dominant Term** | **Optimization That Works** | **Optimization That is Wasted** |
231231
|:------------------|:---------------------------------|:------------------------------------------------------------------|:---------------------------------------------------|
232232
| **Memory-Bound** | $D_{\text{vol}}/BW$ | Quantization, pruning, batching, kernel fusion | Faster accelerator (more FLOP/s will not help) |
233233
| **Compute-Bound** | $O/(R_{\text{peak}} \cdot \eta)$ | Better kernels, Tensor Cores, faster accelerator, lower precision | More memory bandwidth (already saturated) |
@@ -319,7 +319,7 @@ Identifying the root cause of performance bottlenecks requires systematic elimin
319319
|:--------------------------------|:-------------------------|:-------------------------------------------------------------|:-------------------------------------------------------|
320320
| **Low Accelerator Utilization** | **Data** | Is the data loader keeping up with the accelerator? | Implement prefetching and use binary formats. |
321321
| **High Latency (P99)** | **Algorithm** | Is the model depth or width exceeding the latency budget? | Apply quantization (INT8) or structured pruning. |
322-
| **High Training Cost** | **Machine** | Is the hardware utilization ($\eta$) below 30 percent? | Optimize CUDA kernels or use spot instances. |
322+
| **High Training Cost** | **Machine** | Is the hardware utilization ($\eta$) below 30 percent? | Optimize CUDA kernels or use spot instances. |
323323
| **Silent Accuracy Drift** | **Data** | Has the statistical distribution ($P_t$) shifted from $P_0$? | Trigger retraining and update active learning filters. |
324324
| **Out-of-Memory (OOM)** | **Algorithm/Machine** | Does the model state fit in available VRAM? | Use gradient checkpointing or reduce batch size. |
325325

@@ -347,17 +347,17 @@ To surpass qualitative guessing, use the efficiency ratios in @tbl-dam-scorecard
347347

348348
[^fn-mfu-scorecard]: **MFU (Model FLOPs Utilization)**: The ratio of achieved model FLOPs to the hardware's theoretical peak FLOPs, introduced by Chowdhery et al. (2022) in the PaLM paper. Unlike raw accelerator utilization (which counts any work the accelerator performs), MFU measures only *useful* model computation, excluding overhead like gradient synchronization and memory management. @sec-benchmarking covers MFU in depth.
349349

350-
| **Axis** | **Metric** | **Definition** | **Failing Grade** | **Passing Grade** |
351-
|:--------------|:------------------|:-------------------------------------------------------|------------------:|------------------:|
352-
| **Data** | **I/O Overhead** | $\frac{\text{Data Wait Time}}{\text{Total Step Time}}$ | $>$ 10 percent | $<$ 1 percent |
353-
| **Algorithm** | **Active Params** | $\frac{\text{Nonzero Params}}{\text{Total Params}}$ | 100 percent (Dense) | $<$ 50 percent (Sparse) |
354-
| **Machine** | **MFU** | $\frac{\text{Achieved FLOPs}}{\text{Peak FLOPs}}$ | $<$ 30 percent | $>$ 50 percent |
350+
| **Axis** | **Metric** | **Definition** | **Failing Grade** | **Passing Grade** |
351+
|:--------------|:------------------|:-------------------------------------------------------|--------------------:|------------------------:|
352+
| **Data** | **I/O Overhead** | $\frac{\text{Data Wait Time}}{\text{Total Step Time}}$ | $>$ 10 percent | $<$ 1 percent |
353+
| **Algorithm** | **Active Params** | $\frac{\text{Nonzero Params}}{\text{Total Params}}$ | 100 percent (Dense) | $<$ 50 percent (Sparse) |
354+
| **Machine** | **MFU** | $\frac{\text{Achieved FLOPs}}{\text{Peak FLOPs}}$ | $<$ 30 percent | $>$ 50 percent |
355355

356356
: **The D·A·M Efficiency Rubric.** Use these three numbers to characterize any ML system's maturity. A system that passes all three thresholds has exhausted its easy optimizations; further gains require architectural changes or hardware upgrades. {#tbl-dam-scorecard}
357357

358358
The Scorecard and the Roofline Model both answer efficiency questions, but at different scales. The Scorecard grades your current system against known thresholds. Scaling laws and the information roofline address a more strategic question: what happens as you scale *beyond* the current system?
359359

360-
## scaling laws vs. Roofline {#sec-dam-taxonomy-scaling-laws-vs.-roofline-b290}
360+
## scaling laws vs. Roofline {#sec-dam-taxonomy-scaling-laws-vs-roofline-b290}
361361

362362
Systems engineering requires distinguishing between *growth trajectories* and *fundamental limits*.
363363

book/quarto/contents/vol1/backmatter/appendix_data.qmd

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ This appendix is designed as a *reference*. Use it when you are debugging “slo
2929
Conventions used here follow the book-wide notation (for example, we reserve \(B\) for batch size and use \(\text{BW}\) for bandwidth).
3030

3131
- **When data won’t move**: Start with @tbl-data-gravity and the transfer-time equation in @sec-data-foundations-data-engineering-foundations-0c20.
32-
- **When the accelerator is starving**: Use @tbl-serialization-cost and the layout discussion in @sec-data-foundations-row-vs.-columnar-formats-bca2.
32+
- **When the accelerator is starving**: Use @tbl-serialization-cost and the layout discussion in @sec-data-foundations-row-vs-columnar-formats-bca2.
3333
- **When pipelines explode in cost**: Use the primitives in @sec-data-foundations-algebra-data-9792, especially join-induced shuffles.
3434
- **When “average looks fine” but users complain**: Use @sec-data-foundations-distributions-long-tail-901f and session-level tail probability.
3535
- **When accuracy drifts silently**: Use @sec-data-foundations-measuring-drift-divergence-a6dd to compare full distributions.
@@ -107,7 +107,7 @@ Data gravity[^fn-data-gravity] is not a metaphor; it is a calculation of transfe
107107

108108
[^fn-data-gravity]: **Data Gravity**: Coined by Dave McCrory in 2010 to describe how large datasets attract services and applications toward them, much as massive bodies attract smaller ones in physics. The analogy is apt: the "escape velocity" required to move a petabyte-scale dataset is often measured in weeks.
109109

110-
The transfer time for moving a dataset is simply $T = \text{Data Volume} / \text{Bandwidth}$ (for the large volumes here, latency is negligible; the full equation appears in @sec-machine-foundations-bandwidth-vs.-latency-5320). @tbl-data-gravity illustrates the sobering reality:
110+
The transfer time for moving a dataset is simply $T = \text{Data Volume} / \text{Bandwidth}$ (for the large volumes here, latency is negligible; the full equation appears in @sec-machine-foundations-bandwidth-vs-latency-5320). @tbl-data-gravity illustrates the sobering reality:
111111

112112
| **Data Volume** | **1 Gbps (Standard WAN)** | **10 Gbps (High-End WAN)** | **100 Gbps (Direct Connect)** | **Snowmobile (Truck)** |
113113
|:----------------|----------------------------------------:|-----------------------------------------:|----------------------------------------:|:-----------------------|
@@ -163,23 +163,23 @@ Even after data arrives at the machine, we face one final hurdle: the serializat
163163

164164
[^fn-serialization]: **Serialization**: From Latin *serialis* (forming a series). The process of converting in-memory data structures into a byte stream for storage or transmission, and the reverse (*deserialization*). In ML pipelines, the choice of serialization format can dominate end-to-end training time; @sec-data-engineering covers pipeline design strategies that minimize this overhead.
165165

166-
| **Format** | **Decoding Speed (MB/s)** | **CPU Cycles per Byte** | **Suitability** |
167-
|:--------------------|--------------------------------------------------------:|-----------------------------------------------------------:|:------------------------|
166+
| **Format** | **Decoding Speed (MB/s)** | **CPU Cycles per Byte** | **Suitability** |
167+
|:------------------|--------------------------------------------------------:|-----------------------------------------------------------:|:------------------------|
168168
| **CSV/JSON** | `{python} SerializationCost.csv_speed_str` MB/s | `{python} SerializationCost.csv_cycles_str` cycles | Debugging only |
169-
| **Protobuf** | `{python} SerializationCost.proto_speed_str` MB/s | `{python} SerializationCost.proto_cycles_str` cycles | RPC/Messages |
169+
| **Protobuf** | `{python} SerializationCost.proto_speed_str` MB/s | `{python} SerializationCost.proto_cycles_str` cycles | RPC/Messages |
170170
| **Parquet/Arrow** | **`{python} SerializationCost.parquet_speed_str` MB/s** | **`{python} SerializationCost.parquet_cycles_str` cycles** | **High-Scale Training** |
171171

172172
: **Serialization Overhead.** Zero-copy formats like Arrow are 10--100$\times$ faster than row-based text formats because they align directly with internal memory structures. {#tbl-serialization-cost}
173173

174-
### Row vs. columnar formats {#sec-data-foundations-row-vs.-columnar-formats-bca2}
174+
### Row vs. columnar formats {#sec-data-foundations-row-vs-columnar-formats-bca2}
175175

176176
The choice of file format determines the "physics" of how your data is read.
177177

178178
**Row-Oriented (CSV, JSON)**: Data is stored record-by-record. To read just the `age` column, you must scan every byte of every row. This is efficient for *writing* (appending a log) but inefficient for *analytics* (training on specific features).
179179

180-
**Column-Oriented (Parquet, Arrow)**: Data is stored column-by-column. To read the `age` column, the disk head seeks to that column's block and reads it sequentially. This enables **projection pushdown** (reading only the bytes you need) and **vectorized processing** (single instruction, multiple data (SIMD) operations on columns). Compare the two arrangements side by side in @fig-row-vs.-col to see why columnar access avoids scanning unnecessary bytes.
180+
**Column-Oriented (Parquet, Arrow)**: Data is stored column-by-column. To read the `age` column, the disk head seeks to that column's block and reads it sequentially. This enables **projection pushdown** (reading only the bytes you need) and **vectorized processing** (single instruction, multiple data (SIMD) operations on columns). Compare the two arrangements side by side in @fig-row-vs-col to see why columnar access avoids scanning unnecessary bytes.
181181

182-
::: {#fig-row-vs.-col fig-env="figure" fig-pos="htb" fig-cap="**Storage Layouts**: Row-oriented formats pack data together by record (good for transactions). Column-oriented formats pack data by feature (good for analytics)." fig-alt="Diagram contrasting row store vs. column store. Row store shows Record 1 [ID, Name, Age] followed by Record 2. Column store shows Column 1 [ID1, ID2...] followed by Column 2 [Name1, Name2...]."}
182+
::: {#fig-row-vs-col fig-env="figure" fig-pos="htb" fig-cap="**Storage Layouts**: Row-oriented formats pack data together by record (good for transactions). Column-oriented formats pack data by feature (good for analytics)." fig-alt="Diagram contrasting row store vs. column store. Row store shows Record 1 [ID, Name, Age] followed by Record 2. Column store shows Column 1 [ID1, ID2...] followed by Column 2 [Name1, Name2...]."}
183183
```{.tikz}
184184
\begin{tikzpicture}[font=\small\usefont{T1}{phv}{m}{n}]
185185
\tikzset{

book/quarto/contents/vol1/backmatter/appendix_machine.qmd

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ These numbers reflect the current generation. Use them for back-of-envelope calc
221221

222222
| Level | Latency | Bandwidth |
223223
|:---------------------|-----------------------------------------:|------------------------------------------:|
224-
| Register | ~0.3 ns ||
225-
| L1 Cache | ~`{python} NumbersToKnow.lat_l1_ns` ns ||
226-
| L2 Cache | ~`{python} NumbersToKnow.lat_l2_ns` ns ||
224+
| Register | ~0.3 ns ||
225+
| L1 Cache | ~`{python} NumbersToKnow.lat_l1_ns` ns ||
226+
| L2 Cache | ~`{python} NumbersToKnow.lat_l2_ns` ns ||
227227
| GPU HBM3 | ~`{python} NumbersToKnow.lat_hbm_ns` ns | `{python} NumbersToKnow.bw_hbm_h100` TB/s |
228228
| PCIe Gen5 (CPU↔GPU) | ~`{python} NumbersToKnow.lat_pcie_ns` ns | `{python} NumbersToKnow.bw_pcie5` GB/s |
229229
| CPU DRAM | ~100 ns | `{python} NumbersToKnow.bw_dram` GB/s |
@@ -240,7 +240,7 @@ These numbers reflect the current generation. Use them for back-of-envelope calc
240240
|:-----------------------|------------------------------------------------:|------------------------------------------------:|------:|
241241
| Data center GPU (H100) | `{python} NumbersToKnow.flops_h100_fp16` TFLOPS | `{python} NumbersToKnow.flops_h100_fp8` TOPS | 700 W |
242242
| Data center GPU (A100) | `{python} NumbersToKnow.flops_a100_fp16` TFLOPS | 624 TOPS | 400 W |
243-
| Mobile NPU || `{python} NumbersToKnow.flops_mobile_int8` TOPS | 3–5 W |
243+
| Mobile NPU || `{python} NumbersToKnow.flops_mobile_int8` TOPS | 3–5 W |
244244

245245
: **Compute Reference (c. 2024).** Data center is ~28$\times$ more powerful than mobile—this ratio persists across generations. {#tbl-compute-current-ref}
246246

@@ -924,9 +924,9 @@ The memory hierarchy is the fundamental physical constraint of machine learning
924924

925925
| **Layer** | **Technology** | **Latency** | **Bandwidth** | **Energy (per 32b)** |
926926
|:---------------------|:---------------|----------------------------------------------:|---------------------------------------------------:|-------------------------------------------:|
927-
| **Registers** | Flip-Flops | ~0.3 ns || `{python} AppendixMachineSetup.e_reg` pJ |
928-
| **L1 Cache** | SRAM | ~`{python} AppendixMachineSetup.l1_ns` ns || `{python} AppendixMachineSetup.e_l1` pJ |
929-
| **L2 Cache** | SRAM | ~`{python} AppendixMachineSetup.l2_ns` ns || `{python} AppendixMachineSetup.e_l2` pJ |
927+
| **Registers** | Flip-Flops | ~0.3 ns || `{python} AppendixMachineSetup.e_reg` pJ |
928+
| **L1 Cache** | SRAM | ~`{python} AppendixMachineSetup.l1_ns` ns || `{python} AppendixMachineSetup.e_l1` pJ |
929+
| **L2 Cache** | SRAM | ~`{python} AppendixMachineSetup.l2_ns` ns || `{python} AppendixMachineSetup.e_l2` pJ |
930930
| **Memory (Local)** | HBM3 | ~`{python} AppendixMachineSetup.hbm_ns` ns | `{python} AppendixMachineSetup.bw_hbm_str` GB/s | `{python} AppendixMachineSetup.e_dram` pJ |
931931
| **Interconnect** | NVLink 4.0 | ~`{python} AppendixMachineSetup.nvlink_ns` ns | `{python} AppendixMachineSetup.bw_nvlink_str` GB/s | ~`{python} AppendixMachineSetup.e_dram` pJ |
932932
| **Host Link** | PCIe Gen5 | ~`{python} AppendixMachineSetup.pcie_ns` ns | `{python} AppendixMachineSetup.bw_pcie_str` GB/s | ~`{python} AppendixMachineSetup.e_dram` pJ |
@@ -942,7 +942,7 @@ The hierarchy's energy costs reveal why data movement dominates modern system de
942942
Fetching a 32-bit value from DRAM costs roughly **`{python} AppendixMachineSetup.energy_ratio_str`$\times$ more energy** than performing a floating-point operation on it (for example, ~`{python} AppendixMachineSetup.dram_pj` pJ vs. ~`{python} AppendixMachineSetup.flop_pj` pJ). This "Energy Wall" means that maximizing **arithmetic intensity** (doing many ops per loaded byte) is the only way to be energy efficient.
943943
:::
944944

945-
### Bandwidth vs. Latency {#sec-machine-foundations-bandwidth-vs.-latency-5320}
945+
### Bandwidth vs. Latency {#sec-machine-foundations-bandwidth-vs-latency-5320}
946946

947947
Bandwidth (throughput) and latency (delay) are distinct constraints. Total transfer time follows:
948948

0 commit comments

Comments
 (0)