Skip to content

Commit 852b594

Browse files
committed
Format Vol1 Python blocks; fix Fig 7.6 caption widow; tighten Listing 6.7
Bring Vol1 display code blocks into Black display-70 compliance so the CI pre-commit pass makes no modifications. Tighten Listing 6.7 by putting the attention-scores comment on its own line above the single-line computation and dropping the redundant Core computational pattern comment. Trim the Figure 7.6 caption to pull utilization onto the previous line and remove a one-word widow. Shorten the training Step 3 comment to avoid a wrapped line.
1 parent e4a2e40 commit 852b594

13 files changed

Lines changed: 30 additions & 49 deletions

File tree

book/quarto/contents/vol1/benchmarking/benchmarking.qmd

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,13 +2708,13 @@ These metrics interact through unavoidable trade-offs. Optimizing for high throu
27082708

27092709
Deployment scenario determines the priority order among those metrics. The operational constraints and success criteria vary dramatically across contexts, so metric priorities help engineers focus benchmarking effort and interpret results within the right decision framework. @Tbl-metric-priorities illustrates how performance priorities shift across five major deployment contexts, revealing the systematic relationship between operational constraints and optimization targets.
27102710

2711-
| **Deployment Context** | **Primary Priority** | **Secondary Priority** | **Tertiary Priority** | **Key Design Constraint** |
2712-
|:---------------------------|:---------------------|:-----------------------|:----------------------|:--------------------------------------------------|
2713-
| **Real-Time Applications** | Latency (p95 < 50 ms)| Reliability (99.9%) | Memory Footprint | User experience demands immediate response |
2714-
| **Cloud-Scale Services** | Throughput (QPS) | Cost Efficiency | Average Latency | Business viability requires massive scale |
2715-
| **Edge/Mobile Devices** | Power Consumption | Memory Footprint | Latency | Battery life and resource limits dominate |
2716-
| **Training Workloads** | Training Time | GPU Utilization | Memory Efficiency | Research velocity enables faster experimentation |
2717-
| **Scientific/Medical** | Accuracy | Reliability | Explainability | Correctness cannot be compromised for performance |
2711+
| **Deployment Context** | **Primary Priority** | **Secondary Priority** | **Tertiary Priority** | **Key Design Constraint** |
2712+
|:---------------------------|:----------------------|:-----------------------|:----------------------|:--------------------------------------------------|
2713+
| **Real-Time Applications** | Latency (p95 < 50 ms) | Reliability (99.9%) | Memory Footprint | User experience demands immediate response |
2714+
| **Cloud-Scale Services** | Throughput (QPS) | Cost Efficiency | Average Latency | Business viability requires massive scale |
2715+
| **Edge/Mobile Devices** | Power Consumption | Memory Footprint | Latency | Battery life and resource limits dominate |
2716+
| **Training Workloads** | Training Time | GPU Utilization | Memory Efficiency | Research velocity enables faster experimentation |
2717+
| **Scientific/Medical** | Accuracy | Reliability | Explainability | Correctness cannot be compromised for performance |
27182718

27192719
: **Performance Metric Priorities by Deployment Context**: Different operational environments demand distinct optimization focuses, reflecting varying constraints and success criteria. These priorities guide both benchmark selection and result interpretation. {#tbl-metric-priorities tbl-colwidths="[18,19,18,17,28]"}
27202720

book/quarto/contents/vol1/data_engineering/data_engineering.qmd

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,6 @@ Just as systems engineers memorize latency numbers, ML engineers should internal
15621562

15631563
@Tbl-data-engineering-time-constants extends the picture with characteristic durations for labeling, training, and serving operations.
15641564

1565-
15661565
```{python}
15671566
#| echo: false
15681567
@@ -1661,7 +1660,6 @@ class DataEngineeringTimeConstants:
16611660

16621661
: **Data Engineering Time Constants**: Characteristic durations for labeling, training, and serving operations span about `{python} DataEngineeringTimeConstants.span_orders_str` orders of magnitude. Human labeling sets the wall-clock floor for new datasets, making it the dominant scheduling constraint in production ML systems. {#tbl-data-engineering-time-constants tbl-colwidths="[40,34,36]"}
16631662

1664-
16651663
All cost figures reflect approximate 2024 cloud provider rates and are intended to convey relative magnitudes rather than exact pricing.[^fn-pricing-cost-ratios] The consistent pattern across these numbers is that human labor (labeling, annotation, expert review) dominates hardware and storage costs by one to three orders of magnitude. A team that optimizes its labeling pipeline before scaling compute or storage addresses the largest cost term first.
16661664

16671665
```{python}

book/quarto/contents/vol1/data_selection/data_selection.qmd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,9 +2164,9 @@ An `{python} FixmatchLabelEfficiency.cost_reduction_mult_str` cost reduction for
21642164

21652165
The systems trade-off in semi-supervised learning is straightforward: it typically achieves the same accuracy as fully supervised training with 5--10$\times$ fewer labels but requires more compute because training processes both labeled and unlabeled samples. Since labeling costs often dominate compute costs in production settings, this trade-off is usually favorable. A CIFAR-10 comparison makes this label efficiency concrete.
21662166

2167-
| **Label Budget** | **Method** | **Accuracy** | **Label Efficiency** |
2167+
| **Label Budget** | **Method** | **Accuracy** | **Label Efficiency** |
21682168
|:----------------------------------------------------------------------------------------------------------------------------------------------|:-----------------|:---------------------------------------------------------------:|--------------------------------------------------------------------------------------------------:|
2169-
| **`{python} FixmatchLabelEfficiency.cifar10_full_labels_str` (`{python} FixmatchLabelEfficiency.cifar10_full_frac_pct_str`)** | Fully Supervised | `{python} FixmatchLabelEfficiency.cifar10_full_acc_str` | Baseline |
2169+
| **`{python} FixmatchLabelEfficiency.cifar10_full_labels_str` (`{python} FixmatchLabelEfficiency.cifar10_full_frac_pct_str`)** | Fully Supervised | `{python} FixmatchLabelEfficiency.cifar10_full_acc_str` | Baseline |
21702170
| **`{python} FixmatchLabelEfficiency.cifar10_fixmatch_4k_labels_str` (`{python} FixmatchLabelEfficiency.cifar10_fixmatch_4k_frac_pct_str`)** | FixMatch | `{python} FixmatchLabelEfficiency.cifar10_fixmatch_4k_acc_str` | `{python} FixmatchLabelEfficiency.cifar10_fixmatch_4k_efficiency_factor_mult_str` more efficient |
21712171
| **`{python} FixmatchLabelEfficiency.cifar10_fixmatch_250_labels_str` (`{python} FixmatchLabelEfficiency.cifar10_fixmatch_250_frac_pct_str`)** | FixMatch | `{python} FixmatchLabelEfficiency.cifar10_fixmatch_250_acc_str` | `{python} FixmatchLabelEfficiency.cifar10_fixmatch_250_efficiency_factor_mult_str` more efficient |
21722172
| **`{python} FixmatchLabelEfficiency.cifar10_fixmatch_40_labels_str` (`{python} FixmatchLabelEfficiency.cifar10_fixmatch_40_frac_pct_str`)** | FixMatch | `{python} FixmatchLabelEfficiency.cifar10_fixmatch_40_acc_str` | `{python} FixmatchLabelEfficiency.cifar10_fixmatch_40_efficiency_factor_mult_str` more efficient |
@@ -2604,11 +2604,11 @@ Together, augmentation, generative synthesis, and distillation complete the thir
26042604

26052605
When labeling budget, redundancy, rare classes, privacy, and convergence speed all matter at once, the practitioner first has to identify which constraint is binding. Each stage raises the information-compute ratio by a different mechanism: pruning removes low-value samples before training, dynamic selection focuses compute on high-value samples during training, and synthesis creates new high-value samples on demand (@tbl-data-selection).
26062606

2607-
| **Stage** | **When Applied** | **Techniques** | **Typical Gains** |
2607+
| **Stage** | **When Applied** | **Techniques** | **Typical Gains** |
26082608
|:-------------------------|:-----------------|:------------------------------------------------------|:-----------------------------------------------------|
2609-
| **Static pruning** | Before training | Coreset Selection, Deduplication, Quality Filtering | 30–50% dataset reduction |
2609+
| **Static pruning** | Before training | Coreset Selection, Deduplication, Quality Filtering | 30–50% dataset reduction |
26102610
| **Dynamic selection** | During training | Curriculum Learning, Active Learning, Semi-Supervised | 10–30% faster curricula; 2--100$\times$ fewer labels |
2611-
| **Synthetic generation** | On-demand | Augmentation, Generative Models, Distillation | 2--10$\times$ effective data expansion |
2611+
| **Synthetic generation** | On-demand | Augmentation, Generative Models, Distillation | 2--10$\times$ effective data expansion |
26122612

26132613
: **Three-Stage Data Selection Pipeline**: When each stage applies, its representative techniques, and the efficiency gains typically reported for each. {#tbl-data-selection .striped .hover tbl-colwidths="[23,21,28,28]"}
26142614

book/quarto/contents/vol1/frameworks/frameworks.qmd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1412,7 +1412,7 @@ Fusion wins on two fronts at once. Collapsing two launches into one halves the p
14121412

14131413
@Fig-python-tax makes the dispatch tax visible: eager execution creates gaps where the GPU sits idle while Python dispatches the next kernel. The blue compute regions are short; the red dispatch regions are comparatively long. Compilation fuses these operations into a single kernel launch, replacing many dispatch gaps with one dispatch block and one fused compute block.
14141414

1415-
::: {#fig-python-tax fig-env="figure" fig-pos="htb" fig-cap="**The Python Tax**: Visualizing the overhead analysis from the preceding callout. In Eager Mode (top), the GPU (blue) finishes processing each op in microseconds but must sit idle while the Python interpreter (red) dispatches the next kernel launch. Compilation (bottom) fuses these operations into one kernel launch, reducing repeated dispatch gaps and improving utilization." fig-alt="Gantt chart of execution timeline. Eager mode shows alternating red Python dispatch and blue GPU kernel blocks. Compiled mode shows one red dispatch block followed by one fused blue compute block."}
1415+
::: {#fig-python-tax fig-env="figure" fig-pos="htb" fig-cap="**The Python Tax**: Visualizing the overhead analysis from the preceding callout. In Eager Mode (top), the GPU (blue) finishes processing each op in microseconds but must sit idle while the Python interpreter (red) dispatches the next kernel launch. Compilation (bottom) fuses these operations into one kernel launch, reducing dispatch gaps and improving utilization." fig-alt="Gantt chart of execution timeline. Eager mode shows alternating red Python dispatch and blue GPU kernel blocks. Compiled mode shows one red dispatch block followed by one fused blue compute block."}
14161416

14171417
```{python}
14181418
#| echo: false
@@ -3763,6 +3763,7 @@ Complex models compose from reusable submodules\index{nn.Module!hierarchical com
37633763
import torch
37643764
import torch.nn as nn
37653765
3766+
37663767
class ResidualBlock(nn.Module):
37673768
def __init__(self, channels):
37683769
super().__init__()
@@ -3777,6 +3778,7 @@ class ResidualBlock(nn.Module):
37773778
x = self.bn2(self.conv2(x))
37783779
return torch.relu(x + residual)
37793780
3781+
37803782
class ResNet(nn.Module):
37813783
def __init__(self, num_blocks, channels=64):
37823784
super().__init__()
@@ -3793,6 +3795,7 @@ class ResNet(nn.Module):
37933795
x = x.mean(dim=[2, 3]) # Global average pooling
37943796
return self.fc(x)
37953797
3798+
37963799
model = ResNet(num_blocks=4)
37973800
total = sum(p.numel() for p in model.parameters())
37983801
print(f"Total parameters: {total}")

book/quarto/contents/vol1/hw_acceleration/hw_acceleration.qmd

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5882,7 +5882,6 @@ This checklist synthesizes the principles developed throughout this chapter, tra
58825882

58835883
Hardware acceleration is the force that transformed machine learning from academic curiosity to practical reality, reshaping how we design both computational systems and the algorithms that run on them. The evolution from general-purpose processors to specialized AI accelerators reflects a shift toward domain-specific computing where hardware and software are co-designed to optimize specific computational patterns. The progression from CPUs through GPUs to specialized TPUs, NPUs, and wafer-scale systems demonstrates how understanding workload characteristics drives architectural innovation, creating opportunities for orders-of-magnitude performance improvements through targeted specialization.
58845884

5885-
58865885
```{python}
58875886
#| echo: false
58885887
#| label: summary-roofline-recap
@@ -5919,7 +5918,6 @@ The technical challenges of AI acceleration span multiple layers of the computin
59195918

59205919
Engineers who internalize the Roofline model and arithmetic intensity analysis gain a diagnostic framework: when inference runs slower than expected, they can immediately determine whether the bottleneck lies in compute throughput, memory bandwidth, or software overhead, and then select the appropriate optimization strategy. This systems-level understanding transforms hardware selection from vendor comparison into principled engineering.
59215920

5922-
59235921
::: {.callout-chapter-connection title="From optimization to validation"}
59245922

59255923
We have now optimized the full D·A·M stack: data selection minimized training requirements, model compression reduced algorithmic complexity, and hardware acceleration maximized machine throughput. Optimization without measurement, however, is guesswork. In @sec-benchmarking, we move from theoretical FLOPs to measured latency, applying the roofline model and statistical methods to validate our optimization claims against reality.

book/quarto/contents/vol1/ml_systems/ml_systems.qmd

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,6 @@ pics/mobile/.style = {
251251
```
252252
:::
253253

254-
255-
256254
```{python}
257255
#| echo: false
258256
# ┌─────────────────────────────────────────────────────────────────────────────
@@ -644,7 +642,6 @@ Throughout this book, we use the five Lighthouse Models summarized in @tbl-ml-sy
644642
```
645643
:::
646644

647-
648645
These archetypes map naturally to deployment paradigms. Compute beasts and sparse scatter workloads gravitate toward cloud ML where resources are abundant, bandwidth hogs span cloud and edge depending on latency requirements, and tiny constraint workloads belong to TinyML. To make these abstractions concrete, we anchor each archetype to a specific model that recurs throughout this book as one of five reference workloads.
649646

650647
To ground the abstract interdependencies of the iron law in concrete practice, we analyze these five Lighthouse Models in turn. The following summaries recap each workload from a systems perspective, connecting them to the specific iron law bottlenecks they exemplify.
@@ -1691,7 +1688,6 @@ Cloud deployments also carry operational constraints. Unpredictable usage spikes
16911688

16921689
: **Edge Inference Annual TCO**: Itemized hardware, power, cooling, network, and DevOps labor costs for the on-premise T4 implementation, exposing labor as the dominant component that determines edge break-even economics. {#tbl-ml-systems-edge-tco tbl-colwidths="[33,37,30]"}
16931690

1694-
16951691
::: {#nbk-ml-systems-cloud-vs-edge-tco .callout-notebook title="Cloud vs. edge TCO"}
16961692

16971693
**Problem**: A vision system serves `{python} CloudEdgeTCO.requests_str` daily inferences at ResNet-50 scale (`{python} CloudEdgeTCO.inference_ms_str` latency, `{python} CloudEdgeTCO.response_kb_str` response). When all costs are included (GPU hours, network egress, power, cooling, and labor, itemized in @tbl-ml-systems-cloud-tco and @tbl-ml-systems-edge-tco), is cloud or on-premises edge deployment cheaper over `{python} CloudEdgeTCO.server_life_years_str`?
@@ -2632,7 +2628,6 @@ above=0.5of $(B2.north east)!0.5!(B3.north west)$](B0){Mobile ML};
26322628

26332629
:::
26342630

2635-
26362631
```{python}
26372632
#| echo: false
26382633
#| label: battery-tax
@@ -2697,7 +2692,6 @@ class BatteryTax:
26972692

26982693
:::
26992694

2700-
27012695
::: {.column-margin}
27022696
![](images/svg/vol1_ml_systems_margin_003.svg){width="100%" fig-alt="Two horizontal throughput levels: a high burst line and, well below it, a lower sustained line after thermal throttling engages."}
27032697

book/quarto/contents/vol1/ml_workflow/ml_workflow.qmd

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Here, *lifecycle* describes the stages themselves and *workflow* describes the e
116116
text width=25mm,
117117
minimum width=25mm, minimum height=23mm
118118
},
119-
Box1/.style={Box, node distance=3.7,text width=28mm,minimum width=28mm,fill=BlueFill,draw=BlueLine
119+
Box1/.style={Box, node distance=3.7,text width=28mm,minimum width=28mm,fill=BlueFill,draw=BlueLine
120120
},
121121
Line/.style={line width=1.30pt,black!50,text=black, -{Triangle[length=3mm, width=1.75mm]}},
122122
Text/.style={font=\usefont{T1}{phv}{m}{n}\footnotesize,align=center
@@ -987,7 +987,6 @@ class ConstraintPropagation:
987987

988988
:::
989989

990-
991990
## Problem Definition {#sec-ml-workflow-problem-definition-stage-5974}
992991

993992
Problem definition\index{Problem Definition!ML vs. traditional} in ML begins with sentences that look deceptively simple. A product manager writes: "Build a model that detects diabetic retinopathy." That single sentence conceals a dozen engineering decisions: sensitivity thresholds for patient safety, hardware capabilities in rural clinics, latency budgets that keep clinicians engaged, and regulatory frameworks governing approval. In traditional software, requirements translate directly into implementation rules. In ML systems, defining *what* the system should do is inseparable from defining *how* it will learn to do it—and the physical constraints under which it must operate. This first stage, the leftmost box in @fig-lifecycle-overview, lays the foundation for all subsequent phases in the ML lifecycle.

book/quarto/contents/vol1/model_compression/model_compression.qmd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3661,7 +3661,6 @@ FP16\index{FP16!training}\index{FP16!reduced dynamic range}\index{Quantization!F
36613661

36623662
: **Numerical Precision Formats**: Comparison of precision formats by bit width, memory reduction, computational efficiency, accuracy retention, and typical use cases across deployment contexts. {#tbl-numerics tbl-colwidths="[21,10,13,18,12,26]"}
36633663

3664-
36653664
Compare the three bit layouts in @fig-3float to see exactly where the bits go—and why the trade-off between precision and numerical range differs so sharply across formats.
36663665

36673666
::: {#fig-3float fig-env="figure" fig-pos="htb" fig-cap="**Floating-Point Precision**: Reduced-precision formats like FP16 and BF16 trade off numerical range for computational efficiency and memory savings. BF16 maintains the exponent size of FP32, preserving its dynamic range and suitability for training, while FP16's smaller exponent limits its use to inference or carefully scaled training scenarios." fig-alt="Three horizontal bit-layout diagrams. FP32 shows 1-bit sign, 8-bit exponent, 23-bit mantissa. FP16 shows 1-bit sign, 5-bit exponent, 10-bit mantissa. BF16 shows 1-bit sign, 8-bit exponent, 7-bit mantissa."}

0 commit comments

Comments
 (0)