# Eldric Nexus F1

A from-scratch pretrained zero-shot time-series forecaster. 82.50 M parameters,
TiRex-2 architecture ([arXiv:2607.01204](https://arxiv.org/abs/2607.01204)):
12 blocks alternating mLSTM and sLSTM, bidirectional over the context, 9 output
quantiles on 32-step patches.

The weights are our own — pretrained from random initialisation on our corpus,
not fine-tuned from anyone's release. The architecture implementation is NX-AI's,
redistributed under Apache-2.0 (see `NOTICE`).

## Quickstart — three commands

```bash
pip install https://repo.eldric.ai/models/eldric_nexus_f1-1.0.0-py3-none-any.whl
eldric-nexus-f1 check --download          # fetch + verify the 315 MB weights, once
eldric-nexus-f1 forecast --input your.csv --column value --horizon 48
```

The third command prints a CSV to stdout: one row per forecast step, nine
quantile columns `q10 … q90`. `--out file.csv` writes it to a file instead.
`--input` takes a CSV (use `--column` to pick the column) or a file with one
number per line; `-` reads stdin.

For the Python API, the complete runnable example is
[`example_forecast.py`](https://repo.eldric.ai/models/example_forecast.py):

```bash
curl -fLO https://repo.eldric.ai/models/example_forecast.py
python example_forecast.py
```

which prints, on any machine with the package installed:

```
history 512 steps -> forecast 96 steps, shape (9, 96)

  step        q10        q50        q90       truth
     0    131.737    136.037    142.067     133.749
     1    129.981    134.516    140.418     134.003
    95    130.374    136.663    143.566     140.213

  MAE of the median               2.186
  MAE of repeat-last-value       10.423   (0.21x — under 1.00 is better)
  truth inside the q10..q90 band: 100.0 %
```

## Install

```bash
pip install https://repo.eldric.ai/models/eldric_nexus_f1-1.0.0-py3-none-any.whl
```

Pure PyPI, no compiler and **no CUDA toolchain** required: every dependency
(`torch`, `numpy`, `einops`, `flashrnn`, `xlstm`, `PyYAML`) ships a pure-Python
or prebuilt wheel. On CPU and Apple MPS the recurrent kernels run in plain
PyTorch; CUDA is used only if you ask for `device="cuda"`.

Python 3.11–3.13.

## Check it works

```bash
eldric-nexus-f1 check --download
```

This fetches the weights (315 MB) to `~/.cache/eldric-nexus-f1/`, verifies their
SHA-256, loads the model on CPU and prints the parameter count. Run it once
before an evaluation sweep — then you know the download and the checksum are
fine rather than discovering it mid-run.

## Use it

The API is deliberately **identical to TiRex-2's**, so existing evaluation code
needs one line changed:

```python
from eldric_nexus_f1 import load_model      # instead of: from tirex2 import load_model
```

Everything after that is the same:

```python
import torch
from eldric_nexus_f1 import load_model, TimeseriesType

model = load_model()                        # device="cpu" by default
series = TimeseriesType(
    target=torch.randn(1, 512),             # [variates, context], float32
    past_covariates=None,
    future_covariates=None,
)
# Returns a LIST, one entry per input series.
forecasts = model.forecast([series], prediction_length=64, output_type="numpy")

q = forecasts[0][0]                  # (9, 64) = quantiles x horizon
print(q.shape)                       # (9, 64)
print("median of the first 5 steps:", q[4, :5])
print("80 % band at step 0:", q[0, 0], "..", q[8, 0])
```

Quantile rows are in ascending order, `q[0]` = 0.1 … `q[8]` = 0.9, so `q[4]` is
the median. There is no separate mean.

**Feed float32.** A float64 target — which is what you get straight out of
pandas or `numpy.random` — fails deep inside PyTorch with
`mat1 and mat2 must have the same dtype, but got Double and Float`. Cast first:
`torch.from_numpy(arr.astype("float32"))`. The CLI does this for you.

The return value is a **list**, one entry per input series, each shaped
`(variates, quantiles, horizon)`. There is no separate mean — `q50` (index 4) is
the median.

`forecast_gluon(...)` and `forecast_fev(...)` are available with the same
signatures (install the `gluonts` or `fev` extra for those:
`pip install "eldric-nexus-f1[fev]"`).

From the shell, for a quick look:

```bash
eldric-nexus-f1 forecast --input series.csv --horizon 64 --out forecast.csv
eldric-nexus-f1 info
```

## Offline / air-gapped machines

Download the checkpoint once and point at it — no network needed afterwards:

```bash
curl -fLO https://repo.eldric.ai/models/eldric-nexus-f1-model.ckpt
export ELDRIC_NEXUS_F1_WEIGHTS=$PWD/eldric-nexus-f1-model.ckpt
```

`ELDRIC_NEXUS_F1_WEIGHTS` also accepts a directory holding `model.ckpt` plus
`model-config.yaml`, which is the layout TiRex-2 itself ships in. The
architecture file is included in the wheel, so the checkpoint alone is enough.

## What the model was trained on

| | |
|---|---|
| Parameters | 82,500,000 |
| Training steps | 700,000 |
| Context length in training | 2048 |
| Horizon in training | 320 |
| Patch size | 32 (input and output) |
| Quantiles | 0.1 … 0.9 in steps of 0.1 |
| Real-data corpus | 5.99 M series from LOTSA + Chronos + GIFT-Eval (167.6 GB) |
| Synthetic corpus | 15 M Gaussian-process series, drawn at 31.6 % of training samples |
| Coupling | the TiRex-2 pretraining coupling chain (paper §3.4 and appendix F): identity, univariate, mixture, linear and non-linear SCM, cointegration, functional |

Every figure above is read out of the shipped checkpoint's own `cfg`, not from a
training plan. Notably this model saw **no chaotic-system trajectories**: an
earlier version of this table claimed it did, which was wrong.

It generalises to context and horizon lengths other than the training values;
2048/320 is what the sampler drew during pretraining, not a limit of the model.

## Reproducing the claim that the bundled code is unmodified

```bash
pip install "tirex2 @ git+https://github.com/NX-AI/tirex-2@v0.2.1"
python pruef/pruef_bitgleich.py
```

Runs the same checkpoint through the bundled copy and through the upstream
package on the same input and requires the outputs to be bit-identical.

## Licence

Wrapper code and the bundled NX-AI implementation: Apache-2.0 (`LICENSE`,
`NOTICE`).

The **trained weights** are made available for benchmarking, evaluation and
research. For production or commercial use, contact license@eldric.ai.

## Contact

- <https://eldric.ai/>
- license@eldric.ai
