Visualization showcase¶
This page is a documentation-friendly version of examples/viz_showcase.ipynb.
It shows how to:
Compute a few fields via the public
SessionAPI.Add custom per-parameter metadata (so plots can group/color by it).
Render several Plotly figures via
diffract.viz, both from Python objects and from YAML configs (Hydra-style).
Prerequisites¶
Install the visualization extra (and a framework extra if you want to run the example end-to-end):
uv sync --extra viz
uv sync --extra torch # optional, only needed if you run the toy model code
1) Create a session and add models¶
Diffract stores parameters and computed fields in the configured backend. For an interactive visualization workflow you typically want persistence:
from diffract import Session
session = Session(profile="local") # or "hybrid" for large models
The notebook uses a small PyTorch model and attaches metadata like layer_id and
head_id using ParameterOverrides. That metadata becomes available to plots as
columns you can group/color by.
import re
import torch.nn as nn
from diffract import ParameterOverrides
def build_overrides(model: nn.Module) -> dict[str, ParameterOverrides]:
overrides: dict[str, ParameterOverrides] = {}
for name, module in model.named_modules():
if not isinstance(module, nn.Linear):
continue
m = re.match(r"^layers\.(\d+)\.heads\.(\d+)\.proj$", name)
if m:
overrides[name] = ParameterOverrides(
other_meta={
"layer_id": int(m.group(1)),
"head_id": int(m.group(2)),
"kind": "attn_proj",
}
)
continue
m = re.match(r"^layers\.(\d+)\.ffn$", name)
if m:
overrides[name] = ParameterOverrides(
other_meta={
"layer_id": int(m.group(1)),
"head_id": None,
"kind": "ffn",
}
)
return overrides
Add one or more models:
with session:
session.models.add(model_small, model_id="toy_small", parameter_overrides=build_overrides(model_small))
session.models.add(model_big, model_id="toy_big", parameter_overrides=build_overrides(model_big))
2) Compute fields¶
Compute a few scalar fields that plots can consume:
with session:
session.compute.apply("frob_norm", "effective_rank", "stable_rank")
3) Plot from Python objects¶
Box plot (grouped by model)¶
from diffract.viz.data import FieldRef
from diffract.viz.plots.boxplot import BoxPlot
with session:
fig = session.viz.draw(
plot=BoxPlot(
y=FieldRef("stable_rank"),
title="stable_rank by model_id",
x=FieldRef("model_id"),
)
)
fig.show()
You can also use the ergonomic session.viz.box(...) wrapper, which accepts
plain field-name strings:
with session:
fig = session.viz.box(y="stable_rank", x="model_id", title="stable_rank by model_id")
fig.show()
Scatter plot (two scalar fields)¶
from diffract.viz.data import FieldRef
from diffract.viz.plots.scatter import ScatterPlot
with session:
fig = session.viz.draw(
plot=ScatterPlot(
x=FieldRef("frob_norm"),
y=FieldRef("stable_rank"),
title="stable_rank vs frob_norm",
group_by=FieldRef("model_id"),
)
)
fig.show()
Or with the ergonomic session.viz.scatter(...) wrapper (plain field-name
strings):
with session:
fig = session.viz.scatter(
x="frob_norm",
y="stable_rank",
title="stable_rank vs frob_norm",
group_by="model_id",
)
fig.show()
4) Plot from YAML configs (Hydra-style)¶
For reproducible and shareable plots, you can keep plot definitions in YAML and
render them via Session.viz.draw(config_path=...).
All YAML configs used in the notebook live in examples/configs/. For example:
from pathlib import Path
CONFIGS_DIR = Path("examples/configs")
with session:
fig = session.viz.draw(
config_path=CONFIGS_DIR / "boxplot_stable_rank.yaml",
overrides=[], # optional Hydra overrides
)
fig.show()
See Plot configs for the YAML structure and available plot types.
5) Themes and coloring by metadata¶
If you attach metadata via other_meta (like layer_id), you can color by it:
The theme is passed to session.viz.draw(..., theme=...), not to the plot
object. Coloring by metadata is controlled with marker_color.
from diffract.viz import DARK_THEME, MINIMAL_THEME
from diffract.viz.data import FieldRef
from diffract.viz.plots.boxplot import BoxPlot
with session:
fig = session.viz.draw(
plot=BoxPlot(
y=FieldRef("stable_rank"),
title="Stable Rank by Model (Dark theme, color by layer_id)",
x=FieldRef("model_id"),
marker_color=FieldRef("layer_id"),
),
theme=DARK_THEME,
)
fig.show()
with session:
fig2 = session.viz.draw(
plot=BoxPlot(
y=FieldRef("stable_rank"),
title="Stable Rank (Minimal theme)",
x=FieldRef("model_id"),
),
theme=MINIMAL_THEME,
)
fig2.show()
The same is expressible with the ergonomic session.viz.box(...) wrapper, which
accepts plain field-name strings and a theme= argument:
from diffract.viz import DARK_THEME
with session:
fig = session.viz.box(
y="stable_rank",
x="model_id",
marker_color="layer_id",
title="Stable Rank by Model (Dark theme, color by layer_id)",
theme=DARK_THEME,
)
fig.show()
You can also load a theme from YAML (see examples/configs/theme_example.yaml in the repo):
from pathlib import Path
with session:
fig = session.viz.draw(
config_path=Path("examples/configs/boxplot_stable_rank.yaml"),
theme_path=Path("examples/configs/theme_example.yaml"),
)
fig.show()
6) Export results (e.g. pandas)¶
with session:
df = session.results.export_metrics(
"frob_norm",
"effective_rank",
"stable_rank",
export_format="pandas",
)