supertensor: shape-aware tensor figure toolkit
Extracted from the tensor-formula-viz skill and rebuilt around the idea that the geometry rules should be enforced by construction rather than restated as prose an agent has to remember. - assets/supertensor.sty: faces, stacks, index faces, shared caption lanes, meaning box, signature. Macros take a declared axis and a declared role, so equal shapes get equal edges, a x a is square, a transpose swaps the face, and contracted axes share an edge length -- without any manual alignment. - scripts/preflight.sh: decide the TikZ/CJK path before drawing. - scripts/build.sh: compile and fail on silent corruption (missing CJK glyphs, overfull boxes, undeclared roles), then export pdf/svg/png/thumb. - scripts/test.sh: build every figure as a regression test for the package. - examples/: three golden figures (TP-FFN, causal MHA, MoE top-k gather) plus an anti-pattern gallery of figures that compile cleanly and still lie. - SKILL.md + references/: lean entry point, details loaded on demand.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
% Golden example 2 -- causal multi-head attention.
|
||||
% Shows: leading axes as stack depth, a transpose that physically swaps the
|
||||
% face, equal edge length on the contracted axis, and a Boolean mask drawn in
|
||||
% a different grammar from the scores it gates.
|
||||
% ../scripts/build.sh mha-causal.tex
|
||||
\documentclass[border=10pt]{standalone}
|
||||
\usepackage[cjk]{supertensor}
|
||||
|
||||
\stsetrole{q}{stTeal}
|
||||
\stsetrole{k}{stOrange}
|
||||
\stsetrole{v}{stViolet}
|
||||
\stsetrole{s}{stCoral}
|
||||
\stsetrole{w}{stGray}
|
||||
|
||||
\stdim{T}{6}
|
||||
\stdim{dh}{3}
|
||||
\stdim{d}{9} % d = h * d_h, h = 3
|
||||
|
||||
\begin{document}
|
||||
\begin{tikzpicture}
|
||||
|
||||
% ================================================================= formula ==
|
||||
\node (F) at (0,0) {\stformula{$\displaystyle
|
||||
\mathbf A^{(i)}=\mathrm{softmax}\!\left(
|
||||
\frac{\mathbf Q^{(i)}\mathbf K^{(i)\top}}{\sqrt{d_h}}+\mathbf M\right),\qquad
|
||||
\mathbf O^{(i)}=\mathbf A^{(i)}\mathbf V^{(i)}$}};
|
||||
|
||||
% ============================================================ stage A row ===
|
||||
\node[st stage, below=7mm of F] (SA) {每头打分:沿 $d_h$ 收缩};
|
||||
\coordinate (a) at ($(SA)+(-3.9,-1.9)$);
|
||||
|
||||
\ststack[role=q, bracket=true]{Q}{(a)}{T}{dh}{3}
|
||||
\node[st op, right=6mm of Q] (mA) {$\times$};
|
||||
% K^T: the face is physically swapped, not relabelled. Its height equals Q's
|
||||
% width -- that is the contracted axis d_h, drawn at one edge length.
|
||||
\ststack[role=k, bracket=true]{KT}{($(mA)+(1.9,0)$)}{dh}{T}{3}
|
||||
\node[st op, right=6mm of KT] (eA) {$=$};
|
||||
\ststack[role=s]{S}{($(eA)+(2.0,0)$)}{T}{T}{3}
|
||||
|
||||
\node[inner sep=0pt, fit=(Q)(KT)(S)] (rowA) {};
|
||||
\stlane{rowA}
|
||||
\stcaption{Q}{$\mathbf Q^{(i)}$}{$h\times T\times d_h$}
|
||||
\stcaption{KT}{$\mathbf K^{(i)\top}$}{$h\times d_h\times T$}
|
||||
\stcaption{S}{$\mathbf S^{(i)}$}{$h\times T\times T$}
|
||||
\stnolane
|
||||
|
||||
% ============================================================ stage B row ===
|
||||
\node[st stage, below=9mm of Q-shape.south west, anchor=north west] (SB)
|
||||
{因果掩码与加权求和};
|
||||
\coordinate (b) at ($(SB)+(0.6,-2.0)$);
|
||||
|
||||
% The mask is a Boolean support, not a magnitude: one flat level, exact
|
||||
% triangle, no stack -- it is shared by every head.
|
||||
\stface[role=w, pattern=data,
|
||||
data={300000,330000,333000,333300,333330,333333}]{M}{(b)}{T}{T}
|
||||
\ststack[role=s, pattern=causal]{A}{($(M.east)+(3.75,0)$)}{T}{T}{3}
|
||||
\starrowlabel{M.east}{A.west}{softmax}
|
||||
\node[st op, right=6mm of A] (mB) {$\times$};
|
||||
\ststack[role=v, bracket=true]{V}{($(mB)+(1.4,0)$)}{T}{dh}{3}
|
||||
\node[st op, right=6mm of V] (eB) {$=$};
|
||||
\ststack[role=v]{O}{($(eB)+(1.4,0)$)}{T}{dh}{3}
|
||||
|
||||
\node[inner sep=0pt, fit=(M)(A)(V)(O)] (rowB) {};
|
||||
\stlane{rowB}
|
||||
\stcaption{M}{$\mathbf M$}{$T\times T$}
|
||||
\stcaption{A}{$\mathbf A^{(i)}$}{$h\times T\times T$}
|
||||
\stcaption{V}{$\mathbf V^{(i)}$}{$h\times T\times d_h$}
|
||||
\stcaption{O}{$\mathbf O^{(i)}$}{$h\times T\times d_h$}
|
||||
\stnolane
|
||||
|
||||
% ============================================================ stage C row ===
|
||||
\node[st stage, below=9mm of M-shape.south west, anchor=north west] (SC)
|
||||
{沿 $d_h$ 拼接后投影};
|
||||
\coordinate (c) at ($(SC)+(1.2,-2.0)$);
|
||||
|
||||
% Concatenation reverses the split: three h-shards of width d_h tile a face of
|
||||
% width d exactly.
|
||||
\stface[role=v]{C1}{(c)}{T}{dh}
|
||||
\stface[role=v]{C2}{($(C1.east)+(1.5*\stunit,0)$)}{T}{dh}
|
||||
\stface[role=v]{C3}{($(C2.east)+(1.5*\stunit,0)$)}{T}{dh}
|
||||
\node[st op, right=6mm of C3] (mC) {$\times$};
|
||||
\stface[role=w]{WO}{($(mC)+(2.5,0)$)}{d}{d}
|
||||
\node[st op, right=6mm of WO] (eC) {$=$};
|
||||
\stface[role=v, bracket=true]{Y}{($(eC)+(2.5,0)$)}{T}{d}
|
||||
|
||||
\node[inner sep=0pt, fit=(C1)(WO)(Y)] (rowC) {};
|
||||
\stlane{rowC}
|
||||
\stcaption{C2}{$[\,\mathbf O^{(1)}\mid\mathbf O^{(2)}\mid\mathbf O^{(3)}\,]$}{$T\times d$}
|
||||
\stcaption{WO}{$\mathbf W_O$}{$d\times d$}
|
||||
\stcaption{Y}{$\mathbf Y$}{$T\times d$}
|
||||
\stnolane
|
||||
|
||||
% ============================================================== meaning box ==
|
||||
\node[inner sep=0pt, fit=(F)(rowA)(rowB)(rowC)(Y-shape)(C2-shape)] (all) {};
|
||||
\stmeaningbox{mb}{16.8cm}{all}
|
||||
{$T$ 序列长度,$d_h$ 单头宽度,$h$ 头数(图中 $h=3$,即堆叠的三张面),
|
||||
$d=h\,d_h$;批轴 $B$ 省略}
|
||||
{$\mathbf S,\mathbf A$ 是分数与概率(行和为 $1$);$\mathbf M\in\{0,-\infty\}^{T\times T}$
|
||||
是布尔支撑而非数值,被所有头共享,故只画一张、不堆叠;紫色一族标记 $\mathbf V\rightarrow\mathbf O\rightarrow\mathbf Y$ 同一数据流}
|
||||
{$(T\times d_h)(d_h\times T)\rightarrow(T\times T)$:$\mathbf K^{\top}$ 的面高即收缩维 $d_h$;
|
||||
拼接是切分的逆运算,$3$ 个 $d_h$ 恰好铺满 $d$}
|
||||
\stsignature{因果多头注意力(掩码 + 拼接投影)}{mb}
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{document}
|
||||
Reference in New Issue
Block a user