Parallelism Decision Viz

Pick a model size, a GPU count, and a GPU type. Hit Evaluate (or Space). The right-hand panel walks the three canonical questions a systems engineer asks before opening a distributed-training run — does it fit on one GPU? Can ZeRO shard it? Do the weights alone fit? — and lands on one of five strategies, with a memory summary, a communication-overhead bar, and a strategy-tuned topology diagram.

Configuration
Model size (parameters)
GPU count
GPU type
Space to evaluate / R to reset
Training memory (total)104 GiB
GPU memory80 GiB
Usable (70%)56 GiB
Decision flow
Select inputs and press Evaluate
Decision tree ready. Select a model size, GPU count, and GPU type, then press Evaluate.
Customize
Defaults
7B
8
A100-80GB
600ms

Installation

npx shadcn@latest add https://craftbits.dev/r/parallelism-decision-viz.json

Usage

import { ParallelismDecisionViz } from "@craft-bits/viz/parallelism-decision-viz";
 
<ParallelismDecisionViz />

Drive every input from outside (controlled mode):

const [modelSize, setModelSize] = useState<ParallelismDecisionVizModelSize | null>("70B");
 
<ParallelismDecisionViz
  modelSize={modelSize}
  onModelSizeChange={setModelSize}
/>;

Subscribe to phase transitions for an external scoreboard:

<ParallelismDecisionViz
  onPhaseChange={(phase) => {
    if (phase === "result") trackDecisionLanded();
  }}
/>

Understanding the component

  1. Three chip strips. Model size, GPU count, GPU type — each rendered as a role="radiogroup". Every selection resets the stepper to its idle state.
  2. Memory summary. As soon as all three chips are picked, a token-styled card lands with the training memory total, the GPU's raw memory, and the 70%-usable budget.
  3. Decision tree. Three pre-computed params × ? checks. The stepper walks them one at a time on a 600ms cadence, highlighting the active card and resolving each into a YES / NO pill once visited.
  4. Result card. Lands at the end of the walk with the recommended strategy, a prose description, a three-stat row (memory per GPU, overhead, total training mem), an overhead bar, and a topology diagram.
  5. Topology diagram. Per-strategy SVG that repaints with the strategy's accent — a single rectangle for Single GPU, a row of shards for DP / ZeRO + DP, grouped TP+PP+DP nodes with pipeline arrows for the multi-D strategies.
  6. Reduced motion. Under prefers-reduced-motion: reduce, every entrance collapses to instant, the active-step pulse disappears, and the stepper cadence falls to 100ms.

Props

PropTypeDefaultDescription
modelSizeParallelismDecisionVizModelSize | nullControlled model size. Pair with onModelSizeChange.
defaultModelSizeParallelismDecisionVizModelSize | nullnullUncontrolled initial model size.
onModelSizeChange(size) => voidFires when the model-size chip changes.
gpuCountParallelismDecisionVizGpuCount | nullControlled GPU count.
defaultGpuCountParallelismDecisionVizGpuCount | nullnullUncontrolled initial GPU count.
onGpuCountChange(count) => voidFires when the GPU-count chip changes.
gpuTypeParallelismDecisionVizGpuType | nullControlled GPU type.
defaultGpuTypeParallelismDecisionVizGpuType | nullnullUncontrolled initial GPU type.
onGpuTypeChange(type) => voidFires when the GPU-type chip changes.
onPhaseChange(phase) => voidFires on every idle → deciding → result transition.
modelSizesreadonly ParallelismDecisionVizModelSize[]five tiersOverride the model-size chip strip.
gpuCountsreadonly ParallelismDecisionVizGpuCount[]six tiersOverride the GPU-count chip strip.
gpuTypesreadonly ParallelismDecisionVizGpuType[]three SKUsOverride the GPU-type chip strip.
stepDurationMsnumber600Milliseconds between auto-advanced steps.
transitionTransitionSPRINGS.smoothOverride the entrance spring.
classNamestringMerged onto the root via cn().

Accessibility

  • The root is role="figure" with an aria-label describing the viz; the live region announces the active question while stepping and the final recommendation when it lands.
  • Each chip strip is a role="radiogroup"; chips are <button role="radio"> with aria-checked and data-state styling hooks.
  • The Evaluate button reports its disabled reason via aria-label.
  • Keyboard: Space / Enter evaluates, R resets. The root is tabIndex={0} so screen-reader users can scope into it.
  • Colour is never the only signal — every card carries its YES / NO text pill, the result headline carries the strategy name, and the overhead bar carries the percentage as text.
  • Motion respects prefers-reduced-motion: reduce — every entrance collapses to instant and the auto-advance shortens to 100ms.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/systems/ParallelismDecisionViz.tsx). The source painted directly against the lesson palette (--color-accent-400 / --color-ink-*), used SPRINGS.snappy / SPRINGS.gentle / STAGGER.tight aliases, and rendered narration through the lesson-only ca-narration class. The craft-bits extract rewires every colour through the semantic --cb-* palette, re-keys every transition to SPRINGS.smooth / SPRINGS.snap / SPRINGS.bouncy, replaces STAGGER.tight with the library-wide STAGGER constant, lifts the chip strips and decision cards as cb-* token-styled elements, exposes a Radix-style controlled / uncontrolled API on each strip, surfaces computeParallelismDecision as a named export, and wraps the component in forwardRef accepting className via cn() and spreading ...props on the root.