Skip to content

Latest commit

 

History

45 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mlatlas

Declarative, print-first machine-learning & neural-network diagrams for Typst.

Warning

Work in progress — local install only. mlatlas is not yet published to Typst Universe, so #import "@preview/mlatlas:..." does not work yet. Install it locally — see Installation. The API is still stabilizing and may change (e.g. the node primitive was recently renamed block → block2d) before the first published release.

Describe the model — transformer(blocks: 6), mlp((4, 8, 8, 3)), a two-stream fusion — and get a clean, publication-quality figure. Batteries-included defaults so a simple diagram is one line; full control (themes, per-element overrides, custom topologies, raw IR) when you need it.

VGG-16 and LeNet-5 as 3-D feature-map prisms

Publication-grade figures from dedicated per-family renderers — VGG-16 / LeNet-5 above; LSTM cells (Olah), GNN message passing, DDPM chains, and LDA plates below.

LSTM cell   GNN message passing   LDA plate notation

The same Transformer block in four themes

The same diagram in four themes — one setting flips the whole look.

Print-first by design

The default mono theme is built for paper: light fills, dark text, sharp orthogonal edges, stealth arrows, with garnet used only as a sparse accent. Never a dark block with white text. Switch the entire look with one setting:

#render(ir)                       // mono (default) — restrained, print-safe
#render(ir, theme: colorful)      // Okabe-Ito light tints (colourblind-safe)
#render(ir, theme: grayscale)     // pure B&W, value + dash differentiation
#render(ir, theme: slides)        // opt-in dark (auto white text)
#render(ir, theme: palette-theme((op: rgb("#1F414D"), norm: rgb("#65780B"))))  // your own scheme

A luminance check picks readable text for any fill, so contrast is never wrong by accident.

Installation

mlatlas is not on the Typst package registry yet, so install it locally — either as a local package or by relative path.

As a local package (recommended). Clone into Typst's local-packages directory, then import with the @local namespace:

# Linux
git clone https://github.com/j-vaught/mlatlas.git \
  ~/.local/share/typst/packages/local/mlatlas/0.3.0
# macOS:   ~/Library/Application Support/typst/packages/local/mlatlas/0.3.0
# Windows: %APPDATA%\typst\packages\local\mlatlas\0.3.0
#import "@local/mlatlas:0.3.0": *

Or by relative path. Clone anywhere and point at lib.typ directly:

#import "path/to/mlatlas/lib.typ": *

Once published, #import "@preview/mlatlas:0.3.0": * will work too — until then it won't resolve.

Quick start

#import "@local/mlatlas:0.3.0": *     // local install — see Installation above (not on @preview yet)

// Simple is one line — auto-wired, auto-themed.
#render(seq(
  block2d(label: [Input], role: "data"),
  block2d(label: [Hidden Layer]),
  block2d(label: [Output], role: "output"),
))

#render(transformer(blocks: 6, heads: 8, rope: true))   // residual skips auto-routed
#render(mlp((4, 8, 8, 3)))                                // node-edge MLP
#render(lenet(), dir: "ltr")                              // CNN as 3-D feature-map prisms

3-D blocks, volumes & tensors

3-D figures: CNN, U-Net, attention cube, transformer, ResNet, kernel-slide, RNN/LSTM, generative

A small hand-rolled 3-D engine projects each block's eight corners itself — so back-face culling and a single clean silhouette are correct at any camera angle (cetz's native 3-D can't manage this cleanly, because it hides the projected coordinates: you get corner spikes and bow-tied outlines). Flat by default — the crisp edges carry the depth — with opt-in directional shading.

#import "@preview/cetz:0.5.2"
#cetz.canvas(length: 1cm, {
  import cetz.draw
  block3d(draw, w: 1.4, h: 2.0, dep: 1.2, base: rgb("#FFF2E3"))         // one block, one call
  feature-map(draw, (4, 0), spatial: 112, channels: 128, relu: true)    // spatial->height, channels->depth
})

Architecture renderers compose it: cnn / feature-stack (feature-map rows), resnet3d, unet3d, fpn3d, attention-3d (the multi-head QKᵀ score cube), transformer-3d, rnn-unroll3d, lstm-cell3d, voxel-grid, kernel-slide, vae3d / gan3d. Or drop a 3-D tensor straight into the IR for auto-layout + edges: render(seq(tensor(title: [x], axes: ([56], [56], [3])), tensor(title: [z], axes: ([1], [1], [128])))).

The camera is three angles (pitch, yaw, roll) — exactly like cetz's ortho — set once per scene and overridable per block:

preset family look
cam-iso (default) rotation isometric, corner-front — sculptural
cam-dimetric rotation gentle dimetric
cam-top-down rotation high-angle
cam-cabinet oblique upright front face, depth shears up-right — best for CNN rows
cam-cavalier oblique upright front, full-depth
cam-face oblique shallow oblique
block3d(draw, w: 2, h: 2, dep: 2, cam: cam-cabinet, shade: true)   // a preset
block3d(draw, w: 2, h: 2, dep: 2, cam: (30deg, -40deg, 8deg))      // or raw angles

Custom topologies are first-class

Dual-backbone, two-stream / multi-modal fusion, dual-head — a few readable calls, no manual coordinates:

Two-stream multi-modal fusion    Dual-head architecture    U-Net with skip connections

// two-stream / multi-modal fusion
#render(two-stream(image-stream, text-stream, fusion: [Fusion], head: head-stack))

// shared backbone, two task heads
#render(branch(backbone, cls-head, box-head))

// arbitrary fan-in / fan-out
#render(merge(arm-a, arm-b, arm-c, into: block2d(label: [Concat])))

Customization — no forking

block2d(label: [Conv], style: (fill: rgb("#eee"), stroke: 2pt + rgb("#65780B")))  // per-node
block2d(label: [Focal], emphasis: true)                                            // sparse garnet accent
graph(edges: (("a", "b", (style: (stroke: 2pt + red), label: [grad])),))         // per-edge
render(ir, role-map: (attention: "param"))                                       // restyle a category
render(ir, theme: theme(spacing: (18mm, 12mm)))                                  // tweak any theme field
graph(nodes: (..ir-nodes..), edges: (..))                                        // full IR escape hatch

Layout safety net

render warns (by default) when an edge crosses an unrelated block — a bbox-aware, scale-independent check:

#render(ir)                  // check: "warn"  -> banner if a line crosses a block
#render(ir, check: "error")  // hard error
#render(ir, check: "off")

What's here

Layer Pieces
Themes mono (default), colorful, colorblind, grayscale/bw, slides; theme(..), palette-theme(..), theme-swatch
IR ir-node, ir-edge, frag, namespace, shift (escape hatch)
Primitives block2d, op-node, slab/conv (3-D prisms), neuron-graph, tensor (3-D IR node)
3-D engine block3d, feature-map, scene, project, tensor3d, arrow3d/dock, voxel-grid + cam-iso/cam-cabinet/… presets
Composition seq, parallel, branch, merge, concat, residual, plate, graph
Presets perceptron, mlp, feedforward, transformer(-block), attention-head, resnet-stage, unet, two-stream, gan, vae, rnn-unroll, gcn
Dedicated renderers cnn/vgg16/alexnet/lenet5 (PlotNeuralNet-grade), lstm-cell (Olah), message-passing (GNN), diffusion-chain (DDPM), lda-plate/hmm-chain (PGM)
3-D renderers resnet3d, unet3d, fpn3d, attention-3d (QKᵀ cube), transformer-3d, rnn-unroll3d, lstm-cell3d, kernel-slide, vae3d/gan3d

Architecture: a plain-dict semantic IR is the contract; primitives/presets emit IR; the renderer draws it via fletcher/cetz behind an adapter firewall. See docs/design-spec.md for the full design and the roadmap toward the broader ML-diagram atlas (sequence cells, attention internals, generative/graph/probabilistic models, plots, audio/3-D, and the long tail).

Building the examples

typst compile --root . examples/transformer.typ      # or any example
./tools/render-all.sh                                 # compile + rasterize all

License

MIT © 2026 J.C. Vaught.

About

Declarative ML / neural-network / AI diagrams for Typst — rectangular, high-contrast, batteries-included with full customization.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages