Skip to main content

Ultra-lightweight time series foundation model architecture (200K-1.6M params) with streaming inference and Hugging Face Hub integration.

Project description

🔮 NanoForecast

World's most deployable time series transformer

HF Spaces HF Model License Python 3.9+ Eulogik

NanoForecast is a tiny, fast, deployable time series forecasting model. Unlike foundation models that require GPUs and terabytes of data, NanoForecast:

  • Trains on your data in 2 minutespython3 train_from_csv.py --csv sales.csv --target revenue
  • Streams forecasts online — the only TS model where you can feed one value at a time
  • Runs on a Raspberry Pi (<50ms inference on ARM)
  • Exports to 1.4 MB ONNX (Edge/IoT/browser ready)
  • Fully Apache 2.0 — no strings attached

It's not a foundation model. It's not going to beat TimesFM on benchmarks. What it does is actually ship to production.


Quick Start

Train on your own data (primary path)

python3 train_from_csv.py --csv my_data.csv --target sales --horizon 48

That's it. You get a saved model checkpoint + forecast CSV. No GPU, no cloud.

Built by Eulogik — deployable AI for the real world.

Or use the pretrained model

pip install nanoforecast
import numpy as np
from nanoforecast import NanoForecast

model = NanoForecast.from_pretrained("eulogik/nanoforecast-500k")

context = np.sin(np.linspace(0, 8*np.pi, 256)) + 0.1 * np.random.randn(256)
result = model.predict(context, horizon=48, freq=1)
forecast = result["forecast"][0]  # shape (48,)

Streaming / Online Inference (unique to NanoForecast)

NanoForecast's DeltaNet RNN architecture maintains a recurrent state across calls — no other TS model does this.

# Initial forecast + state
result = model.predict(context, horizon=48, return_state=True)
state = result.pop("state")

# Stream new observations one at a time
for new_val in incoming_data_stream:
    result = model.predict_step(new_val, state, horizon=48)
    print(result["forecast"][0, :5])  # updated forecast instantly

Each call preserves the DeltaNet's memory of all past data. Use it for:

  • Real-time IoT sensor monitoring
  • Live financial tick data
  • Interactive dashboards

Try It Now

Open in HF Spaces

Upload a CSV, set your horizon, get a forecast + prediction intervals + decomposition plot. No code required.

Features

| Feature | Details | |---|---|---| | Architecture | LongConv + DeltaNet RNN + gated router + MLP blocks | | Parameters | ~200K–700K (tiny) | | Outputs | Point forecast + 5 quantiles (p10/p25/p50/p75/p90) + trend/seasonal/residual decomposition | | Context | 256 timesteps | | Horizon | Any length (trained on 48) | | Frequency | Hourly / Daily / Weekly / Monthly | | Deploy targets | CPU, ARM, Raspberry Pi, Lambda, iOS, browser (via ONNX.js) | | Streaming inference | Stateful RNN — feed one value at a time, no re-processing | | Train on your data | train_from_csv.py — 2 min on a laptop, no GPU |

Deploy

FastAPI Server

pip install nanoforecast fastapi uvicorn python-multipart
python3 deploy/fastapi_server.py
# → http://localhost:8000/docs
curl -X POST http://localhost:8000/predict \
  -d "context=[1.0,2.0,3.0,...]" \
  -d "horizon=48" \
  -d "freq=1"

Docker

docker build -t nanoforecast -f deploy/Dockerfile .
docker run -p 8000:8000 nanoforecast

ONNX (Edge / IoT)

pip install "nanoforecast[onnx]"
python3 -m nanoforecast.export.onnx_export \
    --checkpoint <checkpoint-dir> \
    --output nanoforecast.onnx

Then load with onnxruntime on any platform:

import onnxruntime as ort
session = ort.InferenceSession("nanoforecast.onnx")
forecast = session.run(None, {"input": context_numpy})

Repository layout

nanoforecast/
  config.py              # NanoForecastConfig dataclass
  model/                 # core architecture
    blocks.py            # LongConv, DeltaNet, GatedMLP, GatedRouter
    heads.py             # point, quantile (monotonic), anomaly, decomposition
    core.py              # NanoForecast nn.Module
    utils.py             # scaler, patching, freq prefix, positional encoding
  train/
    loss.py              # multi-task loss (point + quantile + anomaly + smooth)
    trainer.py           # OneCycleLR trainer with MPS / CUDA / CPU support
  data/
    generator.py         # synthetic time series generator
    pipeline.py          # dataset + resolution-aware batch sampler
    real_datasets.py     # ETTh1/2, ETTm1, exchange_rate, electricity, traffic loaders
  evaluation/
    benchmark.py         # MASE, sMAPE, MSE, MAE, CRPS, coverage
  export/
    onnx_export.py       # FP32 + dynamic INT8 ONNX export
  hub.py                 # save_pretrained / from_pretrained / predict mixin
gradio_app.py            # Hugging Face Space (upload CSV → forecast plot)
demo.py                  # one-liner demo: python3 demo.py
deploy/                  # FastAPI server + Docker
  fastapi_server.py
  Dockerfile
  requirements.txt
pretrain.py              # real + synthetic pretraining CLI
benchmark.py             # multi-dataset benchmark CLI
push_to_hub.py           # publish a checkpoint to the HF Hub
run_pipeline.py          # synthetic-only smoke pipeline (legacy)
train_from_csv.py        # train on your own CSV (primary user path)
tests/                   # unit + smoke tests

Architecture

Raw Context  ->  Robust Scaling & Patching  ->  Resolution Prefix Token
                                                  |
                                                  v
                              Sequence Mixing Blocks (x N)
                                - LongConv (global periodicity)
                                - DeltaNet RNN (local dependencies)
                                - Gated Router & MLP (dynamic blend)
                                                  |
                                                  v
                            Multi-Task Heads (single forward pass)
                              - Point forecast
                              - Monotonic quantiles (p10..p90)
                              - Context reconstruction (anomaly)
                              - Trend / Seasonality decomposition
Preset d_model Layers Patch Parameters FP32 size
nano-200k 32 4 8 ~676K ~2.7 MB
nano-500k 64 8 8 ~1.6M ~6.4 MB
nano-1m (v0.3) 96 8 8 ~3.6M ~14 MB

Design notes

  • Instance Robust Scaler (median / IQR) makes the model robust to outliers.
  • Monotonic quantile head guarantees p10 ≤ p25 ≤ p50 ≤ p75 ≤ p90.
  • Conservation identity: trend + seasonal + residual ≡ point forecast.
  • ONNX exportable with a drop-in RMSNorm replacement.

Train Your Own

python3 pretrain.py \
  --datasets ETTh1,ETTh2,exchange_rate,electricity \
  --epochs 50 \
  --batch-size 64 \
  --device cpu \
  --output checkpoints/nanoforecast-my-data

Benchmarking

python3 benchmark.py \
  --checkpoint <checkpoint-dir> \
  --datasets ETTh1,ETTh2,ETTm1,exchange_rate \
  --max-windows 64 \
  --output results/benchmark.json

Publishing to HF Hub

huggingface-cli login
python3 push_to_hub.py \
  --checkpoint <checkpoint-dir> \
  --repo-id your-username/nanoforecast-500k \
  --benchmark-json results/benchmark.json

Benchmarks

v0.3 (d_model=96, 6.5M params, context=512, 200 epochs, Colab T4)

Dataset MASE sMAPE (%) MAE CRPS
ETTh1 1.95 12.06 1.30 1.05
ETTh2 2.74 10.47 2.46 1.99
ETTm1 2.17 10.70 0.72 0.65
exchange_rate 7.44 1.72 0.011 0.014
electricity 1.29 4.76 158.30 175.24
traffic 0.81 24.00 0.004 0.003
Overall 2.73 10.62 27.13 29.83

v0.2 (d_model=64, 1.6M params, context=256, 100 epochs, Mac Mini M4)

Dataset MASE sMAPE (%) MAE CRPS
ETTh1 3.34 25.13 2.40 1.80
ETTh2 3.71 17.65 3.21 2.52
ETTm1 3.58 17.22 1.17 1.00
exchange_rate 7.31 1.63 0.010 0.009
electricity 1.54 5.65 189.75 187.26
traffic 1.25 44.80 0.006 0.006
Overall 3.45 18.68 32.76 32.10

v0.3 vs v0.2 comparison

Dataset v0.2 v0.3 Improvement
ETTh1 3.34 1.95 ↓ 42%
ETTh2 3.71 2.74 ↓ 26%
ETTm1 3.58 2.17 ↓ 39%
exchange_rate 7.31 7.44 ↑ 2%
electricity 1.54 1.29 ↓ 16%
traffic 1.25 0.81 ↓ 35%
Overall 3.45 2.73 ↓ 21%

v0.3 beats v0.2 on 5 of 6 datasets. Larger model (6.5M vs 1.6M) and longer context (512 vs 256) provide significant accuracy gains on ETTh1/ETTh2/ETTm1. Exchange rate (volatile FX) slightly regresses.


Known limitations

Issue Status
Accuracy Modest vs SOTA (MASE ~2.73 overall for v0.3). Good enough for prototypes, not production forecasting at scale.
Training Multi-dataset mixing (v0.3: 6 real + 10K synthetic, 200 epochs).
Context Fixed 256 — longer history is truncated.
Channels Univariate by default; multivariate support is per-dimension independent.
Edge cases NaN values, missing timestamps, irregularly-sampled data not handled automatically.

This is a developer tool, not a research paper. It prioritizes deployability over accuracy.

Roadmap

Version Focus Timeline
v0.1 Deployable MVP — train, predict, export, deploy ✅ Done
v0.2 Streaming inference + train-from-CSV CLI + multi-dataset training (Mac Mini) ✅ Done
v0.3 Colab T4 training (larger model, more data) + ONNX.js browser demo TBD
v0.4 OpenRouter API — $0.001/forecast TBD

Why "NanoForecast"?

Because forecasting models shouldn't require:

  • A $30K GPU
  • 100 GB of training data
  • 12 dependencies that break every release
  • A team of PhDs to deploy

You should be able to train a forecasting model on your laptop, deploy it to a Raspberry Pi, and have it running in production before lunch.

License

Apache 2.0. See LICENSE.


Built by Eulogik — deployable AI for the real world.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nanoforecast-0.2.0.tar.gz (40.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nanoforecast-0.2.0-py3-none-any.whl (39.8 kB view details)

Uploaded Python 3

File details

Details for the file nanoforecast-0.2.0.tar.gz.

File metadata

  • Download URL: nanoforecast-0.2.0.tar.gz
  • Upload date:
  • Size: 40.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for nanoforecast-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7285e603b94e0274af41cb922dc0b3fce774141477164db2ae2c3ae9ca54c0af
MD5 62a34ff6553ddbc9c4a95e6183ffb86d
BLAKE2b-256 24594337e0928a68cca338c81ad30a3193e44dce59dc9453517ce13e2f1c9225

See more details on using hashes here.

File details

Details for the file nanoforecast-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: nanoforecast-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 39.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for nanoforecast-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6cf08f7f69dfb17c5bc7e3e2cf738745d63f75e6c56913608d09030b08db31d0
MD5 07ee9a41c7fd11aa925388a2310917c7
BLAKE2b-256 5e96802df7877ba0b8a95e8405af4984578845ffdbe41e1859f7e6433769d06a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page