Skip to main content

High-performance, parity-preserving COCO-style evaluation

Project description

vernier

CI PyPI crates.io vernier-core crates.io vernier-mask crates.io vernier-cli License: MIT OR Apache-2.0 Open In Colab

Fast, parity-preserving evaluation for object detection, instance / panoptic / semantic segmentation, boundary IoU, OKS keypoints, LVIS federated, LRP / oLRP error decomposition, and detection-family calibration (ECE / MCE / reliability). Rust core, Python frontend, optional CLI.

60-second example

Post training, if your predictions are already serialized to JSON (CI gate, post-training inspection):

from pathlib import Path
from vernier.instance import Bbox, CocoDataset, Evaluator

gt_bytes = Path("instances_val2017.json").read_bytes()
dt_bytes = Path("detections.json").read_bytes()

dataset = CocoDataset.from_json(gt_bytes)
summary = Evaluator(iou=Bbox()).evaluate(dataset, dt_bytes)
for line in summary.pretty_lines():
    print(line)

In a training loop, vernier supports overlapping eval with the data loading and inference. The matching kernel runs on a worker thread, so submit(...) returns immediately and the main thread keeps moving. Passing a CocoDataset reuses the parsed-once GT and its per-kernel derivation cache across every epoch (ADR-0020). On a dedicated validation pass (no trainer competing for cores), pass num_threads=N to parallelise the matching kernel inside the worker (ADR-0047):

from pathlib import Path
from vernier.instance import Bbox, CocoDataset, Evaluator

gt = CocoDataset.from_json(Path("instances_val2017.json").read_bytes())
evaluator = Evaluator(iou=Bbox())
with evaluator.background(gt, num_threads=8) as bg:  # default: single core
    for images, targets in val_loader:
        # torchvision detection API shape: list[dict] of length batch_size,
        # each with "boxes" (N,4 xywh), "scores" (N,), "labels" (N,) as
        # torch.Tensor. vernier consumes any DLPack-producing array library
        # (torch, jax, cupy, numpy) zero-copy.
        predictions = model(images)
        bg.submit([
            {"image_id": int(t["image_id"]), **p}
            for t, p in zip(targets, predictions)
        ])
    summary = bg.finalize()
print("AP =", summary.stats[0])

Both end in the same 12-line pycocotools-shaped Summary; docs/tutorials/first-evaluation.md walks each end-to-end.

Benchmarks

Workload vernier median Speedup vs alternatives
Instance — bbox AP (val2017) 370 ms 5.8× faster-coco-eval · 16.0× pycocotools
Instance — segm AP (val2017) 987 ms 3.7× faster-coco-eval · 7.0× pycocotools
Instance — boundary AP (val2017) 3.2 s 5.5× faster-coco-eval · 19.3× boundary-iou-api
Instance — keypoints AP (val2017, OKS) 136 ms 12.3× faster-coco-eval · 16.7× pycocotools
Panoptic — PQ (val2017) 10.5 s 3.3× panopticapi
Semantic — mIoU (val2017) 2.8 s 7.4× mmsegmentation
Instance — LVIS bbox AP (v1 val, perfect-DT) 3.6 s 57.2× lvis-api · 10× lower peak RSS (1.48 GiB vs 15.01 GiB)

Panoptic cell exceeded the 5% relative-IQR gate (9.78% on this snapshot — chronically noisy because PNG decode dominates wall time, but ~halved vs the 21% in 0.0.4 after the sparse-remap cache landed in #260). The 3.3× speedup is the load-bearing signal; the precise ratio carries a wider confidence band than the others.

Median total-stage wall time on a KVM VPS (AMD EPYC-Milan, 4 cores × 2 threads = 8 logical CPUs, x86_64 — not a bare-metal Milan box), harness mode release (N=10 measurement reps + 2 warmup, randomised impl order, 5% relative-IQR gate per impl), build profile = cargo release defaults (opt-level=3, lto=thin, codegen-units=1, no target-cpu) — same as the PyPI wheel. Full per-cell breakdown (including IQRs), RSS, and methodology in docs/benchmarks.md; per-library comparison of when to pick which in docs/comparison.md.

Baselines pinned for these numberspycocotools==2.0.11, faster-coco-eval==1.7.2, panopticapi @ 7bb4655, boundary-iou-api @ 37d2558, mmsegmentation @ c685fe6 (vendored), lvis-api @ 031ac21 (PyPI lvis==0.5.3). All cells were measured at HEAD 3a509df6c525 (machine fingerprint 37652a58e939 — same fingerprint as the 0.0.4 snapshot, so the speedup deltas vs that release are not confounded by a host change). Each baseline is locked in its own uv-managed venv per ADR-0017.

Install

pip install vernier                  # Python wheel
cargo add vernier-core               # Rust library
cargo install vernier-cli            # `vernier` CLI binary

Wheels ship for linux x86_64 / aarch64 (glibc + musl), macOS x86_64 / arm64, and windows x64. The umbrella vernier crate name on crates.io is held as a 0.0.0 placeholder; vernier-core is the real Rust entry point — see docs/engineering/registry-reservations.md.

Status & validation

Pre-1.0; public API is unstable. See docs/adr/ for the design decisions shaping it.

pycocotools==2.0.11 is the de-facto reference for COCO evaluation — slow, unmaintained, and full of edge-case quirks. Faster reimplementations exist, but each silently fixes some quirks and not others, so you discover the divergences empirically. vernier takes a third path:

  • Auditable parity. Every divergence from pycocotools is filed in the quirks survey under ADR-0002 as either strict (bit-equal output, even when vernier's implementation is structurally different) or corrected (opt-in opinionated fix). Strict is the default; corrected fixes are itemized so you always know when your numbers diverge from a reference run. A drop-in shim (vernier.patch_pycocotools()) keeps existing pycocotools-based scripts working with one line.
  • Rust core, Python frontend. The matching kernel is pure Rust with runtime SIMD dispatch; the FFI layer is data conversion only. The CLI ships as a static binary, so CI pipelines call vernier without provisioning a Python interpreter.
  • One toolkit instead of five. bbox / segm / boundary / keypoints AP, panoptic PQ, semantic mIoU, LVIS federated, oLRP error decomposition, and detection-family calibration all live behind one Python API and one CLI — folded over a single matching pass. Per-paradigm migration guides under docs/migrate/ show how to replace pycocotools, faster-coco-eval, panopticapi, lvis-api, and mmsegmentation one at a time.
  • Scenario slicing + cross-run aggregation. A partition manifest (weather, time_of_day, …) feeds vernier eval --manifest for per-slice headline metrics and vernier aggregate for cross-run corruption tables (mPC / rPC) — one matching pass, N slices (ADR-0046).

Per-paradigm parity status:

Paradigm / metric Oracle Parity tier Open caveat
Instance bbox / segm / keypoints AP pycocotools==2.0.11 strict bit-equal none
Instance boundary IoU boundary-iou-api strict bit-equal none
Segm + boundary TIDE thresholds (t_b) none yet corrected-only ADR-0022 still proposed; defaults extrapolated, not measured
Panoptic PQ panopticapi (single-core path) strict bit-equal none
Panoptic boundary PQ bowenc0221/boundary-iou-api (single-core path, same SHA as the instance vendor) strict bit-equal ADR-0025 §Z1/Z2 amendment; Cityscapes panoptic (Z3) deferred
Semantic mIoU / FWIoU / pAcc / mAcc mmseg.IoUMetric vendored at v1.2.2 (ADR-0036, still proposed); cityscapesScripts + ADE20K cross-impl bench externally blocked strict bit-equal on the four per-class u64 marginals at val2017 scale ADR-0028; ADE20K-scale bench gated on license-cleared cache
LVIS federated AP lvis-api (vendored at 031ac21f, ORACLE_LVIS_COMMIT_SHA) strict bit-equal on the (T, R, K, A) precision tensor at full LVIS v1 val bench paradigm wired; segm cell waits on evaluate_segm_grid_with_dataset
LRP / oLRP error decomposition (instance bbox / segm / boundary / keypoints) pure-NumPy oracle (ADR-0043) strict against the oracle within 1e-9; kemaloksuz/LRP-Error tripwire vendored opt-in panoptic LRP is a typed NotImplementedError stub — panoptic predictions carry no per-segment scores (ADR follow-up)
Detection-family calibration — ECE / MCE / reliability (instance bbox / segm / boundary / keypoints) clean-room NumPy oracle (ADR-0018) with isolated P1–P10 quirks survey strict bit-equal against the oracle (16/16 parity tests) panoptic (Shape 2) and semantic (Shape 3) calibration deferred on data-model prerequisites; Clopper-Pearson CI documented Phase-2

Three-tier parity model: ADR-0002; per-library comparison: docs/comparison.md.

Three evaluation paradigms

They have different data models, different matching rules, and different parity oracles:

  • vernier.instance — detections with scores → bbox / segm / boundary / keypoints AP.
  • vernier.panoptic — RGB-encoded panoptic PNGs + segments_info JSON → PQ.
  • vernier.semantic — single-channel class-id label maps → mIoU / FWIoU / pAcc / mAcc.

See Three paradigms.

Documentation

Contributing

Local checks: just lint && just test && just audit. The full contributor workflow (ADR lifecycle, vendoring policy, code style) is in CONTRIBUTING.md. Repository layout and common just recipes are in CLAUDE.md.

License

Dual-licensed under Apache-2.0 or MIT at your option.

Third-party code

vernier vendors a small number of test-only reference implementations to support parity testing. None of this code is included in published wheels or linked into the Rust binary. See THIRD_PARTY_NOTICES.md for the full inventory and license attributions.

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

vernier-0.2.0.tar.gz (676.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

vernier-0.2.0-cp310-abi3-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

vernier-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

vernier-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl (2.2 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

vernier-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

vernier-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.0 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

vernier-0.2.0-cp310-abi3-macosx_11_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

vernier-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file vernier-0.2.0.tar.gz.

File metadata

  • Download URL: vernier-0.2.0.tar.gz
  • Upload date:
  • Size: 676.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vernier-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a8d0027b023153d0ca402d1161ce6034faca2ff1562cb4a00be0caa64fd27334
MD5 540d94bfc388a6d3894029ba139655e2
BLAKE2b-256 112aaaf072a749d694b33fdecde50d7fd5e82e5e535dc6729645cbccf4d4c1e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0.tar.gz:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: vernier-0.2.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vernier-0.2.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f86d7a6edea189f96ca5a408507ce8a0866fcd0a000dfe78285819abcb1139a0
MD5 41a4ebe939281e813d15d26ed5cf143d
BLAKE2b-256 3784fbed38ff730a175e84fefd246e7f0567ce8d7e9b60b5979358fcb9c83e89

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-win_amd64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for vernier-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c3f791d093fc0f44238e84165ff98da07f8f5db2336f8bdd6dd04ad4d6c05538
MD5 238b534237d821dca111f9d52bd7bf47
BLAKE2b-256 49506a90a11ebb69d882d7c0ffa704020d1c2a2990dfcbeab8a6d53dca55e86c

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for vernier-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 86154c93f7d34047d20014811cbe8c62f4f7087c7bac002181f49cbcda356f32
MD5 aa2575e09fd61dd1757affdb43be1780
BLAKE2b-256 be24e2f6b634071b7b46467117692740fa62c73467baaf45ac40951ceef08472

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for vernier-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fb2b238a522fa45b289a1c6b8d6f514dbe188f06b146b16575d46bbffa720a4a
MD5 b943dcfae8ae18dd840a1520d8816512
BLAKE2b-256 07a0e883ea99c5f54385a1227d6608f8942e8ca57f2d7d8098046ee135bcc800

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for vernier-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0f5d5d1bfeee86c136e387dd1a2ed61cf112c9cc4a6a15712ba44bc20cf9e61a
MD5 5b0dc27997bf887c4008a46ec5802579
BLAKE2b-256 9a5747425607795eaf5d5672c9b4943ea18ae4eff5d5ea9f46c357fb0e9feb7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for vernier-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 648c75b619313c83ebd2f85c9e3c0e2f65cd2b44f92b644846381a6b6be5b383
MD5 17206540ef432df51f56132d0dc95427
BLAKE2b-256 44f996854809c20cf64fad4d73d1c10b2467662199319c492766e81d4944f819

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vernier-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for vernier-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 474274548fbbf53d7f994c0241e8fe159a990304ad14a3f6fb0a5b19a9d1b756
MD5 fc5bb8168f0e70505975aa90841aeacd
BLAKE2b-256 589c5242fa9baddf62349cc2972dc5f261d4d59c5530e1da130f385de363d6d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for vernier-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: wheels.yml on NoeFontana/vernier

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page