speaker_helper.router module

Backend router: pick an engine + mode from measured quality↔speed evidence.

Module summary

The rest of speaker-helper measures a TTS operating point — real-time factor (RTF), anomaly rate, and a quality score (measured chrF, or an engine prior) — and can rank engines on the quality↔RTF plane (pareto_front()). What it historically did not do is act on that evidence: create_engine() just read settings.backend. This module closes that loop. Given an operating condition it returns a concrete, justified choice of engine, mode, and streaming knobs — never a vibe, always traceable to numbers.

Two conditions, two different objectives (this is the scientific core):

  • online real-time (delay-bounded / streaming). To sustain playback without underrun the engine must synthesise faster than real time: RTF < 1 is a hard feasibility boundary. We keep a margin for time-to-first-audio and jitter (default ceiling 0.8). Among the engines that keep up, we maximise quality. Mode is streaming with low-TTFA knobs (small first chunk, strict pipeline). If nothing keeps up, that is reported, not hidden.

  • offline (batch). There is no real-time constraint — RTF may exceed 1 — and quality is the only objective: speed is disregarded entirely. We pick the highest-quality engine outright (an optional RTF patience budget and an equal-quality speed tie-break are the only places RTF appears). Mode is offline.

For the online condition the choice is taken only from the Pareto front (the non-dominated set), so the router never returns a point some other engine beats on both axes while still keeping up. Offline is a pure quality argmax.

Where does the evidence come from? In order of confidence:

  1. Measured reports — pass a list of EvalReport (from run_eval / run_multilang_eval / tune_profiles). Both axes are then measured on your host → highest confidence.

  2. The built-in operating-point catalogue (default_operating_points()) — seeded from the per-language profiles (kokoro RTF measured on native-MLX) and the engine quality priors. RTF is known only where it was measured; other engines carry a quality prior and an unknown RTF, and are therefore excluded from online routing (we will not claim an engine keeps up if we never timed it). Confidence is flagged on every decision.

Further characterisation of new engines is a study, not a toolbox concern — run it in the speak experiment repo and fold the resulting numbers back into the catalogue or pass them as reports.

Usage example

>>> from speaker_helper.router import route, RouteRequest
>>> d = route(RouteRequest(condition="online_realtime", language="fr"))
>>> d.engine
'kokoro'
>>> d.mode
'streaming'

Author

Warith HARCHAOUI — https://linkedin.com/in/warith-harchaoui

class speaker_helper.router.OperatingPoint(engine, quality, mean_rtf, quality_source='prior', rtf_source='unknown', backend='voicebox', language=None)[source]

Bases: object

One engine’s position on the quality↔speed plane, with provenance.

Parameters:
  • engine (str) – Engine/model id (e.g. "kokoro").

  • quality (float) – Quality score in [0, 1] to maximise (measured chrF or a prior).

  • mean_rtf (float or None) – Mean real-time factor to minimise; None when never measured (the engine then cannot be routed for the online condition).

  • quality_source (str) – "measured_chrf" or "prior" — how quality was obtained.

  • rtf_source (str) – "measured", "estimate", or "unknown" — how mean_rtf was obtained.

  • backend (str) – The backend that serves this engine (default "voicebox").

  • language (str or None) – Language the measurement pertains to, when language-specific.

backend: str = 'voicebox'
engine: str
language: str | None = None
mean_rtf: float | None
quality: float
quality_source: str = 'prior'
rtf_source: str = 'unknown'
class speaker_helper.router.RouteDecision(condition, engine, backend, mode, first_chunk_sentences, stream_concurrency, quality, mean_rtf, quality_source, rtf_source, confidence, justification, candidates_considered, pareto_size)[source]

Bases: object

A concrete, justified operating point the caller can act on.

Parameters:
  • condition (str) – The condition this decision answers.

  • engine (str) – The chosen engine and the backend that serves it.

  • backend (str) – The chosen engine and the backend that serves it.

  • mode (str) – "streaming" (online) or "offline".

  • first_chunk_sentences (int) – Streaming producer/consumer knobs implied by the condition (only meaningful when mode == "streaming").

  • stream_concurrency (int) – Streaming producer/consumer knobs implied by the condition (only meaningful when mode == "streaming").

  • quality (float) – The chosen point’s quality score.

  • mean_rtf (float or None) – The chosen point’s mean RTF (None only in the offline, RTF-unknown fallback).

  • quality_source (str) – Provenance of the two axes (see OperatingPoint).

  • rtf_source (str) – Provenance of the two axes (see OperatingPoint).

  • confidence (str) – "high" (both axes measured), "medium" (one measured), or "low" (both from priors/estimates).

  • justification (str) – A human-readable, number-citing explanation of why this point won.

  • candidates_considered (int) – How many candidates were weighed and how many survived to the Pareto front — for auditability.

  • pareto_size (int) – How many candidates were weighed and how many survived to the Pareto front — for auditability.

apply(settings=None)[source]

Return settings (or fresh defaults) reconfigured for this decision.

Parameters:

settings (Settings or None) – Base configuration to derive from; None uses defaults.

Returns:

A copy carrying the chosen backend, engine, mode, and (for streaming) the first-chunk granularity. stream_concurrency is a Speaker argument, not a Settings field, so read it off this decision separately (see from_route()).

Return type:

Settings

backend: str
candidates_considered: int
condition: str
confidence: str
engine: str
first_chunk_sentences: int
justification: str
mean_rtf: float | None
mode: str
pareto_size: int
quality: float
quality_source: str
rtf_source: str
stream_concurrency: int
to_dict()[source]

Return a JSON-serialisable dict of the decision (for API / MCP / CLI).

Return type:

dict

class speaker_helper.router.RouteRequest(condition, language='fr', rtf_ceiling=0.8, rtf_budget=None, quality_floor=None, require_measured_rtf=True)[source]

Bases: object

What the caller needs; the router turns it into a justified choice.

Parameters:
  • condition (str) – "online_realtime" (delay-bounded streaming) or "offline" (throughput / quality). See CONDITIONS.

  • language (str) – ISO-639-1 target language (drives the default catalogue and profile).

  • rtf_ceiling (float) – Online only: the hard mean_rtf bound an engine must beat to be feasible. Defaults to DEFAULT_RTF_CEILING (0.8).

  • rtf_budget (float or None) – Offline only: optional patience cap on mean_rtf (None = no cap, quality is all that matters).

  • quality_floor (float or None) – Reject any candidate below this quality, in both conditions (None = no floor).

  • require_measured_rtf (bool) – Online only: refuse engines whose RTF was never measured (default True — do not claim an untimed engine keeps up).

condition: str
language: str = 'fr'
quality_floor: float | None = None
require_measured_rtf: bool = True
rtf_budget: float | None = None
rtf_ceiling: float = 0.8
speaker_helper.router.default_operating_points(language='fr')[source]

Build the fallback candidate set for language from profiles + priors.

The per-language profile supplies the measured kokoro operating point (RTF from native-MLX tuning; quality is the engine prior until a round-trip recalibrates it). Every other engine in the priors table contributes a quality-only candidate with an unknown RTF — enough to reason about offline quality, but deliberately not enough to claim it keeps up online.

Parameters:

language (str) – Language whose profile seeds the measured kokoro point.

Returns:

One candidate per known engine, provenance flagged on both axes.

Return type:

list of OperatingPoint

speaker_helper.router.route(request, *, points=None, reports=None)[source]

Choose a justified engine + mode for request from the evidence.

Parameters:
  • request (RouteRequest) – The condition and its constraints.

  • points (sequence of OperatingPoint or None) – Explicit candidate operating points. When None and reports is also None, the built-in catalogue for request.language is used.

  • reports (sequence of EvalReport or None) – Measured reports to derive candidates from (highest confidence). Takes precedence over points when both are given.

Returns:

The chosen operating point, mode, streaming knobs, and a number-citing justification.

Return type:

RouteDecision

Raises:

ValueError – If request.condition is unknown, or no candidate satisfies the condition’s constraints (e.g. no engine keeps up online).

Examples

>>> route(RouteRequest(condition="offline", language="fr")).mode
'offline'
speaker_helper.router.route_settings(condition, *, language='fr', settings=None, **request_kwargs)[source]

Convenience: route for condition and return applied settings + decision.

Parameters:
  • condition (str) – "online_realtime" or "offline".

  • language (str) – Target language.

  • settings (Settings or None) – Base settings to reconfigure; None uses defaults.

  • **request_kwargs – Extra RouteRequest fields (rtf_ceiling, rtf_budget, quality_floor, require_measured_rtf).

Returns:

Settings reconfigured for the decision, and the decision itself (its stream_concurrency still needs forwarding to Speaker).

Return type:

tuple of (Settings, RouteDecision)