Skip to content

Analysis and plotting

Plots belong to analysis jobs. Models expose their forward computation; they do not declare plotting callbacks. Compose an analysis with the trainer whose model and configuration it understands:

from theseus.analysis.attention import AttentionHeatmapAnalysis
from theseus.registry import analysis

@analysis("my-gpt/analyze/attention")
class AnalyzeAttention(AttentionHeatmapAnalysis, MyGPTTrainer):
    pass

Put the analysis first so its run() takes precedence. AnalysisBase checks this ordering. Its CONFIG combines the trainer and analysis schemas through normal Python dataclass inheritance.

Run it as an isolated job, with a checkpoint node passed as base= to restore weights through the normal model-surgery path. Without a base, it analyzes newly initialized weights. select(paths) chooses a target module; analyze(layer, inputs) runs inside a compiled pure trainer trace and returns a numerical PyTree. The framework gathers that result and synchronously calls the required plot(results) on host zero. It returns a CPU Matplotlib figure, a JSON value, or None. NAME determines the artifact filename. Host zero saves PDF or JSON and uploads it to Comet when configured.

For trainer integration, declare ANALYSIS = [MyAnalysis]. Each analysis borrows the live trainer's model, state, and node without initializing another state. training/analyze controls whether these analyses run at validation cadence.

The line, scatter, heatmap, and bar helpers in theseus.analysis.plots create figures with scoped Seaborn styling. They accept CPU data. Analysis authors crop or reduce arrays inside analyze() before the framework gathers them and calls plot(). All hosts must agree on collective order. The notebook debugger remains eager and is not used by scheduled analysis. Both paths share the pure trace(state, batch, key, *, sharding) execution boundary; data retrieval and placement stay outside it, using the existing trainer batch APIs.