Merge remote-tracking branch 'origin/feature/book-volumes' into feature/book-volumes

This commit is contained in:
Vijay Janapa Reddi
2026-02-26 08:10:51 -05:00
2 changed files with 359 additions and 59 deletions

View File

@@ -307,36 +307,35 @@ Every operation has an **arithmetic intensity**: the ratio of computations perfo
```{.tikz}
\begin{tikzpicture}[font=\small\usefont{T1}{phv}{m}{n}, scale=1.0]
\tikzset{
Axis/.style={line width=1.0pt, draw=GrayLine, ->, >=stealth},
Axis/.style={line width=1.0pt, draw=GrayLine, ->, >=Latex},
Guide/.style={dashed, draw=GrayLine!60, line width=0.6pt},
Label/.style={text=TextBlack, align=center, font=\footnotesize\usefont{T1}{phv}{m}{n}},
Dot/.style={circle, fill=#1, draw=white, line width=0.5pt, minimum size=5pt, inner sep=0pt}
}
\draw[step=0.5, gray!10, very thin] (0,0) grid (6,4);
\draw[Axis] (0,0) -- (6,0) node[right, text=TextBlack] {Arithmetic Intensity (Ops/Byte)};
\draw[Axis] (0,0) -- (0,4.2) node[above, text=TextBlack] {Performance (FLOP/s)};
\draw[step=0.5, gray!15, very thin] (0,0) grid (6,4);
\draw[Axis] (0,0) -- (6,0) node[right,text=TextBlack] {Arithmetic Intensity (Ops/Byte)};
\draw[Axis] (0,0) -- (0,4.2) node[above, text=black] {Performance (FLOP/s)};
\draw[BlueLine, line width=2pt] (0,0) -- (3,3);
\draw[RedLine, line width=2pt] (3,3) -- (5.8,3);
\node[Label, text=BlueLine, rotate=45, anchor=south, yshift=2pt] at (1.5, 1.5) {\textbf{Memory Bound}};
\node[Label, text=RedLine, anchor=south, yshift=2pt] at (4.4, 3) {\textbf{Compute Bound}};
\node[Dot=TextBlack] at (3,3) {};
\draw[Guide] (3,0) -- (3,3);
\node[Dot=TextBlack] at (3,3) {};
\node[below, font=\scriptsize\usefont{T1}{phv}{m}{n}, text=TextBlack] at (3,0) {Ridge Point};
\end{tikzpicture}
```
:::
The **ridge point** determines the hardware's balance. If your workload's intensity is below this point, you are **memory-bound** (sloped region). If it is above, you are **compute-bound** (flat region).
$$ \text{Arithmetic Intensity} = \frac{\text{FLOPs}}{\text{Bytes Accessed}} $$
$$ \text{Ridge Point} = \frac{\text{Peak FLOP/s}}{\text{Memory Bandwidth}} $$
::: {.callout-tip title="Batch Size Controls Arithmetic Intensity"}
For matrix multiplications, arithmetic intensity scales with the batch dimension. When you compute $Y = XW$ where $X$ is $(B \times D_{in})$ and $W$ is $(D_{in} \times D_{out})$:
For matrix multiplications, arithmetic intensity scales with the batch dimension. When you compute $Y = XW$ where $X$ is $(B \times D_{\text{in}})$ and $W$ is $(D_{\text{in}} \times D_{\text{out}})$:
- **FLOPs**: $2 \times B \times D_{in} \times D_{out}$ (multiply-adds)
- **Bytes**: Weights are loaded once: $D_{in} \times D_{out} \times \text{bytes}_{\text{precision}}$
- **FLOPs**: $2 \times B \times D_{\text{in}} \times D_{\text{out}}$ (multiply-adds)
- **Bytes**: Weights are loaded once: $D_{\text{in}} \times D_{\text{out}} \times \text{bytes}_{\text{precision}}$
Doubling the batch size $B$ doubles FLOPs while keeping weight loads constant—directly increasing arithmetic intensity. This is why inference serving batches requests: batch size 1 is almost always memory-bound, while batch size 64+ can approach the compute ceiling.
:::
@@ -493,12 +492,10 @@ This explains why modern frameworks fuse operations: combining ReLU with the pre
The Roofline Model helps diagnose *where* a bottleneck lies. But before applying any performance equation, we should verify that it is physically meaningful. Dimensional analysis provides this sanity check: any valid equation must be **dimensionally homogeneous**—every term must resolve to the same units. If they do not, the equation contains an error.
Consider the Iron Law of ML Systems (Principle \ref{pri-iron-law}) introduced in @sec-introduction-iron-law-ml-systems-c32a:
$$ T = \frac{D_{vol}}{BW} + \frac{O}{R_{peak} \cdot \eta} + L_{lat} $$
$$ T = \frac{D_{\text{vol}}}{BW} + \frac{O}{R_{\text{peak}} \cdot \eta} + L_{\text{lat}} $$
We verify correctness by confirming that every term resolves to **Time (seconds)**:
$$ T [s] = \underbrace{ \frac{D_{vol} [\text{Bytes}]}{BW [\text{Bytes/s}]} }_{\text{Seconds}} + \underbrace{ \frac{O [\text{FLOPs}]}{R_{peak} [\text{FLOPs/s}] \cdot \eta [1]} }_{\text{Seconds}} + \underbrace{ L_{lat} [s] }_{\text{Seconds}} $$
$$ T [s] = \underbrace{ \frac{D_{\text{vol}} [\text{Bytes}]}{BW [\text{Bytes/s}]} }_{\text{Seconds}} + \underbrace{ \frac{O [\text{FLOPs}]}{R_{\text{peak}} [\text{FLOPs/s}] \cdot \eta [1]} }_{\text{Seconds}} + \underbrace{ L_{\text{lat}} [s] }_{\text{Seconds}} $$
* **Data Term**: $\frac{\text{Bytes}}{\text{Bytes/s}} = \text{Bytes} \times \frac{\text{s}}{\text{Bytes}} = \mathbf{s}$
* **Compute Term**: $\frac{\text{FLOPs}}{\text{FLOPs/s}} = \text{FLOPs} \times \frac{\text{s}}{\text{FLOPs}} = \mathbf{s}$
@@ -810,9 +807,7 @@ eq_time = TrainingTimeRef.eq_time
::: {.callout-notebook title="The Training Time Equation"}
Just as classical architecture has an "Iron Law" of performance, Large Language Model training has a fundamental governing equation. To estimate training time $T$:
$$ T \approx \frac{6 \cdot P \cdot D}{N \cdot X \cdot U} $$
Where:
* **$6$**: The factor deriving from the forward pass ($2PD$) and backward pass ($4PD$) FLOPs per token.
@@ -956,20 +951,60 @@ Computer systems use a hierarchy because no single technology provides both high
::: {#fig-memory-hierarchy fig-env="figure" fig-pos="htb" fig-cap="**The Memory Hierarchy**: Performance depends on data proximity. Accessing HBM is ~100$\times$ slower than registers; accessing SSD is ~100,000$\times$ slower." fig-alt="Pyramid showing Registers at top, followed by Cache, HBM/DRAM, and Storage at bottom."}
```{.tikz}
\begin{tikzpicture}[line cap=round, line join=round, font=\usefont{T1}{phv}{m}{n}\small, scale=1.0]
\tikzset{
LabelAxis/.style={text=TextBlack!60, font=\footnotesize\usefont{T1}{phv}{m}{n}, align=center}
}
\filldraw[fill=RedFill, draw=RedLine, line width=1pt] (0, 5.2) -- (-1.2, 4.2) -- (1.2, 4.2) -- cycle;
\node[text=RedLine] at (0, 4.55) {\textbf{Registers}};
\filldraw[fill=YellowFill, draw=YellowLine, line width=1pt] (-1.2, 4.2) -- (-2.4, 2.8) -- (2.4, 2.8) -- (1.2, 4.2) -- cycle;
\node[text=YellowLine!80!black] at (0, 3.5) {\textbf{L1 / L2 / L3 Cache}};
\filldraw[fill=BlueFill, draw=BlueLine, line width=1pt] (-2.4, 2.8) -- (-3.6, 1.4) -- (3.6, 1.4) -- (2.4, 2.8) -- cycle;
\node[text=BlueLine] at (0, 2.1) {\textbf{HBM / DRAM}};
\filldraw[fill=GreenFill, draw=GreenLine, line width=1pt] (-3.6, 1.4) -- (-4.8, 0) -- (4.8, 0) -- (3.6, 1.4) -- cycle;
\node[text=GreenLine] at (0, 0.7) {\textbf{Storage (SSD / Disk)}};
\draw[->, ultra thick, gray!40] (5.5, 0) -- (5.5, 5.2) node[midway, right, LabelAxis, text=gray] {Faster Speed\\ Lower Latency};
\draw[->, ultra thick, gray!40] (-5.5, 5.2) -- (-5.5, 0) node[midway, left, LabelAxis, text=gray] {Larger Capacity\\ Lower Cost};
\begin{tikzpicture}[line cap=round, line join=round, font=\usefont{T1}{phv}{m}{n}\small]
% --- parameters ---
\def\H{6.2} % triangle height
\def\W{4.6} % half triangle width
% --- levele (down to up) ---
\def\yone{1.5}
\def\ytwo{3}
\def\ythree{4.5}
% --- macro: calculate the half-width at the height y and write it in the macro \tmp
\newcommand{\halfwidthat}[2]{%
\pgfmathsetmacro#2{\W*(1-#1/\H)}%
}
% ---calculate the required widths ---
\halfwidthat{0}{\wzero}
\halfwidthat{\yone}{\wone}
\halfwidthat{\ytwo}{\wtwo}
\halfwidthat{\ythree}{\wthree}
% --- centri po visini (x=0 zbog simetrije) ---
\pgfmathsetmacro{\ycA}{0.5*(0+\yone)}
\pgfmathsetmacro{\ycB}{0.5*(\yone+\ytwo)}
\pgfmathsetmacro{\ycC}{0.5*(\ytwo+\ythree)}
\pgfmathsetmacro{\ycD}{0.46*(\ythree+\H)}
%up to down
\filldraw[fill=RedFill, draw=RedLine, line width=1pt]
(-\wthree,\ythree) -- (\wthree,\ythree) -- (0,\H) -- cycle;
\filldraw[fill=YellowFill, draw=YellowLine, line width=1pt]
(-\wtwo,\ytwo) -- (\wtwo,\ytwo) -- (\wthree,\ythree) -- (-\wthree,\ythree) -- cycle;
\filldraw[fill=BlueFill, draw=BlueLine, line width=1pt]
(-\wone,\yone) -- (\wone,\yone) -- (\wtwo,\ytwo) -- (-\wtwo,\ytwo) -- cycle;
\filldraw[fill=GreenFill, draw=GreenD, line width=1pt]
(-\wzero,0) -- (\wzero,0) -- (\wone,\yone) -- (-\wone,\yone) -- cycle;
% ---text ---
\node[font=\usefont{T1}{phv}{b}{n}\small,text=GreenD] at (0,\ycA) {Storage (SSD / Disk)};
\node[font=\usefont{T1}{phv}{bm}{n}\small,text=BlueLine] at (0,\ycB) {HBM / DRAM};
\node[font=\usefont{T1}{phv}{b}{n}\small,text=YellowLine] at (0,\ycC) {L1 / L2 / L3 Cache};
\node[font=\usefont{T1}{phv}{b}{n}\small,text=RedLine] at (0,\ycD) {Registers};
%
\coordinate(D)at($(\W,0)+(0.65,0)$);
\coordinate(L)at($(-\W,0)+(-0.65,0)$);
\coordinate(V)at($(0,\H)+(0,0)$);
\path[green](D)|-coordinate(D1)(V);
\path[green](L)|-coordinate(L1)(V);
%
\draw[->,>=Latex,line width=1pt,draw=black!40](D)--
node[align=center,right]{Faster Speed\\ Lower Latency}(D1);
\draw[->,>=Latex,line width=1pt,draw=black!40](L1)--
node[align=center,left]{Larger Capacity\\ Lower Cost}(L);
% --- outline ---
%\draw[thick] (-\W,0) -- (0,\H) -- (\W,0) -- cycle;
\end{tikzpicture}
```
:::
@@ -1186,14 +1221,11 @@ Among these formats, BF16[^fn-bf16] deserves special attention [@google_bfloat16
Quantization maps continuous floating-point values to discrete integers, typically INT8. The key challenge is choosing how to map the floating-point range to integers. Two approaches dominate.
Symmetric quantization centers the mapping at zero:
$$ x_{int} = \text{round}\left(\frac{x}{\alpha} \times 127\right) $$
$$ x_{\text{int}} = \text{round}\left(\frac{x}{\alpha} \times 127\right) $$
where $\alpha$ is the scale factor (typically the maximum absolute value). This works well for weight distributions centered around zero.
Asymmetric quantization handles distributions that are not centered (common after ReLU, which produces only non-negative values) by shifting the range before scaling. If $x_{min}$ is the minimum of the range and $\alpha$ is the range width ($x_{max} - x_{min}$):
$$ x_{int} = \text{round}\left(\frac{x - x_{min}}{\alpha} \times 255\right) $$
Asymmetric quantization handles distributions that are not centered (common after ReLU, which produces only non-negative values) by shifting the range before scaling. If $x_{\min}$ is the minimum of the range and $\alpha$ is the range width ($x_{\max} - x_{\min}$):
$$ x_{int} = \text{round}\left(\frac{x - x_{\min}}{\alpha} \times 255\right) $$
The choice between symmetric and asymmetric quantization depends on your tensor's distribution and has measurable accuracy implications.

View File

@@ -271,35 +271,303 @@ To see this cycle of mutual constraint in action, trace the flow in @fig-invaria
::: {#fig-invariants-cycle fig-env="figure" fig-pos="htb" fig-cap="**The Cycle of ML Systems (The 12 Invariants)**: The complete systems engineering lifecycle. The meta-principle of *Conservation of Complexity* (center) unifies the process: complexity is neither created nor destroyed, only shifted between Data, Model, Hardware, and Operations. Each transition is governed by specific quantitative invariants that constrain valid engineering decisions." fig-alt="Circular diagram with four phases: Foundations (Data) in green, Build (Model) in blue, Optimize (Hardware) in orange, and Deploy (Operations) in violet. Arrows connect each phase in a cycle, with the 12 invariants labeled on each transition. Conservation of Complexity is shown in the center as a dashed circle."}
```{.tikz}
\begin{tikzpicture}[
node distance=3.5cm,
font=\small\usefont{T1}{phv}{m}{n},
main/.style={rectangle, rounded corners=10pt, draw, ultra thick, minimum width=2.8cm, minimum height=1.4cm, align=center},
inv/.style={font=\scriptsize\usefont{T1}{phv}{m}{n}, align=center, fill=white, fill opacity=0.9, text opacity=1, inner sep=2.5pt}
]
\begin{tikzpicture}[line join=round,font=\usefont{T1}{phv}{m}{n}]
% Colors
\definecolor{GreenLine}{HTML}{008F45}
\definecolor{BlueLine}{HTML}{006395}
\definecolor{OrangeLine}{HTML}{E67817}
\definecolor{VioletLine}{HTML}{7E317B}
\tikzset{
Box/.style={align=flush center,
inner sep=4pt,
node distance=1.4,
draw=OrangeLine,
line width=0.75pt,
rounded corners,
fill=OrangeL!30,
text width=25mm,
minimum width=25mm, minimum height=10mm
},
Box2/.style={Box, draw=VioletLine, fill=VioletL2!70,align=left,
text width=36mm, minimum width=36mm, minimum height=10mm
},
}
% Main Nodes
\node[main, draw=GreenLine, fill=GreenLine!10] (Data) at (-4.5, 0) {\normalsize \textbf{Foundations}\\\scriptsize (Data)};
\node[main, draw=BlueLine, fill=BlueLine!10] (Model) at (0, 3.5) {\normalsize \textbf{Build}\\\scriptsize (Model)};
\node[main, draw=OrangeLine, fill=OrangeLine!10] (Hardware) at (4.5, 0) {\normalsize \textbf{Optimize}\\\scriptsize (Hardware)};
\node[main, draw=VioletLine, fill=VioletLine!10] (Ops) at (0, -3.5) {\normalsize \textbf{Deploy}\\\scriptsize (Operations)};
\tikzset{%
planet/.style = {circle, draw=yellow!50!red!90,semithick, fill=yellow!30,line width=1.5pt,
font=\usefont{T1}{phv}{m}{n}\bfseries,
minimum size=24mm, inner sep=1mm,align=flush center},
satellite/.style = {circle, draw=none, semithick, fill=#1!10,
text width=26mm, inner sep=1pt, align=flush center,minimum size=20mm,minimum height=12mm},
TxtC/.style = {font=\small\usefont{T1}{phv}{m}{n},text width=44mm,align=flush center},
arr/.style = {-{Triangle[length=3mm,width=6mm]}, color=#1!60,
line width=3mm, shorten <=1mm, shorten >=1mm},
LineA/.style = {violet!60,{Circle[line width=1.5pt,fill=white,length=7.5pt]}-,line width=2.0pt,shorten <=-4pt},
LineAA/.style={violet!30,dashed, line width=1.0pt,{-{Triangle[width=1.0*6pt,length=1.6*6pt]}},shorten <=3pt,shorten >=2pt}
}
% Center
\node[circle, draw=gray, dashed, ultra thick, align=center, inner sep=10pt, fill=gray!5] (Center) at (0,0) {\small \textbf{Conservation}\\\small \textbf{of}\\\small \textbf{Complexity}};
\tikzset{pics/brain/.style = {
code = {
\pgfkeys{/channel/.cd, #1}
\begin{scope}[local bounding box=BRAIN,scale=\scalefac, every node/.append style={transform shape}]
\draw[fill=\filllcolor,line width=\Linewidth](-0.3,-0.10)to(0.08,0.60)
to[out=60,in=50,distance=3](-0.1,0.69)to[out=160,in=80](-0.26,0.59)to[out=170,in=90](-0.46,0.42)
to[out=170,in=110](-0.54,0.25)to[out=210,in=150](-0.54,0.04)
to[out=240,in=130](-0.52,-0.1)to[out=300,in=240]cycle;
\draw[fill=\filllcolor,line width=\Linewidth]
(-0.04,0.64)to[out=120,in=0](-0.1,0.69)(-0.19,0.52)to[out=120,in=330](-0.26,0.59)
(-0.4,0.33)to[out=150,in=280](-0.46,0.42)
%
(-0.44,-0.03)to[bend left=30](-0.34,-0.04)
(-0.33,0.08)to[bend left=40](-0.37,0.2) (-0.37,0.12)to[bend left=40](-0.45,0.14)
(-0.26,0.2)to[bend left=30](-0.24,0.13)
(-0.16,0.32)to[bend right=30](-0.27,0.3)to[bend right=30](-0.29,0.38)
(-0.13,0.49)to[bend left=30](-0.04,0.51);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.23,0.03)--(-0.15,-0.03)--(-0.19,-0.18)--(-0.04,-0.28);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.17,0.13)--(-0.04,0.05)--(-0.06,-0.06)--(0.14,-0.11);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.12,0.23)--(0.31,0.0);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.07,0.32)--(0.06,0.26)--(0.16,0.33)--(0.34,0.2);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.01,0.43)--(0.06,0.39)--(0.18,0.51)--(0.31,0.4);
\end{scope}
}
}
}
% Paths with refined curves and labels
\draw[->, line width=2.5pt, GreenLine, bend left=40] (Data) to node[inv, pos=0.5] {\textbf{1. Data as Code}\\\textbf{2. Data Gravity}} (Model);
\draw[->, line width=2.5pt, BlueLine, bend left=40] (Model) to node[inv, pos=0.5] {\textbf{3. Iron Law}\\\textbf{4. Silicon Contract}} (Hardware);
\draw[->, line width=2.5pt, OrangeLine, bend left=40] (Hardware) to node[inv, pos=0.5] {\textbf{5. Pareto Frontier}\\\textbf{6. Arith. Intensity}\\\textbf{7. Energy-Movement}\\\textbf{8. Amdahl's Law}} (Ops);
\draw[->, line width=2.5pt, VioletLine, bend left=40] (Ops) to node[inv, pos=0.5] {\textbf{9. Verification Gap}\\\textbf{10. Stat. Drift}\\\textbf{11. Skew Law}\\\textbf{12. Latency Budget}} (Data);
%brick
\tikzset{
cigla/.style={ inner sep=0pt,anchor=west,
node distance=1.4pt,
draw=none,
line width=0.1pt,
rounded corners=1pt,
fill=\filllcolor,
minimum width=4mm, minimum height=2mm
},
cigla1/.style={cigla,fill=\filllcirclecolor},
pics/brick/.style = {
code = {
\pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\path[clip] (-1.05,-0.52)rectangle (0.71,0.45);
\node[cigla](C1) at (-1.03,-0.4){};
\node[cigla1,right= of C1](C2){};
\node[cigla,right= of C2](C3){};
\node[cigla1,right= of C3](C4){};
%
\node[cigla,above right= of C1,anchor=south](C11){};
\node[cigla1,right= of C11](C12){};
\node[cigla,right= of C12](C13){};
\node[cigla1,right= of C13](C14){};
%
\node[cigla,above right= of C11,anchor=south](C21){};
\node[cigla1,right= of C21](C22){};
\node[cigla,right= of C22](C23){};
%
\node[cigla,above right= of C21,anchor=south](C31){};
\node[cigla1,right= of C31](C32){};
\node[cigla,right= of C32](C33){};
\end{scope}
}
}
}
%vaga
\tikzset{
pics/vaga/.style = {
code = {
\pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\node[rectangle,minimum width=2mm,minimum height=22mm,
draw=none, fill=\filllcolor,line width=\Linewidth](1R) at (0,-0.95){};
\fill[fill=\filllcolor!60!black](230:2.8)arc(230:310:2.8)--cycle;%circle(2.9);
%LT
\node [semicircle, shape border rotate=180, anchor=chord center,
minimum size=11mm, draw=none, fill=\filllcirclecolor](LT) at (-2,-0.5) {};
\node [circle, minimum size=4mm, draw=none, fill=\filllcirclecolor](T1) at (-2,1.25) {};
\draw[draw=\drawcolor,,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T1)--(LT);
\draw[draw=\drawcolor,,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T1)--(LT.30);
\draw[draw=\drawcolor,,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T1)--(LT.150);
%DT
\node [semicircle, shape border rotate=180, anchor=chord center,
minimum size=11mm, draw=none, fill=\filllcirclecolor!70!black](DT) at (2,-0.5) {};
\node [circle, minimum size=4mm, draw=none, fill=\filllcirclecolor!70!black](T2) at (2,1.25) {};
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T2)--(DT);
\draw[draw=\drawcolor,,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T2)--(DT.30);
\draw[draw=\drawcolor,,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T2)--(DT.150);
%
\node[draw=none,rectangle,minimum width=32mm,minimum height=1.5mm,inner sep=0pt,
fill=\filllcolor!60!black]at(0,1.25){};
\node[draw=white,fill=\filllcolor,line width=2*\Linewidth,ellipse,minimum width=9mm, minimum height=15mm](EL)at(0,0.85){};
\node[draw=white,fill=\filllcolor!60!black,line width=2*\Linewidth,,circle,minimum size=10mm](2C)at(0,2.05){};
\end{scope}
}
}
}
%llm
\tikzset{
pics/llm/.style = {
code = {
\pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\node[circle,minimum size=12mm,draw=\drawcolor, fill=\filllcolor!70,line width=0.5*\Linewidth](C\picname) at (0,0){};
\def\startangle{90}
\def\radius{1.15}
\def\radiusI{1.1}
\foreach \i [evaluate=\i as \j using \i+1] [count =\k] in {0,2,4,6,8} {
\pgfmathsetmacro{\angle}{\startangle - \i * (360/8)}
\draw[draw=black,-{Circle[black ,fill=\filllcirclecolor,length=5.5pt,line width=0.5*\Linewidth]},line width=1.5*\Linewidth](C\picname)--++(\startangle - \i*45:\radius) ;
\node[circle,draw=black,fill=\filllcirclecolor!80!red!50,inner sep=3pt,line width=0.5*\Linewidth](2C\k)at(\startangle - \j*45:\radiusI) {};
}
\draw[line width=1.5*\Linewidth](2C1)--++(-0.5,0)|-(2C2);
\draw[line width=1.5*\Linewidth](2C3)--++(0.5,0)|-(2C4);
\node[circle,,minimum size=12mm,draw=\drawcolor, fill=\filllcolor!70,line width=0.5*\Linewidth]at (0,0){};
\end{scope}
}
}
}
%battery
\tikzset{
pics/battery/.style = {
code = {
\pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\node[rectangle,minimum width=35mm,minimum height=8mm,draw=\drawcolor,
rounded corners=4pt,fill=\filllcirclecolor,line width=\Linewidth](2R\picname) at (1,0){};
\node[rectangle,minimum width=45mm,minimum height=22mm,draw=\drawcolor,
rounded corners=4pt,fill=\filllcolor,line width=\Linewidth](R\picname) at (0,0){};
\node[rectangle,minimum width=5mm,minimum height=18mm,draw=none,
fill=green,line width=\Linewidth](3R\picname) at ($(R\picname.west)!0.5!(R\picname.east)$){};
\node[rectangle,minimum width=5mm,minimum height=18mm,draw=none,
fill=green,line width=\Linewidth](3R\picname) at ($(R\picname.west)!0.33!(R\picname.east)$){};
\node[rectangle,minimum width=5mm,minimum height=18mm,draw=none,
fill=green,line width=\Linewidth](3R\picname) at ($(R\picname.west)!0.16!(R\picname.east)$){};
\end{tikzpicture}
\end{scope}
}
}
}
%rocket
\tikzset{
pics/rocket/.style = {
code = {
\pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape},line cap = round]
%vrh
\draw[fill=\filllcolor,draw=\drawcolor,line width=\Linewidth](-0.26,0.5)to[bend right=12](0.26,0.5)to[bend right=7] (0,0.85)to[bend right=7] cycle;
%krila
\draw[fill=\filllcolor!70!red,,draw=\drawcolor,line width=\Linewidth,rounded corners=1pt](-0.2,-0.7)--(-0.45,-0.9)--(-0.567,-0.4)--(-0.3,-0.17)--cycle;
\draw[fill=\filllcolor!70!red,draw=\drawcolor,line width=\Linewidth,rounded corners=1pt](0.2,-0.7)--(0.45,-0.9)--(0.567,-0.4)--(0.3,-0.17)--cycle;
%rep
\draw[fill=\filllcolor!70!green,draw=\drawcolor,line width=\Linewidth](0.16,-0.76)--(0.22,-0.9)--(-0.2,-0.9)--(-0.15,-0.76)--cycle;
%body
\draw[fill=\filllcolor,draw=\drawcolor,line width=\Linewidth](-0.2,-0.7)--(0.2,-0.7)to[out=75,in=320](0,0.85)to[out=220,in=105] cycle;
%krug
\node[circle,draw=\drawcolor,minimum size=4mm,fill=\filllcirclecolor,line width=\Linewidth]{};
\draw[draw=\drawcolor,line width=1.5*\Linewidth](0,-0.99)--(0,-1.3);
\draw[draw=\drawcolor,line width=1.5*\Linewidth](-0.11,-0.99)--(-0.11,-1.2);
\draw[draw=\drawcolor,line width=1.5*\Linewidth](0.11,-0.99)--(0.11,-1.2);
\end{scope}
}
}
}
\pgfkeys{
/channel/.cd,
Depth/.store in=\Depth,
Height/.store in=\Height,
Width/.store in=\Width,
filllcirclecolor/.store in=\filllcirclecolor,
filllcolor/.store in=\filllcolor,
drawcolor/.store in=\drawcolor,
drawcircle/.store in=\drawcircle,
scalefac/.store in=\scalefac,
Linewidth/.store in=\Linewidth,
picname/.store in=\picname,
filllcolor=BrownLine,
filllcirclecolor=violet!20,
drawcolor=black,
drawcircle=violet,
scalefac=1,
Linewidth=0.5pt,
Depth=1.3,
Height=0.8,
Width=1.1,
picname=C
}
\def\radius{3.9}
\def\startangle{90}
\foreach \i/\j/\sho [count=\k from 0] in {
%green!79!black
white/{\textbf{}\\ }/15pt,
%magenta!60!
white/{\textbf{}\\ }/15pt,
%gray
white/{\textbf{}\\}/15pt,
%cyan
white/{\textbf{}\\ }/15pt
}
{
%Satelit
\pgfmathsetmacro{\angle}{\startangle - \k * (360/4)}
\node (s\k) [satellite=\i, font=\footnotesize\usefont{T1}{phv}{m}{n}] at (\angle:\radius) {};
\node[TxtC,below=0pt of s\k]{\j};
}
%logos
%brick
\pic[shift={(0.15,0.15)}] at (s3) {brick={scalefac=1.1,picname=1,filllcolor=red!70!black!80,Linewidth=1.0pt,filllcirclecolor=red!90!black!50}};
%llm
\pic[shift={(0,0)}] at (s0){llm={scalefac=0.9,drawcolor=BlueLine,filllcolor=BlueLine!10!, Linewidth=1.25pt,filllcirclecolor=red}};
%brain
\pic[shift={(0.1,-0.16)}] at (s0){brain={scalefac=0.8,picname=1,filllcolor=orange!30!, filllcirclecolor=cyan!55!black!60, Linewidth=0.5pt}};
%battery
\pic[shift={(0,0)}] at (s1){battery={scalefac=0.38,picname=1, drawcolor=BrownLine,filllcolor=BrownLine!10!, Linewidth=1.5pt,filllcirclecolor=BrownLine}};
%rocket
\pic[shift={(0,0.2)}] at (s2){rocket={scalefac=1.1,picname=1, drawcolor=black,filllcolor=cyan!10!, Linewidth=1.0pt,filllcirclecolor=red}};
%center
\node[circle, draw=BrownLine, dashed,thick, fill=none,,minimum size=26mm](CE)at(0,0){};
\node[TxtC,below=0pt of CE]{Conservation\\ of Complexity};
\pic[shift={(0,0)}] at (0,0){vaga={scalefac=0.35,picname=1,filllcolor=BlueLine, Linewidth=1.0pt,filllcirclecolor=orange}};
\def\ra{26mm}
\foreach \i [count=\k from 0] in{360,320,140,135}{
\pgfmathtruncatemacro{\newX}{\i + 90} %
\draw[line width=2.6pt,violet]
(s\k)+(\i:0.5*\ra) arc[start angle=\i, end angle=\newX, radius=0.5*\ra];
}
\draw[LineA](s0.35)--++(0:1)coordinate(MA);
\node[Box,anchor=west](FO)at(MA){\textbf{Build}\\ (Model)};
\draw[LineA](s1.355)--++(315:1)coordinate(ST);
\node[Box,anchor=west](PR)at(ST){\textbf{Optimize}\\ (Hardware)};
\draw[LineA](s2.185)--++(200:3.25)coordinate(DE);
\node[Box,anchor=west](DEP)at(DE){\textbf{Deploy}\\(Operations)};
\draw[LineA](s3.180)--++(180:3.25)coordinate(FO);
\node[Box,anchor=west](DEP)at(FO){\textbf{Foundations}\\(Data)};
%
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (60:\radius)
arc[radius=\radius, start angle=60, end angle= 16];
\coordinate (AR1) at (38:\radius);
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (340:\radius)
arc[radius=\radius, start angle=340, end angle= 290];
\coordinate (AR2) at (315:\radius);
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (240:\radius)
arc[radius=\radius, start angle=240, end angle= 200];
\coordinate (AR3) at (225:\radius);
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (160:\radius)
arc[radius=\radius, start angle=160, end angle= 114];
\coordinate (AR4) at (137:\radius);
%
\draw[LineA](AR1)--++(0:1.3)coordinate(MA);
\node[Box2,anchor=west]at(MA){3. Iron Law\\
4. Silicon Contract};
\draw[LineA](AR2)--++(340:1.6)coordinate(MA1);
\node[Box2,anchor=west]at(MA1){5. Pareto Frontier\\
6. Arith. Intensity\\
7. Energy-Movement\\
8. Amdahls Law};
\draw[LineA](AR3)--++(180:6)coordinate(MA2);
\node[Box2,anchor=west]at(MA2){9. Verification Gap\\
10. Stat. Drift\\
11. Skew Law\\
12. Latency Budget};
\draw[LineA](AR4)--++(180:6)coordinate(MA3);
\node[Box2,anchor=west]at(MA3){1. Data as Code\\
2. Data Gravity};
\end{tikzpicture}
```
:::