AI-RAN KPI Forecasting Dashboard

I built this because RAN operations cannot rely only on after-the-fact dashboards. The page shows a Non-RT RIC / rApp pattern: schema-typed KPM telemetry in, time-ordered forecasts out, advisory A1 policy candidates generated, and evidence artifacts kept visible for review. Pattern, not deployment.

Executive KPI cards

Forecast horizon 24 steps Forward PRB utilization forecast from committed sample telemetry
Target KPI prb_dl_util Downlink PRB utilization is the current forecast target
Best measured model ridge_linear (0.84 RMSE) Same KPI and same time-ordered split across all models
Peak forecast 56.31 Project-defined risk tier: Stable
Scenario count 3 measured Congestion, backhaul saturation, and outage evidence
A1 policy status no_action Candidate only; no network control is executed
Thor inference 0.0206 ms p95 Slowest of the three ONNX forecasters at 1000 events/s on Jetson AGX Thor, CPU provider, one thread
Benchmark status 3 cells measured Telecom Italia MI, hourly internet_traffic, 2013-11-01 to 2014-01-01; per-cell hold-out with naive baselines
Validation status local tests pass Lint, tests, report generation, and artifact checks
Operational interpretation

Forecast evidence before action

The current sample forecast peaks at 56.31 against an advisory policy threshold of 80.0, so the generated A1 candidate recommends no_action. The useful signal is not that Ridge regression is novel. The useful signal is that the forecast is wrapped in typed input, an auditable policy candidate, and scenario evidence an engineer can inspect.

Policy interpretation

Forecast prb_dl_util on CELL_001 peaks at 56.31 (model=ridge_linear, threshold=80.0). No policy action required.

The dashboard does not pretend to control the network. It shows forecast evidence, scenario impact, and an advisory A1 policy candidate before any human or downstream system takes action.

Congestion risk tiers

Project-defined operational thresholds over forecast PRB DL utilization. These thresholds turn existing forecast values into readable risk tiers; they are not operator SLA values.

TierForecast PRB DL utilOperational interpretation
Stable< 60Routine monitoring; no action implied by this project threshold.
Elevated60-74.99Watch capacity pressure and compare forecast drift across the next horizon.
Congested75-84.99Prepare traffic-steering or capacity investigation as an advisory candidate.
Critical>= 85Escalate planning review; this is still decision support, not closed-loop control.
Model reliability

The model is the least interesting part of this repo. Ridge, GradientBoosting, and MLP are compared on the same sample KPI and forward temporal split so the weak result stays visible: Ridge is best on this tiny sample, while the MLP underfits badly.

ModelRMSEMAEMAPEReadout
ridge_linear0.840.700.82%best current baseline
gradient_boosting2.882.633.16%weaker on this small sample
mlp22.5919.6426.96%weaker on this small sample
Scenario comparison

Scenario packs are deterministic stress overlays on synthetic telemetry. Higher error under a scenario is a signal to monitor transition windows and policy timing, not proof of live-network behavior.

ScenarioRMSEMAEStatus
congestion4.113.30measured
backhaul4.703.91highest error scenario
outage4.593.80measured
Measured: inference cost on Jetson AGX Thor

The three ONNX exports run through the edge inference harness shared with jetson-edge-ai-security on jetsonthor (tegra264, 120W 1 power mode), onnxruntime CPU execution provider, synthetic inputs of the model shape, batch 1, paced load, 300.0 s per tier. Primary run thor_benchmark.json uses one intra-op and one inter-op thread with spinning disabled; the comparison run default_threads.json uses runtime defaults. Inference cost only, not forecast accuracy. At 1000 events/s:

Modelp95 ms, one threadp95 ms, default poolMisses, one threadMisses, defaultVIN p50 mW, one threadVIN p50 mW, default
ridge_linear0.01150.01150424,17024,184
gradient_boosting0.01530.0222018,34224,11254,114
mlp0.02060.0083220124,11024,574

The gradient-boosting graph engages the default thread pool: about 30 W of extra board power and 18,342 pacing misses, both removed by the single-thread setting. The linear model is unaffected; the MLP is faster under the default pool but misses more deadlines.

Thor p95 latency and board power per model, default thread pool against one thread
Read from thread_comparison.json.
Measured: Telecom Italia MI benchmark

Public Milan grid dataset (doi:10.7910/DVN/EGZHFV, ODbL 1.0 (Open Database License), per the Dataverse terms of use), 62 daily files from 2013-11-01 to 2014-01-01, 319,896,289 raw rows. Hourly internet_traffic per square, three squares chosen by activity level (largest total, nearest the median, nearest the 10th percentile), time-ordered split with the last 20% held out, features are calendar terms and lags of the target only. RMSE in the dataset's activity units; every figure links to its file. Generated 2026-09-09T21:26:47Z. Full record: summary.json, dataset.json.

CellHoursTest rowsridge_linear RMSEgradient_boosting RMSEmlp RMSENaive last value RMSESeasonal naive 24 h RMSE
high (5161)14882931697.52793.57653.12407.74163.1
mid (3168)148829324.326.9245.815.943.8
low (9408)14882936.05.179.84.47.8

Second window, series cut at 2013-12-20 so the hold-out falls in ordinary weeks (summary.json). In this window every model beats both baselines on every square; over the holiday window above the naive baseline wins on two of three. Both are reported.

Squareridge_linear RMSEgradient_boosting RMSEmlp RMSENaive last value RMSESeasonal naive 24 h RMSE
51611279.81096.52085.72634.23336.0
316818.715.918.627.943.5
94083.43.03.35.04.7
Hold-out RMSE per square, three models and the naive baseline, holiday window beside ordinary weeks
Both windows, read from the two summary.json files. Each square has its own axis.
Gradient boosting hold-out and forecast for square 5161, ordinary-weeks window
Square 5161: gradient boosting hold-out actuals against predictions and the 24 h forward forecast, ordinary-weeks window (metrics.json).
Gradient boosting hold-out and forecast for square 3168, ordinary-weeks window
Square 3168: gradient boosting hold-out actuals against predictions and the 24 h forward forecast, ordinary-weeks window (metrics.json).
Gradient boosting hold-out and forecast for square 9408, ordinary-weeks window
Square 9408: gradient boosting hold-out actuals against predictions and the 24 h forward forecast, ordinary-weeks window (metrics.json).
Tech brief (1 page)

A short engineering brief: what I built, what the evidence says, and where the live-RIC boundary starts.

rApp pattern artifacts

The contracts around the model: rApp manifest, KPM input schema, advisory A1 output schema, and the R1-style dataflow demo.

Three-model comparison

Ridge / GradientBoosting / MLP head-to-head on the same KPI and time split, on the 48-row sample. Public-data accuracy is in the Telecom Italia section above.

Forecast Evidence Pack

Baseline KPI forecast, metrics, impact plot, and feature importance for the sample RAN telemetry.

Congestion Scenario

Pre-shock versus shock-window evidence showing PRB, throughput, and latency stress on one cell.

Backhaul Scenario

Backhaul saturation example with throughput collapse and latency growth under constrained transport.

Cell Outage Scenario

Cell-level outage and recovery example with throughput collapse, low PRB, and packet loss spikes.

Data Contracts

Telemetry assumptions and synthetic data contract for reproducible runs.

Release Bundle

Static landing page for GitHub Pages, release uploads, or other publishable report hosting.

Engineering boundaries

The boundary is simple: this is a reproducible rApp pattern, not a deployed RIC workload. It uses synthetic and sample telemetry, does not connect to a live RAN, does not deploy an xApp or rApp, does not execute wire-protocol A1 transport, and does not perform autonomous control.