speaker_helper.eval.deepeval_metrics module
DeepEval metrics wrapping speaker-helper’s speed and integrity measurements.
Module summary
The evaluation contract asks for a dedicated evaluation framework, not just hand-rolled asserts. speaker-helper’s native metrics (RTF, audio anomalies) are audio-specific, so instead of forcing a text-only framework to measure audio we adapt those measurements as DeepEval custom metrics. That plugs speaker-helper into DeepEval’s test-case model, reporting, and thresholds while keeping the actual measurement in this project.
Both metrics are deterministic and offline — they read values a caller stores in
test_case.additional_metadata (rtf and anomalies), so no LLM, API
key, or network is involved.
deepeval is imported at module import time, so this module is optional: it is
only imported by callers that installed the eval extra.
Usage example
>>> # from deepeval.test_case import LLMTestCase
>>> # tc = LLMTestCase(input="Bonjour.", actual_output="<audio>",
>>> # additional_metadata={"rtf": 0.3, "anomalies": []})
>>> # RealTimeFactorMetric(threshold=1.0).measure(tc) # -> 1.0 (passes)
- class speaker_helper.eval.deepeval_metrics.AudioIntegrityMetric(*args, **kwargs)[source]
Bases:
BaseMetricDeepEval metric: passes when the synthesised audio has no anomaly.
Notes
Reads
test_case.additional_metadata['anomalies'](a list of labels fromdetect_anomalies()); an empty list passes.
- class speaker_helper.eval.deepeval_metrics.RealTimeFactorMetric(*args, **kwargs)[source]
Bases:
BaseMetricDeepEval metric: passes when synthesis is faster than real time.
- Parameters:
threshold (float) – Maximum acceptable real-time factor (
compute_s / duration_s). Defaults to1.0— the operating point (faster than real time).
Notes
Reads
test_case.additional_metadata['rtf']; a missing value scores 0.
- class speaker_helper.eval.deepeval_metrics.RoundTripIdempotenceMetric(*args, **kwargs)[source]
Bases:
BaseMetricDeepEval metric: text → speech → text should recover the text.
This formalises the idempotence view of synthesis quality: if you synthesise a sentence and transcribe the audio back (with
vocal-helper, the STT sibling), an intelligible voice yields a transcript close to the original. We score that closeness with chrF (character n-gram F-score, robust to the ASR’s tokenisation) and pass when it clears a bar.What this does and does not measure
It measures intelligibility — a necessary lower bound on quality — not naturalness (a clear-but-robotic voice can still score high). It also couples TTS quality with the ASR’s quality, so absolute chrF is best read as a relative ranking across engines scored by the same ASR (the ASR’s error is largely common-mode and cancels when comparing engines). For a naturalness axis, pair this with a MOS predictor (e.g. UTMOSv2) measured in the
speakstudy.- param threshold:
Minimum acceptable round-trip chrF in
[0, 1]. Defaults to0.75, matching the bundled fidelity bar (thresholds.yaml:min_mean_chrf).- type threshold:
float
Notes
Reads
test_case.metadata['chrf'](the round-trip chrF a caller stored fromchrf()); a missing value scores 0.- Parameters:
threshold (float)