Skip to main content

vernier

CI PyPI crates.io vernier 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) 354 ms 1.6× hotcoco · 4.7× faster-coco-eval · 16.0× pycocotools
Instance — segm AP (val2017) 968 ms 1.4× hotcoco · 3.5× faster-coco-eval · 6.7× pycocotools
Instance — boundary AP (val2017) 3.2 s 16.7× faster-coco-eval · 19.5× boundary-iou-api
Instance — keypoints AP (val2017, OKS) 136 ms 1.6× hotcoco · 5.7× faster-coco-eval · 16.9× pycocotools
Panoptic — PQ (val2017) 10.6 s 3.3× panopticapi
Semantic — mIoU (val2017) 2.9 s 14.0× mmsegmentation
Instance — LVIS bbox AP (v1 val, perfect-DT) 2.6 s 1.4× hotcoco · 73.1× lvis-api · 10× lower peak RSS (1.45 GiB vs 15.01 GiB)
Instance — bbox AP (Objects365 val, 1.06M dets) † 8.8 s 1.7× hotcoco · 41.9× pycocotools · faster-coco-eval did not finish (OOM at ~30 GiB)

Thread scaling (num_threads, each cell pinned to that many CPUs — nt=8 is every library's out-of-the-box configuration on this 8-vCPU host):

Workload nt=1 nt=2 nt=4 nt=8 vs hotcoco / faster-coco-eval at nt=8
bbox (val2017) 354 ms 267 ms 229 ms 226 ms 1.6× hotcoco · 6.5× faster-coco-eval
segm (val2017) 983 ms 569 ms 375 ms 319 ms 1.7× hotcoco · 11.0× faster-coco-eval
boundary (val2017) 3.20 s 1.70 s 937 ms 790 ms 21.5× faster-coco-eval
keypoints (val2017) 136 ms 118 ms 109 ms 104 ms 1.5× hotcoco · 7.3× faster-coco-eval
bbox (Objects365) 8.8 s — — 4.7 s 1.7× hotcoco

faster-coco-eval ≥1.8 and hotcoco are multi-threaded too, so every column compares equal CPU budgets. Its parallelism pays off on boundary IoU but is flat on segm and keypoints, which is why vernier's lead widens with cores there.

† The Objects365 row is harness mode dev (one measurement rep per impl, no IQR gate) — pycocotools alone needs ~6 minutes per rep at that size. Every other row is release mode.

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. Every impl gets one CPU: faster-coco-eval ≥1.8, hotcoco and mmsegmentation are multi-threaded by default, so each runner is pinned to the cell's CPU budget and each result records its CPU/wall ratio as evidence (ADR-0049). vernier scales with num_threads — the thread-scaling tables on the benchmarks page cover 1/2/4/8. Full per-cell breakdown (including IQRs), peak and eval-delta memory, and methodology in docs/benchmarks.md; per-library comparison of when to pick which in docs/comparison.md.

Baselines pinned for these numbers — pycocotools==2.0.11, hotcoco==1.0.1, faster-coco-eval==1.8.0, panopticapi @ 7bb4655, boundary-iou-api @ 37d2558, mmsegmentation @ c685fe6 (vendored), lvis-api @ 031ac21 (PyPI lvis==0.5.3). All cells were measured at HEAD e361050ef582 (machine fingerprint 59aab88b17f4). That is a different host from the 2026-05 snapshot's 37652a58e939, and the CPU budget above changed what a "single-thread" cell means, so absolute numbers are not comparable with earlier snapshots — ratios within this one are. Each baseline is locked in its own uv-managed venv per ADR-0017.

Install

pip install vernier                  # Python wheel
cargo add vernier                    # Rust library (all paradigms)
cargo install vernier-cli            # `vernier` CLI binary

Wheels ship for linux x86_64 / aarch64 (glibc + musl), macOS x86_64 / arm64, and windows x64.

On the Rust side, vernier is a facade (ADR-0048): it re-exports the paradigm crates under one dependency and one module map — vernier::{instance, mask, panoptic, semantic, partial} — mirroring the Python namespace. It holds no code of its own, so depending on a leaf crate directly (cargo add vernier-core for bbox / segm / boundary / keypoints AP alone) is equally supported; the three optional paradigms can also be trimmed in place with default-features = false. Note the asymmetry: cargo add vernier gets the library, cargo install vernier-cli gets the binary — the CLI stays out of the library's dependency tree so clap never lands in a consumer's build.

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.

Metadata

Release files for vernier 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vernier 0.3.0
File Size Uploaded
vernier-0.3.0.tar.gz 688.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for vernier 0.3.0
File
vernier-0.3.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
vernier-0.3.0-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
vernier-0.3.0-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details
vernier-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
vernier-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
vernier-0.3.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
vernier-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 15.9 MB

Release files / vernier-0.3.0.tar.gz

Download URL vernier-0.3.0.tar.gz
Size 688.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a45162065810d535bc3635939b06870fb89023133f01915fc176cdafd6d226f6
BLAKE2b-256 checksum
How to use checksums
e48bbb49fca47b05be74b377a9558e472517e6ef4adcbd0267f968f2e6abd42d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-win_amd64.whl

Download URL vernier-0.3.0-cp310-abi3-win_amd64.whl
Size 2.2 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
5eccc8f12d0cbcb918caac392015c4b9f5d9e0ca8b313d38c15e2b59abfad348
BLAKE2b-256 checksum
How to use checksums
434d91c3bd27dfb0c8494cb39b663212cfb54f542b9a7ed765477b5e1c844fec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL vernier-0.3.0-cp310-abi3-musllinux_1_2_x86_64.whl
Size 2.4 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
3dbcb8d34646bb545bb2f184c50fd908d19537951a0354442117cd88ceeee9d6
BLAKE2b-256 checksum
How to use checksums
13d1560dd48e5349c87c3f254149a63e4188ad05f2eac5303f9bcb5677af13a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL vernier-0.3.0-cp310-abi3-musllinux_1_2_aarch64.whl
Size 2.2 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
9be89a4a135f764c3c18fd0262c9265ac3b7f01e87351a55dc6705f16a66a01c
BLAKE2b-256 checksum
How to use checksums
ed854bd214560efb893708ef7491e870354cff4e06cc7878f80b665d480852ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL vernier-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.2 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
9563a97d6ca0a095f18e38eecf9a29164e95302af8119a956af80dba2708a828
BLAKE2b-256 checksum
How to use checksums
5400654f0532b69be2589882b79f411f1892e22daa0d2608610b508d79361c7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL vernier-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.0 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
fb219e2bd4b887828d736bf9d9b06e0f2b7b15ab3e4253c604da02b827753228
BLAKE2b-256 checksum
How to use checksums
0342e5df88d8682347f8553d22856eede1bf2d6450c47e72429e8cef0c800ceb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL vernier-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Size 2.0 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a8c59f30b386d76056c58f3b01eed8dcb21b4a1c4c543453b32c975f680f26ad
BLAKE2b-256 checksum
How to use checksums
f78b6b1722c12758b1d51d3fdbb950c0150609036d6fe13434a3333c82380655
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / vernier-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL vernier-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 2.1 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
299e80b60df21d3ec6635ef725a99db007b697b02f9085ff9b883702d463766c
BLAKE2b-256 checksum
How to use checksums
ddca7be729f0918671da51022db52874d4c1400282251a62ef059abeb976eba4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.4

8 release files

0.5.3

8 release files

0.5.2

8 release files

0.5.1

8 release files

0.5.0

8 release files

0.4.1

8 release files

0.4.0

8 release files

This release

0.3.0 This release

8 release files

0.2.0

8 release files

0.1.0

8 release files

0.0.4

8 release files

0.0.3

8 release files

0.0.2

8 release files

0.0.1

7 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page