Modular Time Series Forecasting Library
Project description
foreBlocks: Modular Deep Learning Library for Time Series Forecasting
foreBlocks is a flexible and modular deep learning library for time series forecasting, built on PyTorch. It provides a wide range of neural network architectures and forecasting strategies through a clean, research-friendly API โ enabling fast experimentation and scalable deployment.
๐ GitHub Repository ยท PyPI
๐ Quick Start
pip install foreblocks
Or install from source:
git clone https://github.com/lseman/foreblocks.git
cd foreblocks
pip install -e .
import torch
from foreblocks import (
ForecastingModel, Trainer, TrainingConfig,
create_dataloaders, LSTMEncoder, LSTMDecoder,
)
# Build a seq2seq LSTM forecaster
encoder = LSTMEncoder(input_size=8, hidden_size=128, num_layers=2)
decoder = LSTMDecoder(hidden_size=128, output_size=1, num_layers=2)
model = ForecastingModel(
encoder=encoder,
decoder=decoder,
forecasting_strategy="seq2seq",
target_len=24,
)
# Create data loaders
train_loader, val_loader = create_dataloaders(
X_train, y_train, X_val, y_val, batch_size=32
)
# Train
config = TrainingConfig(num_epochs=100, learning_rate=1e-3, use_amp=True)
trainer = Trainer(model, config=config)
trainer.train(train_loader, val_loader)
โจ Key Features
| Feature | Description |
|---|---|
ForecastingModel |
Unified model wrapping any encoder/decoder pair with pluggable heads |
| Modular Blocks | LSTM, GRU, Transformer, TCN, xLSTM, ODE, Graph, Fourier, Wavelet |
| Head System | 13+ composable heads: RevIN, DAIN, Decomposition, PatchEmbed, FFT, Wavelet, Time2Vec, โฆ |
| Forecasting Strategies | seq2seq, autoregressive, direct, transformer_seq2seq |
| Conformal Prediction | 7 methods: split, local, rolling, agaci, enbpi, cptc, afocp |
| NAS via HeadComposer | Differentiable head search with configurable alpha LR and warmup |
Trainer |
AMP, gradient clipping, early stopping, LR scheduling, MLTracker SQLite logging |
ModelEvaluator |
MAE, RMSE, MAPE, SMAPE, MASE, coverage, sharpness, Winkler score |
๐๏ธ Architecture Overview
Input Tensor โโโฌโโ[input head]โโโบ Encoder โโ[encoder head]โโโบ
โ โ
โ โผ
โ Attention Module
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโบ
โ
โผ
Decoder โโ[decoder head]โโโบ
โ
[output head / head_only]
โ
Output Tensor
ForecastingModel glues any encoder, decoder, and attention module together and routes each forward pass through the chosen forecasting_strategy. Heads can be inserted at eight positions (input, encoder, attention, decoder, output, input_norm, output_norm, head) via add_head().
๐ฎ Forecasting Strategies
LSTM Seq2Seq
from foreblocks import ForecastingModel, LSTMEncoder, LSTMDecoder
encoder = LSTMEncoder(input_size=8, hidden_size=128, num_layers=2)
decoder = LSTMDecoder(hidden_size=128, output_size=1, num_layers=2)
model = ForecastingModel(
encoder=encoder, decoder=decoder,
forecasting_strategy="seq2seq",
target_len=24,
)
Transformer Seq2Seq
from foreblocks import ForecastingModel, TransformerEncoder, TransformerDecoder
encoder = TransformerEncoder(input_size=8, d_model=128, nhead=4, num_layers=3)
decoder = TransformerDecoder(d_model=128, output_size=1, nhead=4, num_layers=3)
model = ForecastingModel(
encoder=encoder, decoder=decoder,
forecasting_strategy="transformer_seq2seq",
target_len=24,
)
Autoregressive & Direct
from foreblocks import ForecastingModel, LSTMEncoder
encoder = LSTMEncoder(input_size=8, hidden_size=128, num_layers=2)
# Autoregressive: step-by-step, feeding last prediction as next input
ar_model = ForecastingModel(
encoder=encoder,
forecasting_strategy="autoregressive",
target_len=24, output_size=1,
)
# Direct: single-shot multi-step projection
direct_model = ForecastingModel(
encoder=encoder,
forecasting_strategy="direct",
target_len=24, output_size=1,
)
โ๏ธ Advanced Features
Head System
from foreblocks.core.heads import RevinHead, PatchEmbedHead, FFTTopKHead
# Add a reversible instance normalisation head at the input
model.add_head(RevinHead(num_features=8), position="input")
# Stack patch embedding before the encoder
model.add_head(PatchEmbedHead(input_size=8, patch_size=16, d_model=128), position="encoder")
# FFT spectral filtering at the output
model.add_head(FFTTopKHead(top_k=16), position="output")
# Inspect all heads
print(model.list_heads())
Available heads: RevinHead, DAINHead, DecompositionHead, DifferencingHead,
DropoutTSHead, FFTTopKHead, HaarWaveletTopKHead, LearnableFourierSeasonalHead,
MultiKernelConvHead, MultiscaleConvHead, PatchEmbedHead, Time2VecHead, TimeAttentionHead
Neural Architecture Search (HeadComposer)
from foreblocks import TrainingConfig
from foreblocks.core.heads import HeadComposer, HeadSpec, RevinHead, DAINHead, PatchEmbedHead
# Define a search space
candidates = [RevinHead(8), DAINHead(8), PatchEmbedHead(8, 16, 128)]
composer = HeadComposer([HeadSpec(h) for h in candidates])
model.set_head_composer(composer)
# Enable NAS in training
config = TrainingConfig(
num_epochs=100,
train_nas=True,
nas_alpha_lr=3e-4,
nas_warmup_epochs=10,
)
trainer = Trainer(model, config=config)
trainer.train(train_loader, val_loader)
Conformal Prediction Intervals
from foreblocks import TrainingConfig, Trainer
config = TrainingConfig(
conformal_enabled=True,
conformal_method="enbpi", # split | local | rolling | agaci | enbpi | cptc | afocp
conformal_quantile=0.9,
)
trainer = Trainer(model, config=config)
trainer.train(train_loader, val_loader)
# Calibrate on held-out data, then predict with intervals
trainer.calibrate_conformal(cal_loader)
preds, lower, upper = trainer.predict_with_intervals(X_test)
coverage = trainer.compute_coverage(y_test, lower, upper)
trainer.plot_intervals(y_test, lower, upper)
Scheduled Sampling
from foreblocks.aux.utils import linear_schedule, exponential_schedule, inverse_sigmoid_schedule
# Linear decay: teacher forcing ratio goes from 1.0 โ 0.0 over training
model = ForecastingModel(
encoder=encoder, decoder=decoder,
forecasting_strategy="seq2seq",
target_len=24,
scheduled_sampling_fn=linear_schedule(start=1.0, end=0.0, total_steps=100),
)
๐ ๏ธ Configuration Reference
TrainingConfig
| Parameter | Default | Description |
|---|---|---|
num_epochs |
100 |
Maximum training epochs |
learning_rate |
0.001 |
Optimiser learning rate |
batch_size |
32 |
Mini-batch size |
patience |
10 |
Early-stopping patience (epochs) |
use_amp |
True |
Mixed-precision (AMP) training |
gradient_clip_val |
None |
Gradient norm clipping value |
scheduler_type |
None |
LR scheduler: cosine, step, plateau, โฆ |
weight_decay |
0.0 |
L2 regularisation coefficient |
train_nas |
False |
Enable differentiable NAS |
nas_alpha_lr |
3e-4 |
Architecture parameter learning rate |
nas_warmup_epochs |
5 |
Epochs before NAS search begins |
conformal_enabled |
False |
Enable conformal prediction |
conformal_method |
"split" |
Conformal method (split, local, rolling, agaci, enbpi, cptc, afocp) |
conformal_quantile |
0.9 |
Coverage target quantile |
ModelConfig
| Parameter | Description |
|---|---|
input_size |
Number of input features |
hidden_size |
Encoder/decoder hidden units |
num_layers |
Number of recurrent/transformer layers |
output_size |
Number of output targets |
target_len |
Forecast horizon |
dropout |
Dropout rate |
forecasting_strategy |
One of seq2seq, autoregressive, direct, transformer_seq2seq |
model_type |
One of lstm, transformer, informer-like, head_only |
use_attention |
Whether to add an attention module |
nhead |
Number of attention heads (Transformer) |
๐ Documentation
| Resource | Link |
|---|---|
| Full Docs | lseman.github.io/foreblocks |
| Custom Blocks Guide | docs/custom_blocks.md |
| Transformer Guide | docs/transformer.md |
| Preprocessor Guide | docs/preprocessor.md |
| DARTS Guide | docs/darts.md |
| GitHub Repo | github.com/lseman/foreblocks |
| PyPI Package | pypi.org/project/foreblocks |
| Issue Tracker | GitHub Issues |
๐ฉบ Troubleshooting
CUDA out of memory
Reduce batch_size in TrainingConfig, or enable gradient checkpointing:
config = TrainingConfig(batch_size=8, gradient_clip_val=1.0)
Alternatively, use use_amp=True (default) to reduce memory via mixed precision.
Loss is NaN during training
Common causes:
- Learning rate too high โ lower
learning_rate - Inputs not normalised โ add a
RevinHeadorDAINHeadatposition="input" - Gradient explosion โ set
gradient_clip_val=1.0
model.add_head(RevinHead(num_features=input_size), position="input")
config = TrainingConfig(learning_rate=1e-4, gradient_clip_val=1.0)
Conformal intervals are too wide
Try a different conformal method or adjust the quantile:
config = TrainingConfig(
conformal_enabled=True,
conformal_method="agaci", # adaptive method
conformal_quantile=0.80, # 80 % coverage
)
๐ก Best Practices
- Always normalise inputs โ use
RevinHeadorDAINHeadatposition="input"unless your data is already z-scored. - Start simple โ begin with
seq2seq+ LSTM before exploring Transformer orhead_onlystrategies. - Use AMP โ
use_amp=Trueis the default; disable only when debugging NaN losses. - Monitor with MLTracker โ
Trainerauto-creates a SQLite experiment log; passauto_track=True(default). - Validate conformal coverage โ after calibration, call
compute_coverage()and aim for โฅ your target quantile. - NAS warmup โ set
nas_warmup_epochsto at least 5โ10 % ofnum_epochsto stabilise base weights before architecture search.
๐ค Contributing
Contributions are welcome! Please:
- Fork the repository and create a feature branch.
- Run
npm test/pytestand ensure all tests pass. - Follow existing code style (
ruff/black). - Open a pull request with a clear description.
See CONTRIBUTING.md for detailed guidelines.
๐ License
This project is licensed under the MIT License โ see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file foreblocks-0.1.8.tar.gz.
File metadata
- Download URL: foreblocks-0.1.8.tar.gz
- Upload date:
- Size: 3.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9afce1b257fd3b9bd6fb54655a12e7c81f2f9816c55b10d326bd215da6b227ab
|
|
| MD5 |
996224964dff5c43790d20d5e3385e00
|
|
| BLAKE2b-256 |
22dbf5db4e725882d1da0529cb513acfee03c4e0c344dec64b864b0ce4506f7d
|
File details
Details for the file foreblocks-0.1.8-py3-none-any.whl.
File metadata
- Download URL: foreblocks-0.1.8-py3-none-any.whl
- Upload date:
- Size: 867.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba4cd3e15211cda3b37e29f21769f42d10856412f36052c31c984a5ceb84be38
|
|
| MD5 |
8bdc6a5f4c917f127717f506d0e7f6eb
|
|
| BLAKE2b-256 |
9c125ebbfcd671cec7c76dd63d835f2266e33c4e359c07488c4e00d2f76ff775
|