From ea00a2efcfb047ffea344f4cf4d76066d3acead0 Mon Sep 17 00:00:00 2001 From: Vijay Janapa Reddi Date: Wed, 22 Apr 2026 16:26:05 -0400 Subject: [PATCH] fix(tinytorch-pdf): polish targeted Lab Guide rendering issues Pointed-at fixes from a visual PDF review: - preface.qmd: drop emojis from the astronaut/rocket-scientist opener (XeLaTeX renders them as zero-width glyphs, leaving phantom space before the period); split the colored-card grids into HTML-only and PDF-only branches via :::{.content-visible} so PDF readers get a clean bold-paragraph layout instead of the divs flattening into unstyled prose; remove the JIT/Pin compilers footnote. - modules/04_losses.qmd: blank line before the Case 1/Case 2 bullet lists so Pandoc actually emits them as a list (not run-on prose), plus a PDF-only \medskip between the two cases since callouts collapse paragraph spacing. - milestones/index.qmd, conclusion.qmd: remove stray --- horizontal rules in body content (per project rule: HRs only inside code or style examples). - assets/images/diagrams/03_layers-diag-1.svg: redraw per STYLE.md. Old version had four L-shaped paths starting inside the source box. New version: orange parent at top, three children fanning out below with straight diagonal/vertical arrows, no overlapping geometry. - pdf/_quarto.yml: * fvextra Highlighting/verbatim envs with breaklines so long code lines wrap cleanly inside the page column instead of overflowing the right margin. * \titleformat{\part} so Part divider pages carry the brand: a flameorange "PART I" eyebrow above a torchnavy bold-sans title, bracketed by hairline rules. --- .../images/diagrams/03_layers-diag-1.svg | 46 ++++++++++--------- tinytorch/quarto/conclusion.qmd | 2 - tinytorch/quarto/milestones/index.qmd | 2 - tinytorch/quarto/modules/04_losses.qmd | 8 +++- tinytorch/quarto/pdf/_quarto.yml | 44 ++++++++++++++++++ tinytorch/quarto/preface.qmd | 43 ++++++++++++++--- 6 files changed, 111 insertions(+), 34 deletions(-) diff --git a/tinytorch/quarto/assets/images/diagrams/03_layers-diag-1.svg b/tinytorch/quarto/assets/images/diagrams/03_layers-diag-1.svg index 1101ff3e2..4612dd637 100644 --- a/tinytorch/quarto/assets/images/diagrams/03_layers-diag-1.svg +++ b/tinytorch/quarto/assets/images/diagrams/03_layers-diag-1.svg @@ -1,29 +1,31 @@ - - + + - - - Your Layer System - - Layer Base Class - forward(), parameters() - - Linear Layer - y = xW + b - - Dropout Layer - regularization - - Sequential Container - layer composition - - - - - + + Your Layer System + + + Layer Base Class + forward(), parameters() + + + Linear Layer + y = xW + b + + + Sequential Container + layer composition + + + Dropout Layer + regularization + + + + diff --git a/tinytorch/quarto/conclusion.qmd b/tinytorch/quarto/conclusion.qmd index d4d4857a8..113b4f5bf 100644 --- a/tinytorch/quarto/conclusion.qmd +++ b/tinytorch/quarto/conclusion.qmd @@ -121,6 +121,4 @@ You chose to be both. You did not just fly the rocket. You built it. And now you **Don't import torch. You built it.** ---- - *Share your journey with the TinyTorch community, or explore the [MLSysBook](https://mlsysbook.ai) for the full textbook.* diff --git a/tinytorch/quarto/milestones/index.qmd b/tinytorch/quarto/milestones/index.qmd index d2bbe3804..b3c860e3c 100644 --- a/tinytorch/quarto/milestones/index.qmd +++ b/tinytorch/quarto/milestones/index.qmd @@ -61,6 +61,4 @@ Milestone proves: WHAT you can build with it The combination of modules + milestones ensures you don't just complete exercises — you build something historically significant that works. ---- - **Build the future by understanding the past.** diff --git a/tinytorch/quarto/modules/04_losses.qmd b/tinytorch/quarto/modules/04_losses.qmd index a58500c43..2643508aa 100644 --- a/tinytorch/quarto/modules/04_losses.qmd +++ b/tinytorch/quarto/modules/04_losses.qmd @@ -794,11 +794,17 @@ You're building a medical diagnosis system with 5 disease categories. Should you :::{.callout-note collapse="true" title="Answer"} **Case 1: Mutually exclusive diseases** (patient has exactly one) + - **Use**: CrossEntropyLoss - **Model output**: Logits of shape (batch_size, 5) -- **Why**: Categories are mutually exclusive - softmax ensures probabilities sum to 1.0 +- **Why**: Categories are mutually exclusive — softmax ensures probabilities sum to 1.0 + +::: {.content-visible when-format="pdf"} +\medskip +::: **Case 2: Multi-label classification** (patient can have multiple diseases) + - **Use**: BinaryCrossEntropyLoss - **Model output**: Probabilities of shape (batch_size, 5) after sigmoid - **Why**: Each disease is an independent binary decision. Softmax would incorrectly force them to sum to 1. diff --git a/tinytorch/quarto/pdf/_quarto.yml b/tinytorch/quarto/pdf/_quarto.yml index 109695d21..c644a46ee 100644 --- a/tinytorch/quarto/pdf/_quarto.yml +++ b/tinytorch/quarto/pdf/_quarto.yml @@ -239,6 +239,33 @@ format: \newunicodechar{╚}{\texttt{+}} \newunicodechar{╝}{\texttt{+}} + % ── Code-block line wrapping ──────────────────────────────── + % Pandoc emits highlighted code into the `Highlighting` Verbatim + % environment (from `fancyvrb`). By default that environment does + % NOT break long lines — they overflow the page right margin and + % fall off the printable area. fvextra is a drop-in superset of + % fancyvrb that adds `breaklines`, plus visual cues so a wrapped + % line is unambiguously a continuation, not a new statement. + \usepackage{fvextra} + \DefineVerbatimEnvironment{Highlighting}{Verbatim}{% + breaklines,% + breakanywhere,% + breaksymbolleft={\color{flameorange!60}\hookrightarrow\space},% + breaksymbolright={},% + breakanywheresymbolpre={},% + breakanywheresymbolpost={},% + commandchars=\\\{\}% + } + % Plain ``` fences (no language tag) render through Pandoc's + % `verbatim` environment. Same treatment so ASCII art / shell + % snippets without syntax highlighting also wrap cleanly. + \RecustomVerbatimEnvironment{verbatim}{Verbatim}{% + breaklines,% + breakanywhere,% + breaksymbolleft={\color{flameorange!60}\hookrightarrow\space},% + breaksymbolright={}% + } + % ============================================================= % Professional styling — fancy header/footer, chapter format, % section hierarchy, microtype polish, widow/orphan discipline, @@ -369,6 +396,23 @@ format: % Running head carries just the chapter title (no number). \renewcommand{\chaptermark}[1]{\markboth{#1}{}} + % ── Part page styling ────────────────────────────────────── + % Default `book` class renders Part pages as plain serif black + % "Part I" / "Foundation Tier" stacked centered. Repaint with + % the brand palette so Part dividers carry the same identity as + % chapter openers: flameorange "PART I" eyebrow, torchnavy + % bold sans title, hairline rule above and below to give the + % page weight without any color blocking. + \titleformat{\part}[display] + {\centering\normalfont\sffamily} + {\vspace*{0.15\textheight}% + {\color{flameorange!50}\titlerule[0.6pt]}\vspace{1em}% + {\color{flameorange}\large\bfseries\MakeUppercase{\partname~\thepart}}} + {0.8em} + {\color{torchnavy}\Huge\bfseries} + [\vspace{1em}{\color{flameorange!50}\titlerule[0.6pt]}] + \titlespacing*{\part}{0pt}{0pt}{0pt} + % ── Section hierarchy ────────────────────────────────────── % Sans-serif navy titles, flameorange numerals. Weight and % color fade as level depth increases so the reader's eye diff --git a/tinytorch/quarto/preface.qmd b/tinytorch/quarto/preface.qmd index 4bc506d31..759773fab 100644 --- a/tinytorch/quarto/preface.qmd +++ b/tinytorch/quarto/preface.qmd @@ -6,7 +6,7 @@ title: "Welcome" TinyTorch -Everyone wants to be an astronaut 🧑‍🚀. Very few want to be the rocket scientist 🚀. +Everyone wants to be an astronaut. Very few want to be the rocket scientist. In machine learning, we see the same pattern. Everyone wants to train models, run inference, deploy AI. Very few want to understand how the frameworks actually work. Even fewer want to build one. @@ -59,38 +59,51 @@ This is how people move from *using* machine learning to *engineering* machine l ## Who This Is For +::: {.content-visible when-format="html"} +
-🎓 Students & Researchers +Students & Researchers

Want to understand ML systems deeply, not just use them superficially. If you've wondered "how does that actually work?", this is for you.

-⚙ ML Engineers +ML Engineers

Need to debug, optimize, and deploy models in production. Understanding the systems underneath makes you more effective.

-💻 Systems Programmers +Systems Programmers

You understand memory hierarchies, computational complexity, performance optimization. You want to apply it to ML.

-🛠 Self-taught Engineers +Self-taught Engineers

Can use frameworks but want to know how they work. Preparing for ML infrastructure roles and need systems-level understanding.

-What you need is not another API tutorial. You need to build.[^pin] +::: +::: {.content-visible when-format="pdf"} -[^pin]: My own background was in compilers, specifically just-in-time (JIT) compilation. But I did not become a systems engineer by reading papers alone. I became one by building [Pin](https://software.intel.com/content/www/us/en/develop/articles/pin-a-dynamic-binary-instrumentation-tool.html), a dynamic binary instrumentation engine that uses JIT technology. The lesson stayed with me: reading teaches concepts, but building deepens understanding. +**Students & Researchers** — want to understand ML systems deeply, not just use them superficially. If you've wondered "how does that actually work?", this is for you. + +**ML Engineers** — need to debug, optimize, and deploy models in production. Understanding the systems underneath makes you more effective. + +**Systems Programmers** — you understand memory hierarchies, computational complexity, performance optimization. You want to apply it to ML. + +**Self-taught Engineers** — can use frameworks but want to know how they work. Preparing for ML infrastructure roles and need systems-level understanding. + +::: + +What you need is not another API tutorial. You need to build. ## What You Will Build @@ -112,6 +125,8 @@ This is not a simulation. This is the actual architecture of modern ML framework Each module follows a **Build-Use-Reflect** cycle: implement from scratch, apply to real problems, then connect what you built to production systems and understand the tradeoffs. Work through Foundation first, then choose your path based on your interests. +::: {.content-visible when-format="html"} +
@@ -140,6 +155,20 @@ Each module follows a **Build-Use-Reflect** cycle: implement from scratch, apply
+::: + +::: {.content-visible when-format="pdf"} + +**Type every line yourself** — do not copy-paste. The learning happens in the struggle of implementation. + +**Profile your code** — use the built-in profiling tools. Measure first, optimize second. + +**Run the tests** — every module includes comprehensive tests. When they pass, you have built something real. + +**Compare with PyTorch** — once your implementation works, compare with PyTorch's equivalent to see how production frameworks scale the same ideas. + +::: + Take your time. The goal is not to finish fast. The goal is to understand deeply.