Skip to content

Bring your model to Seahorse

Every model in Seahorse has the same shape. Express your freshly built STPP model that way once, and it plugs into the entire harness — training, multi-seed benchmarks, every metric profile, and sampling — with no other wiring.

UnifiedSTPP
StateModel event history → hidden state encodeevolve
EventModel hidden state → log-probability log_probsample_nextintensity_grid
you get, for free fit bench · multi-seed evaluate · all profiles predict_next CLI + Python API

Your model is comparable to every baseline by construction: the same data contract, the same normalization, the same metric definitions apply the moment it is registered.

Four steps from nn.Module to benchmarked

  1. 1
    Wrap your model as two parts

    Split it into a StateModel (encodes history into a hidden state) and an EventModel (turns that state into a log-likelihood). Both are plain nn.Modules.

    class MyEventModel(nn.Module): def log_prob(self, times, locs, state, mask): ... Wrap an existing model →
  2. 2
    Wire them in a config

    A ModelFamilyConfig owns the build-time parameters and returns a wired UnifiedSTPP from build_model().

    def build_model(self): return UnifiedSTPP(state, event, hidden_dim=self.hidden_dim) Register a preset →
  3. 3
    Register a preset name

    One decorator makes your model resolve through fit, bench, evaluate, and the Python API — no import-path changes anywhere else.

    @ConfigRegistry.register("my_preset") Full checklist →
  4. 4
    Declare what it can do

    The methods you implement decide which metrics run. An unimplemented capability is reported as a clean skip — never a silent wrong number.

    def sample_next(self, state, t_last, n_samples=1): ... # unlocks predictive metrics Declare capabilities →

Then test and ship

Run a tiny one-epoch fit, an evaluate, and a save/load round-trip before adding the preset to benchmark examples. The Testing Checklist is the short list to clear.

Pick your path

See also