EvSys

callbacks

Callbacks - hook points inside :class:~evsys_sdk.training.loop.TrainingLoop for logging, debugging, visualization, and early stopping.

The :class:Callback base has no-op defaults for every hook. Override only the ones you need:

class MyDebug(Callback): def on_step_end(self, state, step_idx, batch, metrics): if step_idx % 100 == 0: print(f"[{step_idx}] {metrics}")

Then hand to the loop:

loop = TrainingLoop(..., callbacks=[MyDebug(), CsvMetricsCallback(...)])

A failing callback never kills the loop - the exception is logged at WARNING and the loop continues. Same pattern as failing evaluators.

For early stopping (e.g. on a plateau in val pass_rate), call state.request_stop() from inside a hook and the loop breaks after the current step. Researchers writing a new "stop after N evals without improvement" policy subclass :class:EarlyStoppingCallback.

Three built-ins ship today:

  • :class:PrintProgressCallback - tqdm-style stdout one-liner per step.
  • :class:CsvMetricsCallback - mirror metrics.jsonl to a per-step CSV for pandas-friendly inspection.
  • :class:EarlyStoppingCallback - request_stop after N evals with no improvement on a named metric.
attributelogger
= logging.getLogger(__name__)
attribute__all__
= ['Callback', 'CsvMetricsCallback', 'EarlyStoppingCallback', 'DebugLoggerCallback', 'EvsysLoggerCallback', 'LocalLoggerCallback', 'LogContext', 'LoopState', 'PrintProgressCallback', 'TensorBoardLoggerCallback', 'WandbLoggerCallback', 'build_callbacks', 'dispatch']
funcdispatch(callbacks, hook, *args, **kwargs) -> None

Call hook on every callback. A raising callback NEVER propagates - the exception is logged at WARNING and the next callback runs. Used by both the TrainingLoop (loop-scope hooks) and the Experiment (experiment-scope hooks) so error isolation is identical everywhere.

paramcallbackslist[Callback]
paramhookstr
paramargsAny
= ()
paramkwargsAny
= {}

Returns

None
funcbuild_callbacks(specs) -> list[Callback]

Materialize callbacks from a list of \{kind, params\} specs.

Each spec may be a :class:~evsys_sdk.config.CallbackSpec (or any object/dict with kind + params). The kind is resolved through the callback registry; params are validated against the callback's Config (so a YAML typo fails loudly) before construction. Users register their own callbacks with @register_callback("my_name") - see the built-ins above for the contract (name + Config ClassVars).

paramspecsAny

Returns

list[evsys_sdk.training.callbacks.Callback]
func_fmt_value(v) -> str
paramvAny

Returns

str