← browse the library
Distributed data-parallel training preview
template

Distributed data-parallel training

Editable data-parallel training figure composing the dataset, gpu, and server icons: a training-data source shards batches to GPU workers that exchange gradients and weights with a parameter server. Parametric spacing and labels.

This template ships an edit contract (in its meta.json) that the repo-wide using-opentikz skill reads to edit it reliably — the parameters and safe operations are listed below.

iddistributed-training
typetemplate
domainml, systems
venueNeurIPS, MLSys, OSDI
requirestikz, arrows.meta, positioning
licenseCC0-1.0
authorOpenTikZ contributors

distributed trainingdata parallelparameter servergpugradientssynchronizationsystem diagram

Download SVG
template.tex
\documentclass[border=10pt]{standalone}

% --- packages (mirror these in figure.meta.json "requires") ---
\usepackage{tikz}
\usetikzlibrary{positioning, arrows.meta}

% --- palette (canonical source: reference/color-palettes/color-palettes.md; light variant) ---
\definecolor{otblue}{HTML}{0072B2}
\definecolor{otorange}{HTML}{E69F00}
\definecolor{otteal}{HTML}{009E73}
\definecolor{otpurple}{HTML}{CC79A7}
\definecolor{otgray}{HTML}{5A5A5A}

% ===== reusable icon sub-pictures (adapted from icons/) ==================
% Each is a small self-contained tikzpicture, dropped into a node so it can be
% positioned and connected by its anchors. Swap/extend with other icons.
\newcommand{\datasetpic}{%
  \begin{tikzpicture}[line width=0.6pt]
    \fill[otteal!8] (0,0) rectangle (1.3,0.9);
    \filldraw[draw=otteal!75!black, fill=otteal!22] (0,0.9) rectangle (1.3,1.2);
    \draw[otteal!55] (0.433,0)--(0.433,1.2) (0.866,0)--(0.866,1.2)
                     (0,0.3)--(1.3,0.3) (0,0.6)--(1.3,0.6);
    \draw[draw=otteal!75!black, line width=0.8pt] (0,0.9)--(1.3,0.9) (0,0) rectangle (1.3,1.2);
  \end{tikzpicture}}
\newcommand{\gpupic}{%
  \begin{tikzpicture}[line width=0.6pt]
    \filldraw[draw=otteal!70!black, fill=otteal!12, rounded corners=1.5pt] (0,0) rectangle (1.9,1.0);
    \begin{scope}[shift={(0.55,0.5)}]
      \filldraw[draw=otteal!75!black, fill=otteal!20] (0,0) circle[radius=0.32];
      \foreach \a in {0,60,...,300}{\draw[otteal!70!black, line width=0.5pt] (0,0)--(\a:0.28);}
      \filldraw[draw=otteal!75!black, fill=otteal!45] (0,0) circle[radius=0.07];
    \end{scope}
    \node[font=\sffamily\scriptsize\bfseries, text=otteal!80!black] at (1.35,0.5){GPU};
    \foreach \i in {0,...,5}{\draw[otorange!80!black, line width=1pt] (0.25+\i*0.14,0)--+(0,-0.12);}
  \end{tikzpicture}}
\newcommand{\serverpic}{%
  \begin{tikzpicture}[line width=0.6pt]
    \foreach \i in {0,1,2}{
      \filldraw[draw=otblue!75!black, fill=otblue!12, rounded corners=1pt]
        (0,\i*0.44) rectangle (1.5,\i*0.44+0.34);
      \filldraw[otteal] (0.18,\i*0.44+0.17) circle[radius=0.05];
      \foreach \j in {0,1,2}{\draw[otblue!55!black, line width=0.5pt]
        (1.5-0.2-\j*0.13,\i*0.44+0.08)--+(0,0.18);}
    }
  \end{tikzpicture}}
% ========================================================================

\begin{document}
% ==== parameters (edit these) ============================================
\def\colsep{4.6}    % horizontal gap between stages: data -> workers -> server (cm)
\def\rowsep{2.5}    % vertical gap between GPU workers (cm)
% labels
\def\datalabel{Training data}
\def\workeronelabel{Worker 1}
\def\workertwolabel{Worker 2}
\def\workerthreelabel{Worker 3}
\def\pslabel{Parameter server}
\def\batchlabel{batch}
\def\gradlabel{$\nabla\theta$}
\def\weightlabel{$\theta$}
\def\titlelabel{Distributed data-parallel training}
% =========================================================================

\begin{tikzpicture}[
    >={Stealth[length=2.4mm]},
    icon/.style={inner sep=1pt},
    slbl/.style={font=\sffamily\footnotesize, text=otgray},
    data/.style={draw=otgray!75, line width=1pt, ->},
    grad/.style={draw=otpurple!85!black, line width=1pt, ->},
    wts/.style={draw=otteal!70!black, line width=1pt, ->, dashed},
  ]

  % data source
  \node[icon] (data) at (0,0) {\datasetpic};
  \node[slbl, below=2pt of data] {\datalabel};

  % GPU workers
  \node[icon] (w1) at (\colsep, \rowsep)  {\gpupic};
  \node[icon] (w2) at (\colsep, 0)        {\gpupic};
  \node[icon] (w3) at (\colsep, -\rowsep) {\gpupic};
  \node[slbl, below=2pt of w1] {\workeronelabel};
  \node[slbl, below=2pt of w2] {\workertwolabel};
  \node[slbl, below=2pt of w3] {\workerthreelabel};

  % parameter server
  \node[icon] (ps) at (2*\colsep,0) {\serverpic};
  \node[slbl, below=2pt of ps] {\pslabel};

  % data sharding: dataset -> workers
  \draw[data] (data.east) -- (w1.west);
  \draw[data] (data.east) -- (w2.west) node[midway, above, slbl] {\batchlabel};
  \draw[data] (data.east) -- (w3.west);

  % synchronisation: gradients up to the server, weights back down (curved apart)
  \foreach \w in {w1,w2,w3}{
    \draw[grad] (\w.east) to[bend left=10] (ps.west);
    \draw[wts]  (ps.west) to[bend left=10] (\w.east);
  }
  \node[slbl, text=otpurple!85!black] at (1.5*\colsep,0.6)  {\gradlabel};
  \node[slbl, text=otteal!70!black]   at (1.5*\colsep,-0.6) {\weightlabel};

  % title
  \node[font=\sffamily\bfseries] at (\colsep,{\rowsep+1.2}) {\titlelabel};

\end{tikzpicture}
\end{document}

Edit contract — how the AI edits this template

using-opentikz skill →
Parameters & safe edit operations

Parameters

\colsephorizontal gap between the three stages (data -> workers -> server) default 4.6
\rowsepvertical gap between adjacent GPU workers default 2.5
\datalabeldata-source label
\workeronelabeltop GPU worker label
\workertwolabelmiddle GPU worker label
\workerthreelabelbottom GPU worker label
\pslabelparameter-server label
\batchlabellabel on the data-sharding edge
\gradlabelgradient-flow label (math allowed)
\weightlabelweight-flow label (math allowed)
\titlelabelfigure title

Node naming

fixed semantic names: (data) source; GPU workers (w1)(w2)(w3) top-to-bottom; (ps) parameter server. New workers continue the w<n> sequence and are positioned at (\colsep, k*\rowsep)

Operations

  • rename-node — edit the matching label macro (\datalabel, \worker*label, \pslabel, \titlelabel)
  • add-worker — declare \node[icon] (w4) at (\colsep, k*\rowsep) {\gpupic} plus its slbl label, then add it to the sync \foreach list and a data edge from (data.east)
  • change-spacing — edit \colsep (stage gap) or \rowsep (worker gap); the server and title positions are derived from \colsep/\rowsep
  • swap-icon — replace a node body picture macro (\datasetpic, \gpupic, \serverpic) with another icon sub-picture adapted from icons/
  • recolor — change the palette name in the data/grad/wts styles or an icon macro; keep distinct flows (data/gradient/weight) in distinct colors; never inline hex

Use it

The file compiles on its own (\documentclass{standalone}). Drop it into your project and \input it, or copy the tikzpicture into your figure. Colours come from the shared palette defined in the preamble — edit those named colours, not raw hex.

Graphic content is CC0 1.0 (public domain) — reuse freely, no attribution required.