--- license: apache-2.0 library_name: transformers pipeline_tag: feature-extraction tags: - surprise - regime-change - model-monitoring - calibrated-uncertainty - abstention - time-series - multi-domain ---
# Zeno Divergent **A learned representation of *model-relative surprise* — the probability that an observable departure happens next, calibrated, with an explicit option to abstain.** [![latest](https://img.shields.io/badge/latest%20revision-v0.7.0-1f2937)](https://huggingface.co/mbarbosa1/zeno-divergent-v1/tree/v0.7.0) [![recommended](https://img.shields.io/badge/recommended-v0.7.0-166534)](https://huggingface.co/mbarbosa1/zeno-divergent-v1/tree/v0.7.0) [![params](https://img.shields.io/badge/parameters-1.87M-1f2937)](#architecture) [![corpora](https://img.shields.io/badge/real%20corpora-7%20of%208-1f2937)](#training-data) [![gate](https://img.shields.io/badge/promotion%20gate-beats%20logistic%20on%202%20domains-166534)](#the-promotion-gate) [![site](https://img.shields.io/badge/zenodivergent.dev-live-1f2937)](https://zenodivergent.dev)
--- ## What is published here | revision | model | corpus | promoted domains | loader | | --- | --- | --- | --- | --- | | **`v0.7.0`** | multi-domain, 1,874,220 params — **latest and recommended** | 8 corpora, 7 real | hydrology, climate | explicit revision (safetensors + config) | | `v0.6.0` | multi-domain, 1,874,220 params — multi-scale windows + robust normalisation | 8 corpora, 7 real | hydrology, markets, climate | explicit revision | | `v0.5.0` | multi-domain, 1,677,870 params — pin this for seismic / space weather | 8 corpora, 7 real | seismic, hydrology, markets, spaceweather | explicit revision | | `v0.3.1` | single-domain, 30,859 params — `transformers`-native custom pipeline | seismic only | seismic | pinned revision, `trust_remote_code=False` | | `v0.2.3` | frozen v0.2 prototype | synthetic | — | remote-code loader | **Read this before picking a revision.** v0.7.0 promotes **fewer** domains than v0.6.0 — two instead of three — because the gate got harder, not because the model got worse. From v0.7.0 onward a domain cannot be promoted unless it **beats a plain logistic regression fitted on the same features**, with a bootstrap CI excluding zero, and unless **no head sits within 0.005 AUROC of chance**. Under v0.6.0's rules none of its promoted domains passed that bar. Under v0.7.0's rules, hydrology and climate do — that is the headline. Markets promoted in v0.6.0 and does not in v0.7.0: it never beat the logistic baseline, and now that is disqualifying. Seismic and space weather still have collapsed rare-event heads; if you need those domains, pin `v0.5.0`. `main` now serves the **v0.7.0** multi-domain weights, so the repository metadata reflects the real model (1,874,220 params) rather than the 30,859-param v0.3.1 seismic checkpoint it used to carry. The `transformers`-native custom pipeline stays available at revision `v0.3.1`. Revisions are immutable: nothing published is ever overwritten in place. **v0.7.0 closed the gap it was built for.** It adds per-target loss normalisation, bounded heteroscedastic attenuation, raised rare-event class weighting, a collapse guard, exclusion of targets with fewer than 25 test positives, and a hard gate requiring a win over the logistic baseline. Two domains now clear that bar. Six do not, and each one is published with its blocking reason attached. --- ## Why this matters Every deployed forecaster carries an invisible assumption: *tomorrow looks enough like the data I was fitted on*. When that assumption dies, the model does not raise its hand. Accuracy degrades, uncertainty stays flat, and the failure is only discovered downstream. The usual answers are partial: | Approach | What it tells you | What it misses | | --- | --- | --- | | Predictive uncertainty (`σ`, ensembles) | how noisy *this* prediction is | stays low right up to a regime break | | Drift / OOD detectors | the inputs moved | fires on harmless movement, silent on harmful stable-looking shifts | | Change-point detection | something changed **already** | it is a post-mortem, not a lead time | | **Zeno Divergent** | **the calibrated probability that an observable departure happens in the next window, with an option to abstain** | it is not a hazard forecast — see [limits](#limits) | **The falsifiable claim this model exists to test:** > A learned representation of model-relative surprise contains information about > future regime change and model failure that is **not** captured by predictive > uncertainty or rule baselines alone — and that representation is **shared > across domains**. The harness is built to *reject* that claim. Every target is scored against a phase-0 rule baseline with entity-level bootstrap confidence intervals, and a pre-declared promotion gate refuses to publish a domain unless the corpus is real and the lifts hold. --- ## How it works ``` observations ──▶ schema contract ──▶ past-only features ──▶ per-domain adapter │ ▼ shared dilated causal trunk │ ▼ surprise state z^S │ ┌──────────────────────────────────────┼───────────────┐ ▼ ▼ ▼ calibrated p_k(t+Δ) uncertainty σ_k abstain gate ``` 1. **Declare a schema.** Categories, numeric channels, targets, horizon. The schema is a contract, not a guess — it is hashed into the config. 2. **Build past-only features.** Row `i` is a function of observations `0..i` and nothing after it. Leakage is re-derived from the raw stream, not asserted. 3. **Adapt, then share.** A small per-domain adapter maps each schema into one **shared** dilated causal trunk. 1,349,417 of the 1,677,870 parameters (80%) are shared across all eight domains — that sharing is the claim under test. 4. **Encode the surprise state `z^S`.** A representation of *how* expectation is failing, common to every head. 5. **Predict observable departures.** One head per target: category-regime transitions, cadence shifts, magnitude-regime shifts, compound transitions. 6. **Calibrate, then gate.** Probabilities are fitted on a held-out validation split; low-evidence rows are marked `abstained` rather than scored. ### What comes back | Field | How to read it | | --- | --- | | `probabilities` | calibrated probability of each observable transition inside the horizon | | `uncertainty` | heteroscedastic spread — large means *poorly determined*, not *safe* | | `abstained` | admission control. **"Not enough evidence", never "nothing to see"** | | `surprise_index` | max over targets — a ranking, not a probability of harm | | `latent` | `z^S` itself, for probing and transfer studies | --- ## Results Held-out chronological test split with a horizon buffer, entity-level bootstrap CIs, one row per domain showing its strongest scored target. ### v0.7.0 — latest revision **Promoted — cleared the pre-declared gate, *including* a win over a logistic regression fitted on the same features** | domain | corpus | entities | rows | best target | AUROC (95% CI) | ECE | beats logistic on | | --- | --- | --- | --- | --- | --- | --- | --- | | **Climate** | NOAA GHCN-Daily | 179 | 739,220 | `heat_extreme_ahead` | **0.890** [0.869, 0.910] | 0.010 | `weather_regime_transition`, `diurnal_collapse`, `compound_climate_stress` | | **Hydrology** | USGS daily water services | 320 | 419,840 | `flow_regime_transition` | **0.786** [0.774, 0.798] | 0.017 | `discharge_regime_shift`, `volatility_regime_shift` | **Not promoted — published with the blocking reason, not hidden** | domain | best AUROC | why it did not promote | | --- | --- | --- | | Seismic | 0.644 | does not beat the logistic baseline on any target; 3 heads still collapsed to chance; worst ECE 0.79 | | Space weather | 0.664 | no logistic win; 4 collapsed heads; worst ECE 0.11 | | Markets | 0.664 | no logistic win; worst ECE 0.101, just over the 0.10 bound | | Macro (FRED) | 0.922 | no logistic win; 2 collapsed heads; 80 entities, below the 100 minimum | | Wildfire (NASA FIRMS) | 0.528 | beats neither the rule nor the logistic baseline; all 6 heads at chance; ECE 0.95 | | Chaos (Lorenz-96 / Kuramoto) | 0.998 | **synthetic corpus.** A deterministic control that proves the pipeline runs. Never evidence about real data. | **External-corpus transfer (evidence only, never gating).** The trunk and `z^S` are frozen and only fresh adapters and heads are fitted on corpora the model never trained on: | corpus | entities | rows | best target | AUROC | | --- | --- | --- | --- | --- | | `Salesforce/lotsa_data` | 240 | 337,140 | regime transition | ~0.92 | | `Salesforce/GiftEvalPretrain` | 240 | 338,832 | `regime_transition` | 0.786 | Several proxy targets on both external corpora sit at 0.5 — the shared representation transfers for transition detection and not, so far, for the magnitude-shift proxies. ### v0.6.0 — previous revision **Promoted (cleared the pre-declared gate)** | domain | corpus | entities | rows | best target | AUROC (95% CI) | ECE | abstention gain | | --- | --- | --- | --- | --- | --- | --- | --- | | **Climate** | NOAA GHCN-Daily | 182 | 739,220 | `heat_extreme_ahead` | **0.883** [0.860, 0.903] | 0.011 | +0.045 @ 0.77 coverage | | **Hydrology** | USGS daily water services | 320 | 419,840 | `flow_regime_transition` | **0.770** [0.757, 0.782] | 0.015 | +0.021 @ 0.79 coverage | | **Markets** | Coinbase public market data | 357 | 258,570 | `dislocation_ahead` | **0.691** [0.672, 0.712] | 0.092 | +0.034 @ 0.89 coverage | **Not promoted — published with the blocking reason, not hidden** | domain | entities | best AUROC | why it did not promote | | --- | --- | --- | --- | | Seismic | 224 | 0.640 | **regression against v0.5.0.** Four of five heads collapsed to a constant 0.500 while a logistic regression on the same features reaches 0.887. Rare-positive training defect. | | Space weather | 293 | 0.644 | **regression against v0.5.0.** Four heads collapsed to 0.500 against a 0.78–0.84 logistic baseline. Same defect. | | Macro (FRED) | 80 | 0.731 | below the 100-entity minimum and below the AUROC floor on every target. | | Wildfire (NASA FIRMS) | 250 | 0.692 | below the floor; calibration still the weakest of the real corpora. | | Chaos (Lorenz-96 / Kuramoto) | 240 | 0.998 | **synthetic corpus.** A deterministic control that proves the pipeline runs. Never evidence about real data. | **The honest headline:** no promoted domain in v0.6.0 yet beats a logistic regression fitted on the same features. Multi-scale windows and robust median/IQR normalisation bought climate and cost seismic. Closing that gap is the entire purpose of v0.7.0. ### v0.5.0 — recommended for seismic and space weather | domain | corpus | entities | rows | best target | AUROC (95% CI) | ECE | abstention gain | | --- | --- | --- | --- | --- | --- | --- | --- | | **Seismic** | USGS FDSN events | 224 | 44,470 | `significant_event_ahead` | **0.911** [0.878, 0.933] | 0.071 | +0.092 @ 0.69 coverage | | **Space weather** | GFZ Potsdam Kp/ap/F10.7 | 293 | 63,224 | `activity_transition` | **0.823** [0.804, 0.839] | 0.044 | +0.091 @ 0.51 coverage | | **Hydrology** | USGS daily water services | 320 | 419,840 | `flow_regime_transition` | **0.781** [0.771, 0.791] | 0.017 | +0.021 @ 0.83 coverage | | **Markets** | Coinbase public market data | 357 | 258,570 | `dislocation_ahead` | **0.709** [0.691, 0.731] | 0.084 | +0.037 @ 0.81 coverage | ### Cross-domain transfer (leave-one-domain-out) The trunk and `z^S` are trained on the *other* domains, then frozen; only the held-out domain's adapter and heads are fitted. If the shared representation were domain-specific bookkeeping, transfer would collapse. It does not — five domains (seismic, hydrology, markets, space weather, climate) clear the gate under leave-one-domain-out transfer in v0.6.0. That result is **reported, not required**: the gate rule is discrimination and calibration on each domain's own corpus. ### The promotion gate Declared before the run, applied without discretion: ``` real corpus required · ≥ 2 targets significant vs phase-0 rules paired lift vs phase-0 ≥ 0.03 · worst-target ECE ≤ 0.10 selective-accuracy gain ≥ 0.02 · ≥ 100 entities leakage tests must pass ``` v0.7.0 adds two rules that v0.6.0 would have failed: **beat a logistic regression on the same features**, and **block any head sitting within 0.005 of chance**. **Verdict for v0.7.0: `promoted`** — two real-corpus domains cleared the gate, and for the first time both of them beat a logistic regression on the same features. Six domains did not clear it and ship as candidates with their blocking reasons attached. v0.4.0 is a documented gate failure and was never published as a model. Full run report in `report.json`, digests in `SHA256SUMS`. If those digests do not match your rebuild, you are not looking at the same artifact. --- ## Quick start **The current model (`main`, v0.7.0)** loads through the standard Auto classes, no `trust_remote_code`: ```bash pip install "zeno-divergent>=0.7.0" transformers torch ``` ```python from transformers import AutoModel import zeno_divergent # registers config + model with the Auto classes model = AutoModel.from_pretrained("mbarbosa1/zeno-divergent-v1") model.describe() # {'model_version': '0.7.0', 'parameters': 1874220, # 'promoted_domains': ['climate', 'hydrology'], 'steps': 12, ...} events = [ {"timestamp": 1717171717.0, "category": "elevated_flow", "values": {"discharge_cfs": 812.0, "abs_daily_change_cfs": 41.0, "rise_ratio": 1.2}}, # ... chronological, one entity ] rows = model.score_events(events, domain="hydrology", entity_id="usgs-01646500") last = rows[-1] last.probabilities # calibrated, one per declared target last.uncertainty, last.risk, last.abstained last.promoted # False => this domain did not clear the release gate ``` Discover a domain's contract instead of hardcoding it: ```python info = model.domain_info("hydrology") info["schema"]["categories"], info["schema"]["channels"], info["targets"] info["promoted"], info["blocking_reasons"], info["abstention_threshold"] # refuse exploratory output outright model.score_events(events, domain="seismic", entity_id="x", allow_unpromoted=False) # ValueError: 'seismic' did not clear the release gate (...) ``` Standardisation statistics, degenerate-column masks, per-target calibration and the abstention threshold all travel in **`inference.json`** in this revision, and are applied in the run's own order (standardise and clamp, *then* zero degenerate columns). That is the same chain the exported browser ONNX graphs run, so a Python score and an in-browser score of the same window agree to ~1e-7. Six of the eight domains did not clear the v0.7.0 gate. They still carry weights and still return numbers, but every row comes back `promoted=False`. Do not present those as validated results; for seismic or space weather, pin `revision="v0.5.0"`. Older APIs stay pinned and unchanged: `revision="v0.3.1"` for the single-domain `transformers` pipeline, `revision="v0.2.3"` for the frozen synthetic prototype. No GPU, no network calls at inference time. --- ## Architecture | | | | --- | --- | | architecture | per-domain input adapters → shared dilated causal trunk → shared surprise latent `z^S` → per-domain calibrated heads | | parameters | **1,874,220** total (v0.7.0), **1,349,417 shared** (72%) across 8 domains; v0.5.0 is 1,677,870 | | domains | 8 schemas, 7 real corpora, 2 promoted in v0.7.0 under a stricter gate (3 in v0.6.0, 4 in v0.5.0) | | features | 72 per step, multi-scale windows (5 / 20 / 100 events) + calendar features, robust median/IQR normalisation | | training | 14 epochs, seed 7, batch 512, lr 1.5e-3, single NVIDIA L4 | | auxiliary objectives | counter-expectation head, domain-adversarial head, contrastive surprise objective, per-target loss normalisation, bounded log-variance | | precision | float32, safetensors | | runtime | CPU, sub-millisecond per row |
Why did the parameter count move around across versions? Capacity is set by what the corpus supports, not by what looks impressive. v0.2.x was a wide multi-reference encoder over a *synthetic* ten-mechanism generator (large, but fitted to a simulator). v0.3 replaced it with a domain-neutral schema contract over one real corpus, and capacity dropped to ~31k accordingly. v0.5.0 trains one shared trunk across eight real schemas at once, so capacity is back up to 1.68M, and v0.6.0 to 1.87M with the multi-scale feature set — this time earned by real data breadth, not by a generator. Nothing was ever pruned or quantised; every version stays loadable at its own revision.
--- ## Training data Public, credential-free sources. No personal data, no identity, no intent, no ownership fields — the input contract rejects them. | domain | source | | --- | --- | | seismic | USGS FDSN event web service | | hydrology | USGS Water Services daily values | | markets | Coinbase Exchange public market data API | | spaceweather | GFZ Potsdam Kp/ap/F10.7 (definitive, CC BY 4.0) | | climate | NOAA GHCN-Daily station access files | | macro | FRED (Federal Reserve Bank of St. Louis) | | wildfire | NASA FIRMS active fire detections (VIIRS) | | chaos | in-repo Lorenz-96 / Kuramoto integrator (deterministic control) | Splits are chronological with a horizon buffer between them. --- ## Intended use **In scope** - Research on model-validity forecasting and surprise representations - Advisory decision support with a named human owner - Prioritising which observation to collect next - Benchmarking change-point and surprise detectors against a locked protocol - Reproducing — or falsifying — the claim above on your own corpus **Out of scope** - Automated or safety-critical actuation - Reading the output as the probability of a *physical* event (it predicts model failure, not hazard) - A single cross-domain risk number - Scoring people. Entities are models, sensors, regions, instruments, processes — never individuals. --- ## Limits - **Two domains are promoted in v0.7.0, not eight.** Those numbers are published so they can be checked, not because they are trusted. - Hydrology and climate beat a logistic regression on the same features. **The other six do not** — on those domains a linear baseline is still the honest choice, and the model says so rather than hiding it. - Seismic, space weather, macro and wildfire still contain heads collapsed at chance. The collapse guard now blocks them from promotion instead of averaging them away. - Leave-one-domain-out transfer promoted nothing in this revision. - Probabilities are calibrated on the validation split; recalibrate before using them as decision thresholds in a new deployment. - Abstention must be surfaced next to the score. Hiding it turns "not observed" into "not at risk" — that is a misuse. - The model predicts *observable* transitions in a public descriptive stream. It makes no claim about identity, intent, ownership or causation. - `main` serves v0.7.0. Pin `revision="v0.5.0"` for seismic and space weather, or `revision="v0.3.1"` for the `transformers`-native single-domain pipeline. --- ## Citation ```bibtex @software{zeno_divergent_0_7_0, title = {Zeno Divergent: a shared representation of model-relative surprise}, author = {Barbosa, M.}, year = {2026}, url = {https://huggingface.co/mbarbosa1/zeno-divergent-v1}, version = {v0.7.0} } ```
**[zenodivergent.dev](https://zenodivergent.dev)** — live workspace, interactive benchmarks, full documentation.