Module Train.Outlier_detector

A sliding-window z-score outlier detector for host-observed scalars (per llm.c's llmc/outlier_detector.h): feed it the per-step loss and/or grad_l2_norm values and skip the optimizer step when the returned z-score exceeds a threshold. Pure host-side state; use one detector per monitored quantity.

type t = {
  1. window : Base.float Base.array;
  2. mutable count : Base.int;
    (*

    Number of recorded values while the window is still filling.

    *)
  3. mutable index : Base.int;
    (*

    Replacement position once the window is full.

    *)
}
val create : ?window_size:??? -> unit -> t
val update : t -> Base.Float.t -> Base.Float.t

Returns v's z-score against the sliding window of the previously recorded values, then records v (replacing the oldest sample): Float.nan until the window has filled — treat that as "not an outlier". Three deliberate departures from llm.c's update_detector: the score is computed before v joins the window, since self-inclusion dilutes the baseline and caps any finite spike's score at sqrt (n - 1) — for a small window that bound sits below reasonable thresholds; a non-finite v never enters the window and scores infinity, so any finite threshold flags it and the update is skipped, while later samples still get a healthy baseline; and the moments are recomputed from the stored window on normalized values instead of llm.c's running sum/sum_sq — the E[x^2] - E[x]^2 form cancels catastrophically for a window with a large common offset and small variance, and even a centered sum can overflow once samples near the float maximum have been recorded, turning later scores into 0 or nan — false passes. Normalization goes first so every intermediate is bounded: mag = max_i (abs x_i) is a pure maximum (cannot overflow), the mean is accumulated as x /. mag /. n (partial sums within [-1, 1]), and deviations x/mag - mean/mag lie in [-2, 2] — no finite window can overflow any of it; O(window) per step is free on the host where llm.c needed O(1) in a kernel-adjacent loop. A genuinely constant-valued window has standard deviation 0, making the z-score of any deviation infinity (and of v = mean, 0).