File size: 4,259 Bytes
a2bbd94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# Sensorflow Studio — Aggregate-First Evaluation Architecture (megaeval)

The `sensorflow/megaeval/` layer replaces the "evaluation-record browser" model
(annotation as the primary unit) with an **aggregate-first, risk-first,
cohort-first, drill-down-on-demand** design.

## Mental model → code

| Concept | Meaning | Module / storage |
| --- | --- | --- |
| Dataset | immutable source population | `population.py` → `runs/megaeval/populations/{pop}/part-*.npz` |
| Evaluation Run | model+config being evaluated (async job, first-class) | `runs.py` → `runs/megaeval/runs/{run}/run.json` |
| Population | all objects evaluated in a run | headline row of the metric cube |
| Cohort | slice by class/weather/lighting/road/scenario/sensor/distance/speed/occlusion | cube cells + `POST /api/evaluations/query` |
| Container | scene/frame/segment holding related objects | `containers.npz` aggregate table |
| Annotation | individual object — forensic view only | per-object `objects-part-*.npz`, loaded one partition at a time |

## Data flow

```
generate population (vectorized numpy, partitioned npz)
        │
create run (queued) ──► worker pool (4 threads) processes partitions:
        │                 model simulation → PARTIAL sufficient statistics
        │                 (n, tp, fp, fn, sum_iou, conf sums, histograms …)
        │                 grouped by the 9 cube dimensions, per partition
        ▼
reduce (concat + groupby-sum) ──► materialize METRIC CUBE (cube.npz)
        │                          + error index, container table, sketches,
        │                          container embeddings
        ▼
publish ──► queries served by QueryRouter: cache → cube → (rare) record scan
```

Aggregation **never** scans raw records at query time; queries like
"pedestrian recall at night in rain for model v42" are cube lookups.

## Single-node stand-ins for distributed infrastructure

This repo runs on one laptop; the seams are shaped so each piece maps to the
production-scale equivalent:

| Here (single node) | Production analogue |
| --- | --- |
| npz column partitions (`part-0000.npz…`, hash-partitioned by container) | Parquet files in an Iceberg/Delta table, partitioned by scene |
| `ThreadPoolExecutor` workers over partitions | Spark executors / Flink task slots |
| partial stats per partition + `reduce_partials` | map-side combine + shuffle reduce |
| `QueryRouter` (cache → cube → scan) with latency+source reporting | OLAP engine (Druid/Pinot/ClickHouse) over the lakehouse |
| `QueryCache` keyed by hash(dataset+model+filters+group_by+metrics) | result cache / materialized views |
| in-process SSE progress events | job-status topic (Kafka) + progress service |
| numpy cosine similarity over container embeddings | vector DB (hybrid retrieval) |

## Honesty rules encoded in the API

- Cube counts and derived ratios are **exact** (`meta.exact = true`).
- Percentiles/distributions come from fixed-bin quantile histograms;
  cardinalities from HyperLogLog — always labeled approximate.
- Precision/recall from human review are **sampling estimates with 95% CIs**
  (stratified risk-weighted design: Wilson per stratum, weighted normal-approx
  combination), reported with n reviewed / frame size / method.
- Every query response reports `source` (cache/cube/scan), `cache_hit`,
  and `latency_ms` so aggregate-first behavior is observable in the UI.
- Evaluation runs are reproducible: lineage (dataset, model+checkpoint, label
  version, evaluator code version, metric version, thresholds, sampling config,
  seed, hardware) is stored on the run and derives the deterministic seed.

## Performance SLOs (measured locally, 320k-object population, 67k cube cells)

| Query | SLO | Measured |
| --- | --- | --- |
| aggregate dashboard (group by class) | < 2 s | ~75 ms |
| filtered cohort query | < 3 s | ~350 ms first / sub-ms cached |
| cached query | < 100 ms | ~0.1 ms |
| object investigation (one container, forensic) | < 1 s | ~50–200 ms |

The legacy `sensorflow/evaluation/` layer (label-evaluation pipeline, triage,
HITL, training flywheel) remains unchanged; megaeval integrates with its
regression tracker and alerting rather than duplicating them.