# TinyTorch: Don't just import torch. Build it. # PDF-Specific Configuration title: "TinyTorch" subtitle: "Don't just `import torch`. Build it." author: "Prof. Vijay Janapa Reddi (Harvard University)" copyright: "2025" logo: _static/logos/logo-tinytorch-white.png # Book description description: >- An interactive course for building machine learning systems from the ground up. Learn by implementing your own PyTorch-style framework with hands-on coding, real datasets, and production-ready practices. # Execution settings - cache mode enables {glue} computed values in ABOUT.md files execute: execute_notebooks: "cache" allow_errors: true timeout: 300 # Exclude patterns exclude_patterns: - _build - .venv - appendices - "**/.venv/**" - "**/__pycache__/**" - "**/.DS_Store" # GitHub repository (for reference in PDF) repository: url: https://github.com/harvard-edge/cs249r_book path_to_book: docs branch: main # LaTeX/PDF output configuration latex: latex_engine: xelatex use_jupyterbook_latex: false latex_documents: targetname: tinytorch-course.tex # Bibliography support bibtex_bibfiles: - references.bib # Sphinx extensions sphinx: extra_extensions: - sphinxcontrib.mermaid config: mermaid_version: "10.6.1" # Use npx so PDF build works without global mermaid-cli (requires Node.js) mermaid_cmd: "npx -y @mermaid-js/mermaid-cli" # Render mermaid as PDF for LaTeX # --pdfFit scales PDF to fit the diagram (not full page) # --scale 1.0 keeps diagrams at natural size (1.5 was too large for tall diagrams) mermaid_output_format: "pdf" # Width 600 constrains diagram viewport; scale 1 = natural size # Smaller viewport + pdfcrop produces tighter diagrams that don't stretch to full page width mermaid_params: ['--pdfFit', '--scale', '1', '--width', '600', '--backgroundColor', 'white'] # Use pdfcrop to trim whitespace from mermaid PDFs mermaid_pdfcrop: "pdfcrop" # Use professional sans-serif font for mermaid diagrams to match document mermaid_init_js: "mermaid.initialize({startOnLoad:true, theme:'base', themeVariables:{fontFamily:'Helvetica, Arial, sans-serif', fontSize:'14px'}});" # Custom admonition colors for PDF - make each type visually distinct sphinxsetup: >- noteBorderColor={RGB}{66,139,202}, noteBgColor={RGB}{232,244,253}, tipBorderColor={RGB}{92,184,92}, tipBgColor={RGB}{223,240,216}, warningBorderColor={RGB}{240,173,78}, warningBgColor={RGB}{252,248,227}, cautionBorderColor={RGB}{217,83,79}, cautionBgColor={RGB}{242,222,222}, dangerBorderColor={RGB}{169,68,66}, dangerBgColor={RGB}{242,222,222}, attentionBorderColor={RGB}{138,109,59}, attentionBgColor={RGB}{252,248,227}, importantBorderColor={RGB}{70,136,71}, importantBgColor={RGB}{223,240,216}, hintBorderColor={RGB}{60,118,61}, hintBgColor={RGB}{223,240,216}, seealsobordercolor={RGB}{128,0,128}, seealsobgcolor={RGB}{245,238,248} # PDF-specific settings jupyterbook_latex_engine: 'xelatex' latex_toplevel_sectioning: 'chapter' latex_theme: 'manual' latex_elements: papersize: 'letterpaper' pointsize: '10pt' figure_align: 'H' # Pass 'export' option to adjustbox before Sphinx loads it (avoids option clash). # This enables max width/height keys in \includegraphics for mermaid figure capping. passoptionstopackages: '\PassOptionsToPackage{export}{adjustbox}' fontpkg: | % Professional academic font stack (TeX Gyre - available in TeX Live) \usepackage{fontspec} \defaultfontfeatures{Renderer=HarfBuzz} \setmainfont{TeX Gyre Pagella} % Palatino equivalent \setsansfont{TeX Gyre Heros} % Helvetica equivalent \setmonofont{TeX Gyre Cursor}[Scale=0.88] % Courier equivalent (code) preamble: | % TOC depth: show subsections (###) in table of contents \setcounter{secnumdepth}{3} \setcounter{tocdepth}{3} % Graphics and color support \usepackage{graphicx} \usepackage{xcolor} \usepackage{booktabs} \usepackage{tcolorbox} \usepackage{hyperref} \usepackage{float} % Cap Mermaid diagram width at 75% of text width. % sphinxcontrib-mermaid hardcodes width=\linewidth for all diagrams, % which stretches small flowcharts to full page width. This override % intercepts \includegraphics and uses adjustbox's max width for % mermaid-*.pdf files while passing other images through unchanged. % Note: adjustbox 'export' option passed via passoptionstopackages above. \let\OrigIncludeGraphics\includegraphics \makeatletter \renewcommand{\includegraphics}[2][]{% \begingroup \def\@mermaidtest{mermaid-}% \@expandtwoargs\in@{\@mermaidtest}{#2}% \ifin@ \OrigIncludeGraphics[max width=0.75\linewidth,max height=0.45\textheight,keepaspectratio]{#2}% \else \OrigIncludeGraphics[#1]{#2}% \fi \endgroup } \makeatother % Better figure placement - keep figures inline with text \renewcommand{\topfraction}{0.9} \renewcommand{\bottomfraction}{0.9} \renewcommand{\textfraction}{0.05} \renewcommand{\floatpagefraction}{0.9} % Force figures to appear where defined (not float away) \usepackage{placeins} \let\Oldsection\section \renewcommand{\section}{\FloatBarrier\Oldsection} \let\Oldsubsection\subsection \renewcommand{\subsection}{\FloatBarrier\Oldsubsection} % Make all figures use [H] placement by default \makeatletter \renewenvironment{figure}[1][htbp]{% \@float{figure}[H]% }{% \end@float } \makeatother % TinyTorch brand colors - refined palette \definecolor{torchnavy}{RGB}{27,58,95} % Deep navy - headings only \definecolor{flameorange}{RGB}{255,130,70} % Softer coral orange - easier on eyes \definecolor{flamered}{RGB}{210,35,65} % Warmer red for syntax \definecolor{bodygray}{RGB}{40,40,40} % Near-black for body text \definecolor{codebackground}{RGB}{255,248,240} % Very light peachy background \definecolor{accentwarm}{RGB}{255,160,100} % Soft warm accent % Unicode character support for arrows and symbols \usepackage{newunicodechar} \newunicodechar{→}{$\rightarrow$} \newunicodechar{←}{$\leftarrow$} \newunicodechar{↔}{$\leftrightarrow$} \newunicodechar{⟶}{$\longrightarrow$} \newunicodechar{×}{$\times$} \newunicodechar{÷}{$\div$} \newunicodechar{≈}{$\approx$} \newunicodechar{≠}{$\neq$} \newunicodechar{≤}{$\leq$} \newunicodechar{≥}{$\geq$} \newunicodechar{∈}{$\in$} \newunicodechar{∞}{$\infty$} \newunicodechar{√}{$\sqrt{}$} \newunicodechar{∑}{$\sum$} \newunicodechar{∏}{$\prod$} \newunicodechar{∂}{$\partial$} \newunicodechar{∇}{$\nabla$} \newunicodechar{α}{$\alpha$} \newunicodechar{β}{$\beta$} \newunicodechar{γ}{$\gamma$} \newunicodechar{δ}{$\delta$} \newunicodechar{ε}{$\epsilon$} \newunicodechar{θ}{$\theta$} \newunicodechar{λ}{$\lambda$} \newunicodechar{μ}{$\mu$} \newunicodechar{σ}{$\sigma$} \newunicodechar{τ}{$\tau$} \newunicodechar{φ}{$\phi$} \newunicodechar{ω}{$\omega$} \newunicodechar{✓}{\checkmark} \newunicodechar{✗}{$\times$} % Box-drawing (terminal/code art) - TeX Gyre Cursor has no Unicode box glyphs \newunicodechar{═}{\texttt{=}} \newunicodechar{║}{\texttt{|}} \newunicodechar{╔}{\texttt{+}} \newunicodechar{╗}{\texttt{+}} \newunicodechar{╚}{\texttt{+}} \newunicodechar{╝}{\texttt{+}} % Syntax-highlighted code blocks with refined colors \usepackage{listings} \lstset{ basicstyle=\ttfamily\footnotesize\color{bodygray}, backgroundcolor=\color{codebackground}, frame=leftline, framesep=10pt, framerule=3pt, rulecolor=\color{flameorange}, numbers=none, breaklines=true, showstringspaces=false, commentstyle=\color{torchnavy!60}\itshape, keywordstyle=\color{torchnavy}\bfseries, stringstyle=\color{flamered}, xleftmargin=15pt, framexleftmargin=15pt } % TikZ for neural network decorations \usepackage{tikz} \usetikzlibrary{calc,positioning,decorations.pathmorphing} % Custom title page with TinyTorch branding - Asymmetric Neural Network Design \makeatletter \renewcommand{\sphinxmaketitle}{% \begin{titlepage} % Neural network border decorations - asymmetric diagonal flow \begin{tikzpicture}[remember picture, overlay] % Define node styles \tikzset{ neuron/.style={circle, fill=flameorange!30, draw=flameorange!60, minimum size=6pt, inner sep=0pt}, neuron-small/.style={circle, fill=torchnavy!20, draw=torchnavy!40, minimum size=4pt, inner sep=0pt}, neuron-tiny/.style={circle, fill=torchnavy!12, draw=torchnavy!25, minimum size=3pt, inner sep=0pt}, neuron-accent/.style={circle, fill=flameorange!50, draw=flameorange, minimum size=8pt, inner sep=0pt}, neuron-large/.style={circle, fill=flameorange!40, draw=flameorange!70, minimum size=10pt, inner sep=0pt}, connection/.style={draw=torchnavy!15, line width=0.4pt}, connection-accent/.style={draw=flameorange!25, line width=0.5pt} } % TOP-LEFT: Dense primary cluster (8 nodes) - main visual anchor \node[neuron-large] (tl1) at ($(current page.north west)+(2.0cm,-2.0cm)$) {}; \node[neuron-accent] (tl2) at ($(tl1)+(0.7cm,-0.2cm)$) {}; \node[neuron] (tl3) at ($(tl1)+(0.4cm,-0.8cm)$) {}; \node[neuron] (tl4) at ($(tl1)+(1.2cm,-0.6cm)$) {}; \node[neuron-small] (tl5) at ($(tl1)+(0.5cm,0.5cm)$) {}; \node[neuron-small] (tl6) at ($(tl1)+(1.5cm,-0.1cm)$) {}; \node[neuron-small] (tl7) at ($(tl1)+(1.0cm,-1.2cm)$) {}; \node[neuron-tiny] (tl8) at ($(tl1)+(1.8cm,-0.8cm)$) {}; \draw[connection-accent] (tl1) -- (tl2); \draw[connection-accent] (tl1) -- (tl3); \draw[connection] (tl2) -- (tl4); \draw[connection] (tl3) -- (tl4); \draw[connection] (tl1) -- (tl5); \draw[connection] (tl2) -- (tl6); \draw[connection] (tl4) -- (tl7); \draw[connection] (tl6) -- (tl8); \draw[connection] (tl4) -- (tl8); % TOP-RIGHT: Sparse cluster (4 nodes) - lighter weight \node[neuron] (tr1) at ($(current page.north east)+(-1.6cm,-1.5cm)$) {}; \node[neuron-small] (tr2) at ($(tr1)+(-0.5cm,-0.4cm)$) {}; \node[neuron-tiny] (tr3) at ($(tr1)+(-0.9cm,-0.2cm)$) {}; \node[neuron-tiny] (tr4) at ($(tr1)+(-0.3cm,-0.9cm)$) {}; \draw[connection] (tr1) -- (tr2); \draw[connection] (tr2) -- (tr3); \draw[connection] (tr1) -- (tr4); % BOTTOM-LEFT: Sparse cluster (4 nodes) - lighter weight \node[neuron] (bl1) at ($(current page.south west)+(1.5cm,1.6cm)$) {}; \node[neuron-small] (bl2) at ($(bl1)+(0.5cm,0.4cm)$) {}; \node[neuron-tiny] (bl3) at ($(bl1)+(0.9cm,0.1cm)$) {}; \node[neuron-tiny] (bl4) at ($(bl1)+(0.2cm,0.9cm)$) {}; \draw[connection] (bl1) -- (bl2); \draw[connection] (bl2) -- (bl3); \draw[connection] (bl1) -- (bl4); % BOTTOM-RIGHT: Dense secondary cluster (8 nodes) - diagonal balance \node[neuron-large] (br1) at ($(current page.south east)+(-2.0cm,2.0cm)$) {}; \node[neuron-accent] (br2) at ($(br1)+(-0.7cm,0.2cm)$) {}; \node[neuron] (br3) at ($(br1)+(-0.4cm,0.8cm)$) {}; \node[neuron] (br4) at ($(br1)+(-1.2cm,0.6cm)$) {}; \node[neuron-small] (br5) at ($(br1)+(-0.5cm,-0.5cm)$) {}; \node[neuron-small] (br6) at ($(br1)+(-1.5cm,0.1cm)$) {}; \node[neuron-small] (br7) at ($(br1)+(-1.0cm,1.2cm)$) {}; \node[neuron-tiny] (br8) at ($(br1)+(-1.8cm,0.8cm)$) {}; \draw[connection-accent] (br1) -- (br2); \draw[connection-accent] (br1) -- (br3); \draw[connection] (br2) -- (br4); \draw[connection] (br3) -- (br4); \draw[connection] (br1) -- (br5); \draw[connection] (br2) -- (br6); \draw[connection] (br4) -- (br7); \draw[connection] (br6) -- (br8); \draw[connection] (br4) -- (br8); % Left edge: scattered pathway nodes (organic placement) \node[neuron-small] (le1) at ($(current page.west)+(0.9cm,4.5cm)$) {}; \node[neuron-tiny] (le2) at ($(current page.west)+(1.2cm,2.8cm)$) {}; \node[neuron-tiny] (le3) at ($(current page.west)+(0.7cm,0.5cm)$) {}; \node[neuron-small] (le4) at ($(current page.west)+(1.0cm,-1.5cm)$) {}; \draw[connection] (le1) -- (le2); \draw[connection] (le3) -- (le4); % Right edge: scattered pathway nodes (organic placement) \node[neuron-tiny] (re1) at ($(current page.east)+(-0.8cm,2.0cm)$) {}; \node[neuron-small] (re2) at ($(current page.east)+(-1.1cm,-0.5cm)$) {}; \node[neuron-tiny] (re3) at ($(current page.east)+(-0.9cm,-3.0cm)$) {}; \draw[connection] (re1) -- (re2); % Diagonal flow connections (top-left to bottom-right emphasis) \draw[connection] (tl7) to[out=-45, in=135] (le2); \draw[connection] (tl8) to[out=-30, in=160] (re1); \draw[connection] (br7) to[out=135, in=-45] (re2); \draw[connection] (br8) to[out=150, in=-20] (le4); \end{tikzpicture} \centering \vspace*{0.6cm} % TinyTorch Logo \includegraphics[width=\textwidth]{../../_static/logos/logo-tinytorch.png} \vspace{5pt} % Tagline {\fontsize{16}{20}\selectfont\color{flameorange} Don't just \texttt{import torch}. Build it.\par} \vspace{14pt} % Main title - the visual anchor {\fontsize{26}{30}\selectfont\bfseries\color{torchnavy} Build Your Own ML Framework\par} \vspace{24pt} % Author block - tight cluster {\Large\color{torchnavy}\textbf{Prof. Vijay Janapa Reddi}\par} \vspace{3pt} {\large\color{bodygray}Harvard University\par} \vspace{70pt} % MLSysBook badge - light and airy footer \begin{tcolorbox}[ colback=bodygray!4, colframe=bodygray!4, boxrule=0pt, arc=6pt, width=0.58\textwidth, halign=center, left=24pt, right=24pt, top=14pt, bottom=16pt ] {\fontsize{9}{11}\selectfont\color{torchnavy}\textit{From Tensors to Systems}\par} \vspace{8pt} {\fontsize{7}{9}\selectfont\color{bodygray!60}A Build-It-Yourself Companion to the\par} \vspace{8pt} {\fontsize{8.5}{11}\selectfont\color{torchnavy}\textbf{Machine Learning Systems} textbook\par} \vspace{6pt} {\fontsize{7}{9}\selectfont\color{flameorange}\textit{\href{https://mlsysbook.ai}{mlsysbook.ai}}\par} \end{tcolorbox} % Draft indicator with date \clearpage {\fontsize{8}{10}\selectfont\color{bodygray!40}\textit{Draft Edition --- Last updated: February 15, 2026}\par} \vspace{0.6cm} \end{titlepage} } \makeatother % Clean headers and footers with TinyTorch branding \usepackage{fancyhdr} \setlength{\headheight}{21pt} \addtolength{\topmargin}{-9pt} % Define custom fancy page style \fancypagestyle{fancy}{% \fancyhf{}% \fancyfoot[C]{\color{bodygray}\thepage}% \renewcommand{\headrulewidth}{0.5pt}% \renewcommand{\footrulewidth}{0pt}% \renewcommand{\headrule}{% \vbox to 0pt{% \hbox to\headwidth{\hfil{\footnotesize\color{flameorange}Tiny\kern1pt\raisebox{-1pt}{\includegraphics[height=9pt]{../../_static/logos/fire-emoji.png}}\kern1pt\color{torchnavy}Torch}\hfil}% \vskip 4pt% \hrule height 0.5pt width\headwidth% \kern-0.5pt\color{flameorange}\hrule height 0.5pt width\headwidth% }% }% } % Override Sphinx's 'normal' pagestyle to use our fancy style \fancypagestyle{normal}{% \fancyhf{}% \fancyfoot[C]{\color{bodygray}\thepage}% \renewcommand{\headrulewidth}{0.5pt}% \renewcommand{\footrulewidth}{0pt}% \renewcommand{\headrule}{% \vbox to 0pt{% \hbox to\headwidth{\hfil{\footnotesize\color{flameorange}Tiny\kern1pt\raisebox{-1pt}{\includegraphics[height=9pt]{../../_static/logos/fire-emoji.png}}\kern1pt\color{torchnavy}Torch}\hfil}% \vskip 4pt% \hrule height 0.5pt width\headwidth% \kern-0.5pt\color{flameorange}\hrule height 0.5pt width\headwidth% }% }% } % Override plain style used for TOC/chapter pages \fancypagestyle{plain}{% \fancyhf{}% \fancyfoot[C]{\color{bodygray}\mdseries\thepage}% \renewcommand{\headrulewidth}{0pt}% \renewcommand{\footrulewidth}{0pt}% } \pagestyle{fancy} % Bold chapter styling with TinyTorch flame logo - left aligned \usepackage{titlesec} \titleformat{\chapter}[display] {\normalfont\huge\bfseries\color{torchnavy}} {\includegraphics[height=20pt]{../../_static/logos/fire-emoji.png}\hspace{8pt}\color{flameorange}\chaptertitlename\ \thechapter}{15pt}{\Huge\color{torchnavy}} \titlespacing*{\chapter}{0pt}{-10pt}{30pt} % Unnumbered chapter format (for Preface, etc.) \titleformat{name=\chapter,numberless}[display] {\normalfont\huge\bfseries\color{torchnavy}} {}{0pt}{\Huge\color{torchnavy}} \titlespacing*{name=\chapter,numberless}{0pt}{-10pt}{30pt} % Professional hyperlinks with TinyTorch colors \usepackage{hyperref} \hypersetup{ colorlinks=true, linkcolor=torchnavy, urlcolor=flameorange, citecolor=torchnavy, bookmarksnumbered=true, pdfstartview=FitH } latex_additional_files: - _static/logos/fire-emoji.png - _static/logos/logo-mlsysbook.png - _static/images/tito.png # Parse configuration parse: myst_enable_extensions: - "colon_fence" - "deflist" - "html_admonition" - "html_image" - "linkify" - "replacements" - "smartquotes" - "substitution" - "tasklist" # Build only TOC files only_build_toc_files: true