EnerOS v0.32.0
Release Date: 2026-02-08 Codename: ML Git Tag: v0.32.0 Support Status: Stable Total Crates: 60 (6 new) Test Cases: 7900+ (700 new)
Overview
EnerOS v0.32.0 “ML” is the machine learning integration release of the intelligence phase, expanding machine learning capabilities from “calling external LLMs” to “kernel-native ML runtime.” This release enables EnerOS to directly run classic power domain ML tasks such as load forecasting, anomaly detection, and state estimation on the kernel side, without relying on external Python services or offline training pipelines.
The core design philosophy of the ML release is “power-native ML” — model training, registration, version management, and online inference are all built into the operating system, deeply coupled with kernel first-class citizens such as topology, power flow, constraints, and timeseries. This means models can subscribe to topology change events for automatic retraining, can be bound to electrical nodes to migrate with topology drift, and can have their output ranges mandatorily validated within the constraint engine.
This release introduces five core capabilities: Machine Learning Runtime, Load Forecasting Model, Anomaly Detection Engine, Model Registry, and Online Inference Service. All ML capabilities are implemented through five new crates: eneros-ml, eneros-ml-forecast, eneros-ml-anomaly, eneros-ml-registry, and eneros-ml-serving.
Key Metrics
| Metric | Value | Description |
|---|---|---|
| Online inference latency P99 | 8ms | LSTM model |
| Load forecast accuracy | 97.2% | Daily MAPE |
| Anomaly detection recall | 94.5% | With 2.1% false positive rate |
| Model load time | 120ms | 50MB model |
| New Crates | 6 | ML-related |
| New tests | 700+ | Includes 90 end-to-end |
New Features
1. Machine Learning Runtime
Adds the eneros-ml crate, providing a unified ML runtime that supports multiple model formats and inference backends. The runtime is deeply integrated with the kernel timeseries engine and can directly subscribe to PMU/RTU data streams for streaming inference.
Inference Backends
| Backend | Model Format | Applicable Scenario | Acceleration |
|---|---|---|---|
| candle | safetensors | Pure Rust, embedded | CPU |
| ONNX Runtime | onnx | General, cross-platform | CPU/GPU |
| TensorFlow Lite | tflite | Edge devices | Edge TPU |
| TensorRT | engine | GPU high-performance | NVIDIA GPU |
Unified Inference Interface
use eneros_ml::{MlRuntime, Model, InferRequest};
let runtime = MlRuntime::new()
.backend(Backend::Candle)
.device(Device::Cpu)
.build()?;
// Load model (from model registry)
let model = runtime.load_model("load-forecast-lstm", Version::Latest).await?;
// Build inference request
let input = timeseries.query()
.point("bus_5_load")
.range(now() - Duration::hours(24), now())
.resolution(Duration::minutes(15))
.fetch().await?;
let request = InferRequest::new()
.input("history", input.into_tensor())
.input("temperature", tensor!{24.5})
.input("is_holiday", tensor!{false});
// Online inference
let output = model.infer(request).await?;
let forecast: Vec<f64> = output.get("forecast")?.try_into()?;
println!("24-hour load forecast: {:?}", forecast);
Streaming Inference
// Subscribe to PMU data stream for real-time inference
let mut stream = runtime.subscribe_pmu_stream(bus_id, Duration::milliseconds(20));
while let Some(sample) = stream.next().await {
let anomaly_score = anomaly_model.infer(sample).await?;
if anomaly_score > threshold {
ctx.emit(AnomalyDetected { bus: bus_id, score: anomaly_score });
}
}
2. Load Forecasting Model
Adds the eneros-ml-forecast crate, with built-in load forecasting models covering short-term, ultra-short-term, and medium-to-long-term time scales.
Forecasting Model Matrix
| Model | Time Scale | Accuracy (MAPE) | Applicable Scenario |
|---|---|---|---|
| LSTM | Ultra-short-term (15min-4h) | 1.8% | Real-time dispatch |
| Transformer | Short-term (4h-24h) | 2.3% | Day-ahead planning |
| Prophet | Medium-term (1-7 days) | 3.5% | Weekly planning |
| XGBoost | Long-term (7-30 days) | 4.8% | Monthly planning |
| N-BEATS | Ultra-long-term (30-365 days) | 6.2% | Annual planning |
Forecasting API
use eneros_ml_forecast::{ForecastEngine, ForecastHorizon, ForecastConfig};
let engine = ForecastEngine::new(&ctx)
.model("load-forecast-lstm")
.config(ForecastConfig {
horizon: ForecastHorizon::ShortTerm(Duration::hours(24)),
resolution: Duration::minutes(15),
confidence_interval: 0.95,
features: vec![
Feature::HistoricalLoad { window: Duration::hours(168) },
Feature::Weather { forecast: true },
Feature::Calendar { holidays: true },
Feature::TopologyEvent { sensitive: true },
],
})
.build().await?;
// Execute forecast
let forecast = engine.forecast(BusId::from(5)).await?;
// Forecast result contains: point forecast, confidence interval, feature contribution
println!("Forecast points: {}", forecast.points.len());
println!("95% confidence interval: [{}, {}]",
forecast.lower_bound[0],
forecast.upper_bound[0]);
Topology-aware Retraining
When grid topology changes, models automatically trigger retraining:
// Model subscribes to topology change events
forecast_engine.bind_to_topology(&network)?;
network.on_event(TopologyEvent::BusAdded(bus_id), |_| {
// New bus added, auto-initialize forecast model
forecast_engine.init_model_for(bus_id);
});
network.on_event(TopologyEvent::SwitchReconfigured, |_| {
// Topology reconfigured, mark model for retraining
forecast_engine.schedule_retrain(Reason::TopologyChange);
});
Forecast Accuracy Benchmark
| Scenario | LSTM | Transformer | XGBoost |
|---|---|---|---|
| Weekday | 1.5% | 2.0% | 3.2% |
| Weekend | 2.1% | 2.5% | 4.1% |
| Holiday | 3.8% | 3.2% | 5.5% |
| Extreme weather | 4.5% | 3.8% | 6.8% |
3. Anomaly Detection Engine
Adds the eneros-ml-anomaly crate, providing multi-dimensional anomaly detection capabilities covering point anomalies, contextual anomalies, and collective anomalies.
Detection Algorithms
| Algorithm | Type | Applicable Scenario | Computational Cost |
|---|---|---|---|
| Isolation Forest | Point anomaly | General | Low |
| Autoencoder | Contextual anomaly | Timeseries | Medium |
| DBSCAN | Collective anomaly | Clustering | Medium |
| Statistical (Z-score) | Point anomaly | Fast | Very low |
| LSTM-AE | Contextual anomaly | Complex timeseries | High |
Anomaly Detection API
use eneros_ml_anomaly::{AnomalyDetector, DetectorConfig, Algorithm};
let detector = AnomalyDetector::new()
.algorithm(Algorithm::IsolationForest {
n_trees: 100,
contamination: 0.02,
})
.features(vec![
"voltage_pu", "current_a", "power_mw", "frequency_hz",
"temperature_c", "harmonic_thd",
])
.window(Duration::minutes(15))
.build().await?;
// Real-time detection
let detector_handle = detector.run_on_stream(pmu_stream, |anomaly| {
ctx.emit(AnomalyEvent {
bus: anomaly.bus_id,
score: anomaly.score,
features: anomaly.contributing_features,
timestamp: anomaly.timestamp,
});
}).await?;
Anomaly Grading
// Grade based on anomaly score and electrical impact
match anomaly.score {
s if s > 0.9 => Severity::Critical, // Immediate alert
s if s > 0.7 => Severity::High, // Alert within 5 minutes
s if s > 0.5 => Severity::Medium, // Work order routing
s if s > 0.3 => Severity::Low, // Record for observation
_ => Severity::Info,
}
4. Model Registry
Adds the eneros-ml-registry crate, providing full lifecycle management for models: version control, A/B testing, canary release, and rollback.
Model Lifecycle
| Stage | Status | Description |
|---|---|---|
| Training complete | staging | Pending evaluation |
| Evaluation passed | ready | Pending release |
| Canary release | canary | Small traffic validation |
| Full release | production | Production environment |
| Archived | archived | Historical version |
Registry API
use eneros_ml_registry::{ModelRegistry, ModelVersion, Stage};
let registry = ModelRegistry::new(&storage);
// Register new model version
let version = registry.register(ModelVersion::new()
.name("load-forecast-lstm")
.version("2.3.0")
.artifact("/models/lstm-2.3.0.safetensors")
.metrics(ModelMetrics {
mape: 1.8,
rmse: 12.5,
latency_p99: 8.0,
})
.stage(Stage::Staging))?;
// Promote after evaluation passes
registry.promote("load-forecast-lstm", "2.3.0", Stage::Production).await?;
// Canary release (10% traffic)
registry.canary("load-forecast-lstm", "2.3.0", 0.1).await?;
// Rollback to previous version
registry.rollback("load-forecast-lstm").await?;
Model Lineage
// View model lineage
let lineage = registry.lineage("load-forecast-lstm", "2.3.0")?;
// Contains: training dataset, hyperparameters, parent model, derived models
5. Online Inference Service
Adds the eneros-ml-serving crate, providing highly available online inference services with batch inference, caching, and circuit breaking.
Service Configuration
use eneros_ml_serving::{InferenceServer, ServerConfig};
let server = InferenceServer::new()
.config(ServerConfig {
max_concurrent: 256,
batch_size: 32,
batch_timeout: Duration::milliseconds(10),
cache_enabled: true,
cache_ttl: Duration::minutes(5),
circuit_breaker: CircuitBreaker {
failure_threshold: 10,
recovery_time: Duration::seconds(30),
},
})
.model("load-forecast-lstm", Version::Latest)
.model("anomaly-detector", Version::Latest)
.build().await?;
server.serve("0.0.0.0:8080").await?;
Batch Inference Optimization
| Mode | Latency P99 | Throughput | Applicable Scenario |
|---|---|---|---|
| Single inference | 8ms | 125 QPS | Real-time |
| Batch inference (32) | 25ms | 3200 QPS | High throughput |
| Cache hit | 0.5ms | 50000 QPS | Repeated queries |
Improvements
- Timeseries Engine:
eneros-timeseriesadds columnar storage compression, storage space reduced by 60% - Model Loading: Model files loaded via mmap, startup time reduced from 2s to 120ms
- GPU Support: candle backend adds CUDA support, inference speed improved 8x
- Feature Engineering: Built-in 30+ power domain feature extractors (harmonics, three-phase imbalance, flicker)
- Observability: ML inference chain integrated with OpenTelemetry, supporting full-link tracing
Bug Fixes
- Fixed
eneros-mlGPU memory leak during inference (#3205) - Fixed
eneros-ml-forecastholiday feature calculation error for lunar calendar (#3210) - Fixed
eneros-ml-anomalyIsolation Forest performance degradation on high-dimensional data (#3218) - Fixed
eneros-ml-registryversion number conflicts during concurrent registration (#3222) - Fixed
eneros-ml-servingnot clearing request queue after batch inference timeout (#3228)
Breaking Changes
MlRuntime::infer: Return type changed fromResult<Tensor>toResult<InferResponse>ForecastEngine::forecast: Parameter changed fromBusIdto&ForecastTargetenumAnomalyDetector::algorithm: Enum values renamed,IForestchanged toIsolationForest
Upgrade Guide
- Update the
enerosdependency inCargo.tomlto0.32.0 - Install ML runtime dependencies:
cargo install eneros-ml-cli - Configure ML backend and model storage path in
eneros.toml - Run
eneros ml migrateto migrate existing models to the registry
Acknowledgments
Thanks to the 25 contributors who submitted 380+ commits, and to the ML community for providing open-source models and algorithm implementations.