Skip to content

WER integrity: complete, pinned, per-utterance, with intervals - #30

Merged
PhilflowIO merged 3 commits into
masterfrom
fix/wer-integrity
Sep 19, 2026
Merged

PhilflowIO merged 3 commits into
masterfrom
fix/wer-integrity

Conversation

@PhilflowIO

Copy link
Copy Markdown
Owner

Three commits, one work unit: a published WER must describe the whole subset it names, under a fixed counting method, with its uncertainty stated.

What changes for readers

  • Six Grok rows move up (worse WER): fhnw-all-dialects 38.81→39.66 / 43.50→43.92, spc-test 49.38→50.07 / 41.08→41.77, voxpopuli-de 11.01→11.27 / 12.68→12.99. The cause: the old scorer concatenated a subset into one sentence before aligning, so an error at one clip's end could cancel against an error at the next clip's start. Every utterance is now aligned on its own. On flozi's own subsets and FLEURS, nothing moves at the printed precision, so the flozi anchors stay comparable. BENCHMARKS.md documents this under How WER is counted.
  • Every WER row has a 95 % CI. It is a bootstrap over utterances, committed to expected.json, re-derived by make verify and bound to the table.
  • The Grok 2.0 vs 1.0 prose is corrected. Paired intervals rank only FLEURS (2.0 −2.17 pp [−5.02, −0.13]), spc-test (2.0 −8.30 [−12.30, −3.87]) and VoxPopuli (1.0 ahead, +1.72 [+0.49, +3.13]). On avemio, MLS and fhnw the intervals span zero. The earlier text called 2.0 better on both Swiss sets. On fhnw that does not hold.

Guards added

Verification

  • make verify: 35/35 rows reproduce, intervals included. It now takes about 1 min longer because it recomputes the intervals.
  • Full pytest: 374 passed. The one failure (module registry) is fixed in the first commit, and the affected modules were rerun: 137 passed.
  • Every published number was already complete: Grok 1000/1000, Parakeet 9799/9799 (recounted against the dataset shards).

Follow-ups (not in this PR)

  • Embed a run manifest and schema_version in Tier-2 summaries #27 run manifest + schema_version. It is also where a self-hosted endpoint's model identity belongs; model_revision is null for those today.
  • The DER table's CI column is not yet bound to an artifact field the way the WER one now is.
  • BLEU has no interval yet.

Closes #24
Closes #25
Closes #26

🤖 Generated with Claude Code

PhilflowIO and others added 3 commits September 19, 2026 10:19
DER and WER are the same shape of estimator, a corpus sum of errors over a
corpus sum of reference units, so one seeded resampler can serve both. It moves
out of raven_diar.analysis into raven_eval_core.bootstrap with the draw order
unchanged. Every committed DER interval and paired delta recomputes
byte-identical, checked against a snapshot of all of them taken before the move.

A paired comparison now fails when a file exists for only one model. Before,
such files were dropped silently, and the interval then described a smaller
corpus than either published number while looking just as confident.

Refs #25

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three Sortformer artifacts were measured the day before the adapter began
writing its latency preset into summary.json. Nothing stated which streaming
setting their numbers belong to. At the time, the adapter hardcoded v2 to the
exact values of today's "very-high-latency" preset (identical dict at f9dd436)
and gave the offline v1 no streaming config. That is backfilled here in the
same shape the runner writes today.

A guard now fails any artifact of a diarizer that exposes run_config but does
not record it, so a diagnostic run cannot be published as the shipped
configuration.

Refs #26

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A published WER must describe the complete subset it names, under one fixed
counting method, with its uncertainty stated. Four gaps kept it from doing so:

- Failed requests vanished. The runner dropped them before scoring, so a model
  that timed out on the hardest clips read *better*. Every attempted clip now
  gets a prediction line (a failure carries prediction null plus error), the
  summary counts n_attempted/n_ok/n_failed, a failed subset leaves no resume
  marker, and promote refuses the run. verify fails on a failure line or on a
  line count that differs from expected.json's n_samples. The N-model path goes
  through the same recorder. Before, it wrote no predictions at all.
- Errors cancelled across clip boundaries. flozi's scorer concatenates a subset
  into one sentence before aligning, so a word missing from the end of one clip
  cancels against a surplus word at the start of the next. Every utterance is
  now aligned on its own. On flozi's own subsets and FLEURS the numbers are
  identical (largest move +0.001 pp). On VoxPopuli and the two Swiss sets the
  old count read 0.26-0.85 pp low, and six published Grok rows rise by that.
- No interval. Every WER now carries a 95 % bootstrap interval over utterances
  (contract: wer.uncertainty). It is committed to expected.json, re-derived by
  verify and bound to the page. `make analyse COMPARE=` adds the paired gap.
  The page's Grok 2.0-vs-1.0 prose claimed more than its data holds: only
  FLEURS, spc-test (2.0 ahead) and VoxPopuli (1.0 ahead) exclude zero.
- No provenance. Summaries now record model_revision and a per-result
  dataset_revision (or archive sha256). The flozi dataset is pinned to
  9c34cbcc, the HEAD since 2026-01-06, whose shard row counts equal the
  published 414/3996/5389 exactly. Existing artifacts are backfilled from their
  pins, and a guard fails any WER artifact without them.

Closes #24
Closes #25
Closes #26

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@PhilflowIO
PhilflowIO merged commit f9f621e into master Sep 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant