Foundational industrial AI model for real-time telemetry, IoT, and time-series
Project description
VULGARIS
Streaming causal state-space foundation model for industrial and edge intelligence.
VULGARIS is an open-source foundational model for real-time telemetry, sensor fusion, and time-series intelligence across industrial environments. It is written entirely in NumPy with a custom reverse-mode autograd engine — no PyTorch, no TensorFlow, no CUDA dependency. Trains on CPU. Deploys on edge hardware.
Why VULGARIS
| Requirement | Transformers | Mamba | Chronos | VULGARIS |
|---|---|---|---|---|
| O(1) streaming state | ✗ | ✓ | ✗ | ✓ |
| Multi-rate sensor fusion | ✗ | ✗ | ✗ | ✓ |
| Causal structure discovery | ✗ | ✗ | ✗ | ✓ |
| Certified safety output | ✗ | ✗ | ✗ | ✓ |
| Online continual learning | ✗ | ✗ | ✗ | ✓ |
| Edge deployable (no GPU) | ✗ | ✗ | ✗ | ✓ |
| Multi-horizon forecasting | ~ | ~ | ✓ | ✓ |
Architecture
| Module | Role |
|---|---|
| ASE — Adaptive Signal Embedding | Morlet wavelet filterbank; per-channel frequency extraction before cross-channel mixing |
| HTD — Hierarchical Timescale Decomposition | Four-level parallel SSM; captures dynamics from milliseconds to hours |
| SSSR — Selective State-Space Recurrence | ZOH-discretised SSM with HiPPO-LegS init, adaptive timestep, Hebbian online adaptation |
| RMC — Regime Mixture Core | Soft Mixture-of-Experts over operating regimes; sparse top-k routing with load-balancing |
| CRG — Causal Routing Graph | DAGMA-constrained DAG; Neural Granger mask; regime-conditioned adjacency; failure propagation |
| HMB — Hierarchical Memory Bank | VAE-compressed episodic slots; surprise-triggered writes; uncertainty-weighted retrieval |
| DAH — Domain-Adaptive Hypernetwork | LoRA-style adapter generation; zero-shot domain switching at inference |
| ICL — In-Context Learning | Attention-pooled context encoder; persistent episodic memory across sessions |
| ESE — Explainability Engine | CART rule extraction from latent activations; gradient attribution; counterfactuals |
| SHCAL | EWC + Hebbian continual learning; prevents catastrophic forgetting |
| CMLA | InfoNCE cross-modal latent alignment; multi-sensor fusion |
| Safety | Control Barrier Function head; Lipschitz-certified safe action projection |
Installation
pip install vulgaris
pip install "vulgaris[serve]" # + FastAPI REST server
pip install "vulgaris[train]" # + tqdm + rich progress bars
pip install "vulgaris[all]" # everything
Requirements: Python ≥ 3.10 · NumPy ≥ 1.26 · SciPy ≥ 1.11 · PyYAML ≥ 6.0
Quick Start
import numpy as np
from vulgaris import Vulgaris, ModelConfig, Tensor
model = Vulgaris(ModelConfig(input_dim=9, output_dim=1))
# Batch inference: (batch, channels, timesteps)
x = Tensor(np.random.randn(8, 9, 64).astype(np.float32))
prediction, aux = model(x)
print(prediction.data.shape) # (8, 1)
Streaming (O(1) Memory)
state = model.init_state(batch_size=1)
for sensor_reading in live_stream:
x_t = Tensor(sensor_reading.astype(np.float32)) # (1, 9)
output_t, state = model.step(x_t, state)
print(output_t.data)
Training
from vulgaris import (
Vulgaris, ModelConfig,
TrainingPipeline, VulgarisLoss,
SpectralAdamW, CosineSchedule,
)
config = ModelConfig(input_dim=9, output_dim=1)
model = Vulgaris(config)
optimizer = SpectralAdamW(model.parameters(), lr=3e-4)
scheduler = CosineSchedule(optimizer, warmup_steps=1000, max_steps=50_000)
pipeline = TrainingPipeline(model, config, VulgarisLoss(config), optimizer, scheduler)
metrics = pipeline.train_step(x_np, y_np)
# → {"loss": 0.043, "rmc_balance_loss": 0.001, "dag_penalty": 0.002, ...}
Multi-Horizon Forecasting
# Forecast at horizons 1, 5, and 20 steps ahead — all in one pass
config = ModelConfig(input_dim=9, output_dim=1, forecast_horizons=[1, 5, 20])
model = Vulgaris(config)
prediction, aux = model(x)
mh = aux["multi_horizon"] # (batch, 3, 1) — one forecast per horizon
print(mh.shape) # (8, 3, 1)
Causal Graph & Failure Propagation
# Which sensors caused this fault?
model.crg.update_structure(latent_states)
# Forward-propagate a fault from sensor 3
affected = model.crg.propagate_failure(
triggered_nodes=[3],
max_hops=4,
decay=0.85,
)
# → {5: 0.72, 7: 0.61, 12: 0.48} — node: failure probability
Regime-Aware Processing
# Which operating regime is active at each timestep?
regimes = model.rmc.regime_assignments(z) # (batch, T) — 0…K-1
# Visualise routing: which expert each timestep uses
import numpy as np
counts = np.bincount(regimes.flatten(), minlength=4)
print("Expert utilisation:", counts / counts.sum())
Persistent Episodic Memory
from vulgaris import EpisodicMemory, InContextLearning
# Episodes persist across inference calls
icl = InContextLearning(
d_model=256,
episodic_memory=EpisodicMemory(capacity=512, d_model=256),
)
# First call stores the context; subsequent calls retrieve similar past episodes
output = icl.encode_context(z_ref, retrieve_k=4)
Causal Memory Queries
# Discover which sensors causally precede sensor 7
causes = model.causal_memory.query_causes(effect=7, min_confidence=0.3)
# → [(3, 0.81), (5, 0.67), (9, 0.44)] — (cause_node, confidence)
# Top strongest causal relationships in the model's learned graph
edges = model.causal_memory.strongest_edges(top_k=10)
Domain Adaptation (Zero-Shot)
# Switch domain at inference — no retraining, no gradient step
output_factory, _ = model(x, domain_idx=0)
output_telecom, _ = model(x, domain_idx=3)
Anomaly Detection with RevIN
prediction, aux = model(x)
# RevIN stats preserved for anomaly detection
mean = aux["revin_mean"] # per-channel mean of this window
std = aux["revin_std"] # per-channel std
energy = aux["anomaly_energy"] # L2 norm of denorm residual — spikes on anomalies
Drift Detection
from vulgaris import DriftDetector
detector = DriftDetector(window_size=200)
detector.set_reference(reference_data)
result = detector.update(new_batch)
if result["drift_detected"]:
print(f"KS={result['ks_stat']:.3f} MMD={result['mmd_stat']:.3f}")
Save / Load
model.save("checkpoints/my_run") # writes weights.npz + config.yaml + metadata.json
model = Vulgaris.load("checkpoints/my_run")
No pickle. No binary blobs. Checkpoints are inspectable with np.load.
Configuration
from vulgaris import ModelConfig
from vulgaris.config import SSSRConfig, RMCConfig, CRGConfig
config = ModelConfig(
input_dim=32,
output_dim=1,
d_model=256,
forecast_horizons=[1, 5, 20],
sssr=SSSRConfig(state_dim=512, n_heads=16),
rmc=RMCConfig(n_experts=4, top_k=2),
crg=CRGConfig(n_nodes=32, lambda_dag=0.01),
)
config.to_yaml("config.yaml")
# Load from environment variables (containerised deployments)
# VULGARIS_INPUT_DIM=32 VULGARIS_D_MODEL=256
config = ModelConfig.from_env()
Docker
Run the inference server
docker compose up
Starts the VULGARIS inference server on port 8000 and a Prometheus sidecar on port 9090.
Configure at runtime
VULGARIS_INPUT_DIM=32 \
VULGARIS_D_MODEL=256 \
VULGARIS_API_KEYS=secret123 \
docker compose up
All VULGARIS_* variables can be set in a .env file:
VULGARIS_INPUT_DIM=32
VULGARIS_OUTPUT_DIM=1
VULGARIS_N_CLASSES=0
VULGARIS_D_MODEL=256
VULGARIS_CHECKPOINT=checkpoints/production
VULGARIS_API_KEYS=key1,key2
Load a checkpoint
VULGARIS_CHECKPOINT=checkpoints/my_run docker compose up
Checkpoints are mounted from ./checkpoints into the container — no rebuild needed.
Build only (no Prometheus)
docker compose up vulgaris
Resource limits
| Service | Memory | CPU |
|---|---|---|
| vulgaris | 2 GB | 2 cores |
| prometheus | 512 MB | — |
REST API
| Method | Route | Description |
|---|---|---|
POST |
/predict |
Batch prediction |
POST |
/stream/start |
Start stateful streaming session |
POST |
/stream/{id}/step |
Single-step streaming |
GET |
/stream/{id}/stats |
Session latency stats |
DELETE |
/stream/{id} |
Close session |
GET |
/health |
Model info + degradation level |
GET |
/metrics |
Prometheus exposition |
POST |
/explain |
CART rule extraction |
POST |
/counterfactual |
Gradient-based counterfactual |
Inference Server (without Docker)
export VULGARIS_INPUT_DIM=9
export VULGARIS_N_CLASSES=5
vulgaris-serve
Repository Structure
vulgaris/
├── vulgaris/ public API, config, utils
├── engine/ autograd engine — Tensor, Module, layers, parallel_scan, fft_conv
├── modules/ ASE · HTD · SSSR · RMC · CRG · HMB · DAH · ICL · ESE
│ Safety · SHCAL · CMLA · OntologyEmbedding · RuleEngine
├── model/ full Vulgaris model assembly + MultiHorizonHead
├── memory/ EpisodicMemory · CausalMemory
├── training/ loss · optimizer · pipeline · conformal · distillation
│ active_learning · distributed · self_supervised
├── inference/ StreamingInference · SpeculativeRollout · EventBuffer
├── serve/ FastAPI server · auth · metrics · degradation · versioning
├── monitoring/ DriftDetector
├── preprocessing/ IndustrialTokenizer · LogEncoder
├── federated/ DP-SGD federated learning
├── benchmarks/ baselines · synthetic datasets
├── scripts/ distributed training launcher
├── deploy/ prometheus.yml
└── tests/ 220 unit tests — gradients, numerical stability, modules
Self-Supervised Pretraining
from training.self_supervised import SelfSupervisedTrainer
trainer = SelfSupervisedTrainer(model, in_channels=9, d_model=256)
metrics = trainer.pretrain_step(x_np)
# masked reconstruction + temporal InfoNCE — no labels required
Federated Learning
from federated.protocol import FederatedCoordinator
coord = FederatedCoordinator(model, n_clients=10, dp_epsilon=1.0)
coord.aggregate([client_grad_1, client_grad_2, ...])
# Byzantine detection + trimmed mean + DP-SGD noise injection
Reproducibility
from vulgaris import set_seed
set_seed(42)
Citation
@software{vulgaris2026,
title = {VULGARIS: Streaming Causal State-Space Foundation Model for Industrial Intelligence},
author = {Khan, Jalaluddin},
year = {2026},
version = {0.7.0},
url = {https://github.com/jalaluddinkhan1/vulgaris-Main},
license = {Apache-2.0},
}
License
Apache License 2.0. See LICENSE for details.
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
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 vulgaris-0.8.0.tar.gz.
File metadata
- Download URL: vulgaris-0.8.0.tar.gz
- Upload date:
- Size: 214.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ad411c91dcfbaa7fdbc22a82e1e69f1475171203f3e684eb01bdb399ad6ebc2
|
|
| MD5 |
8d596c68ce13706cbef52598dfc5035e
|
|
| BLAKE2b-256 |
1a7a04baccc4fee045c8cbceca6fc8b59934b3f037f138fc92438a3be902fa53
|
File details
Details for the file vulgaris-0.8.0-py3-none-any.whl.
File metadata
- Download URL: vulgaris-0.8.0-py3-none-any.whl
- Upload date:
- Size: 231.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cd8207065a0246ee453d7118ace3997d72e03ec89b0b8372d521683e3597f29
|
|
| MD5 |
3ab499e9b32ede47350e6cda7aefc476
|
|
| BLAKE2b-256 |
55de056cad43a2fe58b936f6c934e455db21a718ad527b77c5916952e28d7d30
|