PolyNorm diagnostic benchmark
Spokenform’s PolyNorm adapter evaluates the overlap between the external
Apple PolyNorm-Bench corpus and the seven base languages supported by
Spokenform. The overlap is de-DE, en-US, es-MX, fr-FR, and it-IT;
This benchmark remains limited to its existing seven-language overlap. Japanese, Korean, and Chinese runtime support is covered by focused spokenform regression tests, not by this PolyNorm parity set. the default run derives its case count from the selected cached files because upstream locale files may differ in length. PolyNorm BCP-47 tags are translated to regional Spokenform identifiers only inside the benchmark adapter; they are not a Spokenform API convention.
The source is pinned to dataset commit
f3c67e047bea6b7c40bc2466c0fdaad51d8ce67d in
apple/ml-speech-polynorm-bench. The dataset is CC BY-NC-ND 4.0. The first
download requires an explicit license acknowledgement:
python -m benchmarks.polynorm --accept-license
After downloading, offline and focused runs are available:
python -m benchmarks.polynorm --offline
python -m benchmarks.polynorm --offline --locale en-US --category Date
python -m benchmarks.polynorm --offline --case en-US:1
python -m benchmarks.polynorm --offline --show-failures all
python -m benchmarks.polynorm --offline --speech-wer-threshold 0.5
python -m benchmarks.polynorm --offline --report html
Use --speech-wer-threshold VALUE to persist only failure entries whose word
error rate is strictly greater than VALUE. The option filters
failures.jsonl and failures.md only; summary metrics and evaluated-case
counts still cover the complete run. With no threshold, all current failure
entries are stored.
The overlap files are not assumed to have equal lengths; the evaluator derives the case count from the cached JSONL files. Reports therefore distinguish raw metrics, canonicalized category metrics, ownership-aware metrics, and a local reviewed subset that excludes annotations in a separate quarantine file. The upstream category and ground-truth text are never rewritten.
Cached JSONL data and the upstream license live under
.cache/polynorm-bench/<commit>/. Reports live under
benchmark-results/polynorm/<run-id>/; only metrics and metadata are intended
for summary consumption, while text-bearing failure reports are local. The
benchmark records dataset/source/dependency environment fingerprints, literal
exactness, raw speech exactness, locale-aware speech-equivalent exactness,
presentation-only disagreements, semantic failures, word error rate, unchanged
cases, exceptions, residual source-symbol counts, locale/category/ownership
aggregates, locale × canonical-category metrics, and per-failure changed
stages/source rules. Each failure also records the primary rule, claim owner,
failure phase, winning source span, protection reason, numeric speech policy,
and render mode. gate_metrics keeps safety, owned, extended-candidate,
protected, and per-locale views separate so protected or unsupported categories
are not mistaken for regressions in owned behavior. Raw speech exactness remains the PolyNorm-comparable metric;
equivalent speech is a parallel diagnostic. It continues after mismatches and individual runtime
exceptions and does not add a score threshold to normal CI. Questionable
upstream rows remain visible with quarantine reasons and are excluded only
from reviewed metrics.
Each run now also writes a self-contained report.html by default. The local
dashboard includes KPI cards, a locale table, a canonical-category table, a
locale × category view, a diagnostics/gate section, a filterable failure
explorer, metadata, and an optional oracle section when --candidate-oracle
data is present. Use --report none to skip HTML generation while keeping the
existing JSONL, Markdown, and summary artifacts unchanged.
The local quarantine annotations are intentionally limited to eight upstream
rows whose expected text is malformed, questionable, or inconsistent with the
source (for example, an instruction instead of normalized speech or an
inconsistent coordinate). They are never rewritten. German compact currency is
an explicit policy: the major unit and minor numeric value are spoken without
und or Cent; locale punctuation is selected before separator heuristics;
URLs, e-mail addresses, versions, and caller-protected spans remain literal by
default.
Structured normalization ownership
Spokenform claims accepted structured expressions as generated output. Those
output spans carry ownership and provenance through later stages, so
abbr2words and the plain-number pass cannot reinterpret words or digits that
were generated by a structured recognizer. The public PreparedText result
exposes these ranges as reserved_spans, while source/output offset mapping
still points each generated phrase to its original source token.
Current structured coverage includes lexical hashtags and mentions with
context-aware markers/separators, locale-aware coordinates, date/time forms,
percentages and compound units, canonical currency and exchange-rate syntax,
addresses, locale phone grouping, ISBNs, typed identifiers/VINs, chemical
formula symbols, legal references, sports scores, fractions, and locale
ordinal symbols. Structured output remains reserved from abbreviation and
plain-number stages. URLs, e-mail addresses, versions, and contextual Roman
numerals can be promoted with normalize_literals=True; caller-protected spans
remain unchanged. Math, music, and biology use conservative context/shape
grammars rather than corpus-specific branches.
Benchmark profiles
The default report uses the public conservative contract with
normalize_literals=False; URL/email and version rows remain protected and
are reported separately from owned semantic failures. Use
--profile extended (or --normalize-literals) to measure optional literal
verbalization. Reports record the selected profile, ownership state, failure
phase, primary rule, and render mode.
The default profile is the safety baseline; extended is an opt-in speech
experiment. Neither profile turns arbitrary long integers, unknown acronyms,
formula-looking words, or unlabeled product codes into spoken output without
the corresponding context and shape checks.
See the benchmark ownership table for comparison compatibility, quarantine handling, and the residual non-goals.