Skip to main content

vernier

PyPI Python Crates.io License

Fast, auditable evaluation for 2D vision models. Detection, instance and panoptic segmentation, semantic segmentation, keypoints, and LVIS, all in one package with a Rust core, a Python API, and a standalone CLI.

  • Bit-exact with pycocotools==2.0.11, panopticapi, lvis-api and boundary-iou-api in strict mode. Every upstream quirk has a documented disposition (quirks survey).
  • Drop-in for pycocotools.cocoeval.COCOeval: change one import, or none. Same constructor, same params mutations, same eval / evalImgs / ious / stats read back off the instance (what carries over).
  • 3.7–19× faster than faster-coco-eval and pycocotools at equal CPU budget (benchmarks).
  • Built for real pipelines: training-loop evaluation, multi-rank gathering, per-image tables, error decomposition, calibration, scenario slicing.

Install

pip install vernier               # Python ≥ 3.10, abi3 wheels
cargo binstall vernier-cli        # standalone `vernier` binary, no Python needed
cargo add vernier                 # Rust library

Quickstart: the COCO API you already know

vernier.COCOeval has the same constructor, the same evaluate() / accumulate() / summarize() sequence, and the same .stats as pycocotools. It defaults to parity_mode="strict", so the output is bit-identical (see Status & validation for what that is measured against).

from pycocotools.coco import COCO
from vernier import COCOeval  # was: from pycocotools.cocoeval import COCOeval

coco_gt = COCO("instances_val2017.json")
coco_dt = coco_gt.loadRes("detections.json")

E = COCOeval(coco_gt, coco_dt, iouType="bbox")  # "segm" | "keypoints" | "boundary"
E.evaluate()
E.accumulate()
E.summarize()

Code you can't edit (mmdetection, detectron2, ultralytics, …): patch the symbol before anything imports pycocotools.cocoeval.

import vernier

unpatch = vernier.patch_pycocotools()  # pycocotools.cocoeval.COCOeval -> vernier
run_existing_eval()
unpatch()

The patch is explicit, reversible, and never happens on import. A context manager (vernier.adapters.patched_pycocotools) and a one-fixture pytest recipe are in the pycocotools migration guide.

TorchMetrics' MeanAveragePrecision runs under the patch unchanged, including class_metrics=True and extended_summary=True (tests/python/test_compat_torchmetrics.py asserts the patched and unpatched results are equal). Two params fields are the exception and raise rather than diverge quietly: imgIds subsetting, and areaRng (custom area ranges are a native-Evaluator feature, ADR-0040). The migration guide has the field-by-field table.

The shim exists for migration. New code should use the native Evaluator: immutable configuration, typed results, no pycocotools dependency, and access to everything below.

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

gt = CocoDataset.from_json(Path("instances_val2017.json").read_bytes())
dt = Path("detections.json").read_bytes()

evaluator = Evaluator(iou=Bbox(), parity_mode="strict")
summary = evaluator.evaluate(gt, dt, num_threads=8)

print("\n".join(summary.pretty_lines()))  # the familiar 12-line table
ap = summary.stats[0]

The native Evaluator defaults to parity_mode="corrected", which applies the itemized fixes to upstream bugs. Pass "strict" when your numbers must match published pycocotools results.

Inside a training loop, evaluate on a background worker and feed it tensors directly (torch, JAX, CuPy, NumPy via DLPack, zero-copy):

with evaluator.background(gt) as bg:
    for images, targets in val_loader:
        preds = model(images)
        bg.submit([{"image_id": int(t["image_id"]), **p} for t, p in zip(targets, preds)])
    summary = bg.finalize()

Per-image and per-class diagnostics as Polars DataFrames (pip install "vernier[tables]"):

result = evaluator.evaluate(gt, dt, tables="all")
result.per_class

Paradigms

Pick the submodule that matches your model's output. They have different data models and matching rules, so they are separate evaluators rather than one class with a mode switch (why).

Submodule Input Metrics
vernier.instance Scored detections: boxes, masks, keypoints AP / AR (bbox, segm, boundary, OKS), LVIS federated AP
vernier.panoptic Panoptic PNGs + segments_info PQ / SQ / RQ, boundary PQ
vernier.semantic Class-id label maps mIoU, FWIoU, pixel accuracy, mean accuracy

Beyond the COCO API

Need Feature Guide
Evaluate without blocking training Evaluator.background(...) how-to
Evaluate across DDP ranks evaluate_to_partial / from_partials how-to
Find which images/classes regressed tables="all" how-to
Explain an AP gap TIDE error decomposition, oLRP tutorial
Check score calibration ECE / MCE / reliability (calibration=True) how-to
Metrics per weather, time of day, … Manifest slicing, vernier aggregate (mPC / rPC) how-to
Non-standard IoU / recall / area grids iou_thresholds=, recall_thresholds=, area_ranges= how-to

CLI

A static binary for CI gates and robotics replay pipelines. Output is byte-deterministic (sorted keys, no timestamps), so artifacts diff cleanly.

vernier eval --gt gt.json --dt dt.json --iou-type bbox                  # pycocotools-identical stdout
vernier eval --gt gt.json --dt dt.json --iou-type segm --emit json=result.json --threads 8

Exit codes: 0 success, 1 evaluation error, 2 invalid arguments. Full reference: crates/vernier-cli.

Status & validation

Every row is checked by a parity harness that runs the reference implementation and vernier on the same inputs. "Bit-exact" means parity_mode="strict", against the reference as published on PyPI — vernier's own output is identical on x86-64 and ARM. (A pycocotools you recompile from source can round bbox IoU 1-2 ULP differently on ARM; see ADR-0056 and the migration guide.)

Metric Reference Parity Notes
bbox / segm / keypoints AP pycocotools==2.0.11 bit-exact
Boundary AP boundary-iou-api bit-exact
LVIS federated AP lvis-api 0.5.3 bit-exact full v1 val, bbox
Panoptic PQ, boundary PQ panopticapi (single-core path) bit-exact Cityscapes panoptic deferred
Semantic mIoU / FWIoU / pAcc / mAcc mmseg.IoUMetric v1.2.2 (vendored) bit-exact on class marginals ADR-0036 proposed; ADE20K-scale check pending
oLRP clean-room NumPy oracle ≤ 1e-9 panoptic not supported
Calibration (ECE / MCE) clean-room NumPy oracle bit-exact detection family only
TIDE thresholds (segm, boundary) none corrected only ADR-0022 proposed

Parity model: ADR-0002. Library-by-library comparison: docs/comparison.md.

Performance

Median wall time at a one-CPU budget (CPU/wall is 1.00 in every cell). COCO val2017 throughout, except the LVIS row, which is LVIS v1 val. Speedup is the other library's time divided by vernier's.

Workload vernier vs pycocotools vs faster-coco-eval vs hotcoco
bbox AP 305 ms 18.7× 5.6× 1.9×
segm AP 931 ms 7.2× 3.7× 1.5×
keypoints AP 137 ms 16.8× 5.7× 1.6×
boundary AP 3.15 s 19.8× ¹ 16.9× —
Panoptic PQ 10.5 s 3.3× ² — —
Semantic mIoU 2.87 s 14.1× ³ — —
LVIS v1 bbox AP 2.50 s 81.0× ⁴ — 1.6×

¹ boundary-iou-api · ² panopticapi · ³ mmsegmentation · ⁴ lvis-api, with 13.6× lower peak memory (1.11 vs 15.08 GiB)

Peak RSS on the COCO cells is 200 MiB, against 274 MiB (hotcoco), 569 MiB (pycocotools) and 691 MiB (faster-coco-eval).

Thread scaling (num_threads, 8-vCPU host)

faster-coco-eval ≥ 1.8 and hotcoco are multi-threaded by default, so each column compares equal CPU budgets.

Workload 1 2 4 8 vs hotcoco @ 8 vs faster-coco-eval @ 8
bbox 306 ms 221 ms 146 ms 131 ms 2.8× 11.4×
segm 926 ms 536 ms 304 ms 239 ms 2.3× 14.6×
boundary 3.18 s 1.68 s 866 ms 711 ms — 23.8×
keypoints 139 ms 90 ms 60 ms 52 ms 3.1× 14.7×
bbox, Objects365 (1.06M dets) † 6.6 s — — 3.2 s 2.6× OOM at ~30 GiB

Strict-mode results are bit-identical across thread counts. † Single-rep dev run; pycocotools takes ~6 min per rep at this size. The faster-coco-eval OOM is carried forward from the previous round rather than re-measured — reproducing a 30 GiB OOM destabilises the host mid-round.

AMD EPYC-Milan KVM VPS (4 cores x 2 threads = 8 logical CPUs), harness mode release (N=10 measurement reps + 2 warmup, randomised impl order, 5% relative-IQR gate), against hotcoco==1.0.1, faster-coco-eval==1.8.0 and pycocotools==2.0.11. Full methodology, every baseline pin and the complete results: docs/benchmarks.md.

Documentation

Contributing

just lint && just test && just audit

See CONTRIBUTING.md for the ADR workflow, vendoring policy, and code style.

License

Licensed under either of Apache-2.0 or MIT at your option. Test-only reference implementations used for parity checks are listed in THIRD_PARTY_NOTICES.md. They are not shipped in wheels or binaries.

Metadata

Release files for vernier 0.4.1

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.4.1
File Size Uploaded
vernier-0.4.1.tar.gz 787.4 kB Details

Built distributions (wheels)

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

Total release size: 16.8 MB

Release files / vernier-0.4.1.tar.gz

Download URL vernier-0.4.1.tar.gz
Size 787.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5851d39c675432a8ec00865ce4886325ed1e57dba2458f43fbb2be85619660d9
BLAKE2b-256 checksum
How to use checksums
77183229d5389e5b8bbeb224693de35e17cce988860965793a9a4f416b33020f
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-win_amd64.whl
Size 2.4 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
9ed2c176e3aa0b50bafe233cb4674e7094d129c9049a414a1cf1224c6bae59e0
BLAKE2b-256 checksum
How to use checksums
06f8c43db15de9d97100b9de053d8a7e1148c21962b5ba68dfbb8f3b5884d5a7
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-musllinux_1_2_x86_64.whl
Size 2.5 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
4c8db7ab9d34d61e1d6a4845d2a01d8a99ef98405b6eab8a8d9ebb5560bae2d9
BLAKE2b-256 checksum
How to use checksums
e1b36aa1618f248c5cd1f04a56353d12a8c9776688ad04b6f9496e710b2a6090
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-musllinux_1_2_aarch64.whl
Size 2.3 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
512d9f69fdb18f95a81a301e5df107d89abe2719d7da5c9a4c8203a5589f8b9e
BLAKE2b-256 checksum
How to use checksums
e32016bfabcd4da2d7fe118b5dfe6734585a19a8e59b11b6fe95fac3d0b99e1a
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.3 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
26e7588d44a90253a5655683297849269e82d6060d7bbce16c95abd411aedb3d
BLAKE2b-256 checksum
How to use checksums
4daf6770a0be2e2a9d66bcd1cbf531bc1abb3efd2c21ba3fefc1976afbb16869
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.2 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
749b5877512bfd6a3a7c9e0fbf43ffd33f734a6ecc81b593899bbf447920d3c1
BLAKE2b-256 checksum
How to use checksums
6cfacc35e45f9c9b2c043f6624d936e773da008b9b371b738890c55ee4f18f73
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-macosx_11_0_arm64.whl
Size 2.1 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
fde2d6d781e927a73552a011113c6516abeed9ebe22c5465c98ebc31d7064ce4
BLAKE2b-256 checksum
How to use checksums
d0821319d9aa1ca4afc9452e8b2c468becef09f8d3f178b60f69e83ccc157575
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 18, 2026.

Transparency log

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

Download URL vernier-0.4.1-cp310-abi3-macosx_10_12_x86_64.whl
Size 2.2 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
3c5653065f79cdb144d1ee4f82306695bb5b216282cd10ecc7676611fa09c3f2
BLAKE2b-256 checksum
How to use checksums
f1c68e19389bfd26ef2331ec8c78f0a30d357bd2b1536449538eda0a01e957ee
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 18, 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

This release

0.4.1 This release

8 release files

0.4.0

8 release files

0.3.0

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