speaker_helper.eval package
Submodules
- speaker_helper.eval.dataset module
- speaker_helper.eval.deepeval_metrics module
- speaker_helper.eval.metrics module
- speaker_helper.eval.multilang module
- speaker_helper.eval.priors module
- speaker_helper.eval.runner module
- speaker_helper.eval.thresholds module
Module contents
speaker-helper evaluation layer — measure speed and quality, gate on thresholds.
Module summary
The project’s coding contract forbids “vibe checks”: anything AI must be evaluated against a committed dataset with versioned metrics and thresholds. This package provides speaker-helper’s measurement machinery and makes it a first-class, CI-gating layer.
It is engine-agnostic: everything runs against the
Speaker façade, so the exact same evaluation
grades the deterministic mock backend in CI or the real Voicebox kokoro
engine locally — only settings.backend differs.
Public surface
- class speaker_helper.eval.CaseResult(id, language, duration_s, rtf, anomalies=<factory>, wer=None, chrf=None, error=None)[source]
Bases:
objectPer-utterance evaluation outcome.
- Parameters:
language (str) – Language synthesised.
duration_s (float) – Audio duration produced.
rtf (float) – Real-time factor for this case (below 1.0 is faster than real time).
anomalies (list of str) – Anomaly labels (empty means clean); see
detect_anomalies().wer (float or None) – Round-trip word error rate, or
Nonewhen no transcriber ran.chrf (float or None) – Round-trip chrF, or
Nonewhen no transcriber ran.error (str or None) – Synthesis error message when the case failed outright (counts as an anomaly), else
None.
- class speaker_helper.eval.EvalCase(id, text, language='fr', reference='')[source]
Bases:
objectOne reference utterance to synthesise and score.
- Parameters:
- class speaker_helper.eval.EvalReport(backend, n_cases, mean_rtf, p95_rtf, anomaly_rate, mean_wer, mean_chrf, quality, quality_source, passed, failures, cases, thresholds)[source]
Bases:
objectAggregated evaluation results plus the pass/fail verdict.
- Parameters:
backend (str) – The backend that was evaluated (echoed for provenance).
n_cases (int) – Number of cases run.
mean_rtf (float) – RTF summary statistics.
p95_rtf (float) – RTF summary statistics.
anomaly_rate (float) – Fraction of cases that errored or were anomalous.
mean_wer (float or None) – Round-trip fidelity means, or
Nonewhen no transcriber ran.mean_chrf (float or None) – Round-trip fidelity means, or
Nonewhen no transcriber ran.quality (float) – A quality score in
[0, 1]that is always present: the measured mean chrF when a transcriber ran, otherwise the engine’s inherited prior (seespeaker_helper.eval.priors). Paired withmean_rtfit places the run on the quality↔RTF plane forpareto_front().quality_source (str) –
"measured_chrf"or"prior"— howqualitywas obtained.passed (bool) – Whether every gated threshold was met.
failures (list of str) – Human-readable reasons the run failed (empty when
passed).cases (list of CaseResult) – Per-utterance detail.
thresholds (dict) – The thresholds applied (echoed for provenance).
- cases: list[CaseResult]
- class speaker_helper.eval.Thresholds(max_mean_rtf=1.0, max_p95_rtf=1.0, max_anomaly_rate=0.0, max_mean_wer=None, min_mean_chrf=None)[source]
Bases:
objectThe bar an evaluation run must clear to pass.
- Parameters:
max_mean_rtf (float) – Maximum allowed mean real-time factor across cases.
max_p95_rtf (float) – Maximum allowed 95th-percentile RTF (guards tail latency).
1.0means even the slow cases stay faster than real time.max_anomaly_rate (float) – Maximum allowed fraction of cases with any audio anomaly (
0.0= none tolerated).max_mean_wer (float or None) – Maximum allowed mean word error rate of the re-transcription round-trip.
Nonedisables the gate (used when no transcriber is provided).min_mean_chrf (float or None) – Minimum allowed mean chrF of the round-trip.
Nonedisables the gate.
- classmethod load(path=None)[source]
Load thresholds from a YAML file, falling back to defaults.
- Parameters:
path (str or Path or None) – YAML file with a subset of the threshold fields. When
None, the bundledthresholds.yamlis used if present; otherwise the dataclass defaults apply. Unknown keys are ignored.- Returns:
The populated thresholds.
- Return type:
- class speaker_helper.eval.Transcriber(*args, **kwargs)[source]
Bases:
ProtocolOptional speech-to-text used for the fidelity round-trip.
Any object with this coroutine can be injected (e.g. a
vocal-helperadapter) to enable WER/chrF scoring. speaker-helper never imports one.
- speaker_helper.eval.available_languages()[source]
Return the sorted language codes that ship a built-in dataset.
- speaker_helper.eval.chrf(reference, hypothesis, *, max_n=6, beta=2.0)[source]
Character n-gram F-score (chrF) between reference and hypothesis.
A robust, tokenisation-free similarity that credits partial-word overlap — well suited to speech round-trips where the transcriber may mis-segment.
- Parameters:
- Returns:
Score in
[0, 1];1.0is identical (after normalisation),0.0no shared n-grams. Returns1.0when both are empty.- Return type:
Examples
>>> round(chrf("bonjour le monde", "bonjour le monde"), 3) 1.0
- speaker_helper.eval.detect_anomalies(result, *, min_chars_per_sec=4.0, max_chars_per_sec=40.0, clipping_threshold=0.999)[source]
Return a list of anomaly labels for one synthesised result (empty = clean).
The checks are engine-agnostic and decidable from the audio alone:
empty_audio— zero or near-zero duration.invalid_sample_rate— non-positive sample rate.duration_too_short/duration_too_long— the characters-per-second implied bylen(text) / durationfalls outside the plausible band, signalling truncation or a runaway stretch.clipping— a sample reaches full scale.
- Parameters:
result (AudioResult) – The synthesised audio and its metadata.
min_chars_per_sec (float) – Plausible speaking-rate band (see module constants).
max_chars_per_sec (float) – Plausible speaking-rate band (see module constants).
clipping_threshold (float) – Absolute amplitude at or above which audio is deemed clipped.
- Returns:
Sorted anomaly labels; an empty list means no anomaly was found.
- Return type:
- speaker_helper.eval.engine_quality_prior(engine)[source]
Return the prior quality score in
[0, 1]for a TTSengine.
- speaker_helper.eval.format_matrix(reports)[source]
Render a per-language report mapping as a compact text matrix.
- Parameters:
reports (dict) – Mapping
language -> EvalReport(e.g. fromrun_multilang_eval()).- Returns:
A fixed-width table with one row per language and a PASS/FAIL verdict.
- Return type:
- speaker_helper.eval.load_dataset(path=None, *, language=None)[source]
Load evaluation cases from a JSON Lines file.
- Parameters:
- Returns:
The cases in file order.
- Return type:
- Raises:
FileNotFoundError – If the resolved dataset does not exist (the error lists the languages that do ship a dataset).
ValueError – If a line is not valid JSON or lacks the required
id/textkeys.
- speaker_helper.eval.pareto_front(points)[source]
Return the non-dominated points: maximise quality, minimise RTF.
A point A dominates B if A is at least as good on both axes (higher or equal
quality, lower or equalmean_rtf) and strictly better on one.- Parameters:
points (sequence) – Candidates, each exposing
qualityandmean_rtf(e.g.EvalReport).- Returns:
The Pareto-optimal subset, in input order.
- Return type:
- speaker_helper.eval.percentile(values, p)[source]
Return the
p-th percentile (0-100) via linear interpolation.- Parameters:
- Returns:
The interpolated percentile, or
0.0for an empty input.- Return type:
Examples
>>> percentile([1, 2, 3, 4], 50) 2.5 >>> percentile([], 95) 0.0
- async speaker_helper.eval.run_eval(speaker, cases=None, *, thresholds=None, transcriber=None)[source]
Evaluate
speakerovercasesand gate onthresholds.- Parameters:
speaker (Speaker) – The façade to drive; its backend is whatever
settings.backendchose.cases (list of EvalCase or None) – Cases to run; defaults to the built-in French dataset.
thresholds (Thresholds or None) – Pass/fail bar; defaults to
Thresholds.load()(bundled YAML).transcriber (Transcriber or None) – Optional STT enabling the WER/chrF round-trip. When
None, fidelity metrics are skipped (and their thresholds are not gated).
- Returns:
The aggregated report and verdict.
- Return type:
- async speaker_helper.eval.run_multilang_eval(base_settings, languages, *, thresholds=None, transcriber=None, warmup=True)[source]
Evaluate an engine across several languages, one report per language.
- Parameters:
base_settings (Settings) – Base configuration (backend, engine, connection). Its
languageandvoice_idare overridden per language so the engine auto-picks a voice matching each language.languages (list of str) – ISO-639-1 codes to measure; each must have a bundled dataset (see
available_languages()).thresholds (Thresholds or None) – Pass/fail bar applied to every language; defaults to the bundled bar.
transcriber (Transcriber or None) – Optional STT enabling the WER/chrF round-trip in each language.
warmup (bool) – When
True(default), warm each language’s voice before measuring so the numbers reflect steady state rather than a one-off cold model/voice load. SetFalseto include cold-start cost.
- Returns:
Mapping
language -> EvalReportin the requested order.- Return type:
- speaker_helper.eval.word_error_rate(reference, hypothesis)[source]
Word error rate between a reference and a hypothesis transcript.
- Parameters:
- Returns:
edit_distance(ref_words, hyp_words) / len(ref_words).0.0for an exact match; can exceed1.0when the hypothesis inserts many words. Returns0.0if both are empty and1.0if only the reference is.- Return type:
Examples
>>> word_error_rate("le chat dort", "le chien dort") 0.3333333333333333