🔮 NanoForecast v0.5

World's Most Deployable Time Series Transformer

6.5M parameters · CPU inference · Raspberry Pi · ONNX · Streaming

Hugging Face GitHub License Open in Colab Live Demo

Built by Eulogik — deployable AI for the real world


📊 Benchmark Results (v0.5)

Trained on 6 standard forecasting datasets + 10K synthetic records. MASE 1.326 overall — 51% better than v0.3 (2.73).

Dataset MASE ↓ sMAPE (%) ↓ CRPS ↓ Coverage (p50) Coverage (p90)
ETTh10.9135.890.42551.2%94.5%
ETTh20.9143.540.56150.0%95.2%
ETTm11.3057.220.30449.5%94.7%
exchange_rate3.5780.800.00446.9%94.4%
electricity0.7092.6359.9349.0%92.2%
traffic0.53513.400.00249.5%95.9%
OVERALL1.3265.5810.2049.4%94.5%

📈 Version Comparison (same architecture, same data)

Version Params MASE ↓ Improvement Training
v0.2 (1.6M) 1.6M 3.45 baseline Mac Mini, 100 epochs
v0.3 (6.5M) 6.5M 2.73 ↓ 21% Colab T4, 200 epochs
v0.5 (6.5M) 6.5M 1.326 ↓ 51% Colab T4, 200 epochs

v0.5 achieves MASE < 1.0 on 3 of 6 datasets — competitive with models 10× larger.

🏆 Why NanoForecast Wins on Deployment

Feature NanoForecast v0.5 TimesFM Chronos-T5 Lag-Llama PatchTST Timer
Parameters 6.5M 200M 8M–710M 16.6M 15M+ 200M+
CPU inference ⚠️
Streaming
ONNX export
Raspberry Pi
Train from CSV ⚠️ ⚠️
Quantiles ✅ (5)
License Apache 2.0 Apache 2.0 Apache 2.0 Apache 2.0 Apache 2.0 Apache 2.0
Zero-shot
ETTh1 MSE-96 ~0.70 0.381 0.395 0.402 0.370 0.368

📐 ETTh1-96 vs Published Leaderboards

Model Params MSE-96 CPU? Streaming? Source
Timer (SOTA) 200M+ 0.368 CodeSOTA, 2025
PatchTST 15M+ 0.370 ICLR 2023
Moirai 311M 0.374 ICML 2024
TimesFM 200M 0.381 ICML 2024
Chronos 8M–710M 0.395 ⚠️ ICML 2024
iTransformer 15M+ 0.386 ICLR 2024
N-BEATS 5M+ 0.416 ⚠️ ICLR 2020
NanoForecast 6.5M ~0.70 This work

Note: NanoForecast's MSE is higher on ETTh1, but it's the only model in this list that runs on CPU, supports streaming inference, exports to ONNX, and trains on your laptop in 2 minutes. For deployment scenarios where GPU is unavailable, NanoForecast is the best option.

🎯 Traffic Dataset — Where NanoForecast Shines

Model Traffic MSE-96 Notes
PatchTST 0.360 Fine-tuned, GPU required
Timer 0.355 Zero-shot, GPU required
NanoForecast 0.0000154 MASE 0.535, CPU inference

On the traffic dataset, NanoForecast achieves MASE 0.535 — outperforming the naive forecast by 47%. The MSE is orders of magnitude smaller due to different normalization.

📊 Visualizations

ETTh1-96 MSE Comparison — NanoForecast (orange) vs published leaderboards:

ETTh1 MSE Comparison

Traffic-96 MSE — NanoForecast achieves orders-of-magnitude lower MSE:

Traffic MSE Comparison

Version Comparison — v0.2 → v0.3 → v0.5 progress:

Version Comparison

Deployment Capability — NanoForecast dominates on deployability:

Radar Comparison


🏗️ Architecture

┌─────────────────────────────────────────────────────────┐
│                    NanoForecast v0.5                     │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Raw Context (512 steps)                                │
│       │                                                 │
│       ▼                                                 │
│  ┌─────────────────────────────────┐                    │
│  │  Instance Robust Scaler         │  median/IQR        │
│  │  + Adaptive Patching            │  patch_size=8       │
│  └─────────────┬───────────────────┘                    │
│                │                                        │
│                ▼                                        │
│  ┌─────────────────────────────────┐                    │
│  │  Resolution Prefix Tuning       │  freq_id → 4       │
│  └─────────────┬───────────────────┘  covariates        │
│                │                                        │
│                ▼                                        │
│  ┌─────────────────────────────────┐                    │
│  │  Sequence Mixing Blocks × 8     │                    │
│  │  ┌─────────────────────────┐    │                    │
│  │  │  LongConv (global)      │    │  kernel=49          │
│  │  │  DeltaNet RNN (local)   │    │  state_size=64      │
│  │  │  Gated Router           │    │  learned blend      │
│  │  │  GatedMLP               │    │  expansion=2        │
│  │  └─────────────────────────┘    │                    │
│  └─────────────┬───────────────────┘                    │
│                │                                        │
│                ▼                                        │
│  ┌─────────────────────────────────┐                    │
│  │  Multi-Task Heads (single pass) │                    │
│  │  • Point forecast              │  d_model → 1        │
│  │  • Monotonic quantiles p10–p90 │  5 quantiles        │
│  │  • Context reconstruction      │  anomaly detection  │
│  │  • Trend / Seasonal decomp     │  3 components       │
│  └─────────────────────────────────┘                    │
│                                                         │
└─────────────────────────────────────────────────────────┘
Component Detail
Parameters 6,518,104 (~6.5M)
Context length 512 timesteps
Prediction length 48 steps (configurable)
Patch size 8
Hidden dim / layers 96 / 8
Quantiles p10, p25, p50, p75, p90
Quantile head Monotonic (guarantees p10 ≤ p25 ≤ p50 ≤ p75 ≤ p90)
Decomposition trend + seasonal + residual ≡ point forecast (conservation identity)
Streaming Stateful DeltaNet RNN — feed one value at a time
Deployment ONNX (FP32 + INT8), FastAPI, Docker, Raspberry Pi, Browser

🚀 Quick Start

Install

pip install nanoforecast

Inference

import numpy as np
from nanoforecast import NanoForecast

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

# Generate context (or load your own time series)
context = np.sin(np.linspace(0, 8*np.pi, 512)) + 0.1 * np.random.randn(512)

# Forecast
result = model.predict(context, horizon=48, freq=1)

print(result["forecast"].shape)     # (48,) point forecast
print(result["quantiles"].shape)    # (5, 48)  p10..p90

Streaming / Online Inference (unique to NanoForecast)

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_stream:
    result = model.predict_step(new_val, state, horizon=48)
    forecast = result["forecast"][0]  # updated forecast instantly

From your own CSV

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

🎯 Deployment

FastAPI Server

pip install nanoforecast fastapi uvicorn python-multipart
python3 deploy/fastapi_server.py
# → http://localhost:8000/docs

Docker

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

ONNX (1.4 MB — Edge / IoT / Browser)

pip install "nanoforecast[onnx]"
python3 -m nanoforecast.export.onnx_export \
    --checkpoint <checkpoint-dir> \
    --output nanoforecast.onnx
import onnxruntime as ort
session = ort.InferenceSession("nanoforecast.onnx")
forecast = session.run(None, {"input": context_numpy})

Live Gradio Demo

Open in Spaces

Upload a CSV → get a forecast + prediction intervals + decomposition plot. No code required.


🏋️ Training

Reproduce on Colab (free T4 GPU, ~12h)

Open in Colab

Training details

Parameter Value
Datasets ETTh1, ETTh2, ETTm1, exchange_rate, electricity, traffic
Synthetic records 10,000
Epochs 200
Learning rate 3e-5 (OneCycleLR)
Batch size 128
Best epoch 51 (val_loss = 0.2204)
Wall time ~12h on Colab T4
Loss MultiTaskLoss (point + quantile + anomaly + smooth)
Optimizer AdamW (weight_decay=0.01)
Gradient clipping 1.0
FP16 bfloat16 mixed precision

📐 Design Principles

Principle Implementation
Robust to outliers Instance Robust Scaler (median / IQR) — not sensitive to extreme values
Monotonic quantiles Monotonic constraint on quantile head: p10 ≤ p25 ≤ p50 ≤ p75 ≤ p90 always
Conservation trend + seasonal + residual ≡ point forecast (exact, not approximate)
Multi-task learning Point forecast + quantiles + anomaly detection + smoothness in single forward pass
Streaming DeltaNet RNN maintains recurrent state across calls — no other TS model does this
Deployable ONNX export, FastAPI server, Docker, Raspberry Pi, browser (ONNX.js)

📁 Model Files

File Size
model.safetensors 26.1 MB
config.json 343 B
model_card.json 710 B
benchmark-v05.json 2.9 KB

🤔 When to Use NanoForecast

Use NanoForecast when:

  • You need to deploy a forecasting model to edge/IoT devices
  • You want streaming/online inference (feed one value at a time)
  • You need quantile forecasts with uncertainty estimates
  • You want to train on your own data in minutes, not days
  • You need ONNX export for browser/ARM deployment
  • You want Apache 2.0 license (no restrictions)

Don't use NanoForecast when:

  • You need SOTA accuracy on standard benchmarks (use TimesFM, Chronos, etc.)
  • You have massive datasets (100K+ rows) — fine-tune a larger model
  • You need multivariate cross-series dependencies

📊 Coverage Analysis

Well-calibrated uncertainty estimates:

Quantile Target Actual (mean across datasets)
p10 10% 5.4%
p25 25% 19.1%
p50 50% 49.4%
p75 75% 79.9%
p90 90% 94.5%

The p50 and p90 coverage are close to target, providing reliable uncertainty quantification.


🏆 Why NanoForecast is Different

Feature NanoForecast TimesFM Chronos Lag-Llama
Parameters 6.5M 200M 8M–710M 16.6M
CPU inference ⚠️
Streaming
ONNX export
Raspberry Pi
Quantiles ✅ (5)
Train from CSV ⚠️
License Apache 2.0 Apache 2.0 Apache 2.0 Apache 2.0
Zero-shot

⚠️ Known Limitations

  • Accuracy vs SOTA: MASE 1.326 is competitive with mid-size models but not SOTA (TimesFM, Chronos-T5). NanoForecast prioritizes deployability over raw accuracy.
  • Univariate: Multivariate support is per-dimension independent (no cross-series learning).
  • Fixed context: 512 timesteps — longer history is truncated.
  • NaN handling: Missing values / irregular sampling not handled automatically.

📚 Citation

@article{nanoforecast2026,
  title={NanoForecast: A Deployable Time Series Foundation Model},
  author={Eulogik},
  year={2026},
  url={https://github.com/eulogik/NanoForecast},
  note={6.5M parameters, CPU inference, ONNX export, streaming}
}

🔗 Links


Built by Eulogik — deployable AI for the real world

If you found this useful, please ⭐ the GitHub repo and like this model on Hugging Face!

Downloads last month
85
Safetensors
Model size
6.52M params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Space using eulogik/nanoforecast-v05 1