hermes(stt): tune final decode for fast-and-accurate (beam 2, name priming)

Default final beam 5 -> 2: the accuracy/speed knee - most of beam
search's benefit at ~2x greedy instead of ~5x, protecting commit
latency on the Jetson (still env-overridable via
HERMES_STT_FINAL_BEAM_SIZE). Prompt now also primes common names (Amy,
Claude, Hermes) so 'Amy' stops transcribing as 'aiming'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
This commit is contained in:
jenkins 2026-08-24 16:57:50 -03:00
parent 1fdfaff096
commit 64b7bc55cf
2 changed files with 6 additions and 4 deletions

View File

@ -35,8 +35,9 @@ CACHE_DIR = Path(os.getenv("HERMES_STT_CACHE", "/cache/whisper"))
# memorizing any single user's phrases. It is never applied to the fast rolling
# previews, which must stay clean and cheap.
DEFAULT_INITIAL_PROMPT = (
"Proper nouns keep their capitalization and accents, for example "
"Córdoba, Cancún, Málaga, Moscú, Москва, and New York."
"Proper nouns and names keep their capitalization and accents, for "
"example Córdoba, Cancún, Málaga, Moscú, Москва, New York, and names "
"like Amy, Claude, and Hermes."
)
INITIAL_PROMPT = os.getenv("HERMES_STT_INITIAL_PROMPT", DEFAULT_INITIAL_PROMPT).strip()
@ -57,7 +58,7 @@ def _parse_temperature_fallback(raw: str) -> tuple[float, ...]:
# The accurate committed transcript retries a low-confidence greedy pass at a
# few higher temperatures; the fast rolling preview never does.
FINAL_BEAM_SIZE = max(1, int(os.getenv("HERMES_STT_FINAL_BEAM_SIZE", "5")))
FINAL_BEAM_SIZE = max(1, int(os.getenv("HERMES_STT_FINAL_BEAM_SIZE", "2")))
FINAL_TEMPERATURE = _parse_temperature_fallback(
os.getenv("HERMES_STT_FINAL_TEMPERATURE", "0.0,0.2,0.4")
)

View File

@ -489,7 +489,7 @@ def test_final_decode_is_accurate_and_primed_while_rolling_stays_fast_and_clean(
final_model = _RecordingModel()
module._decode_final(final_model, wav, "auto")
assert final_model.options["beam_size"] == module.FINAL_BEAM_SIZE >= 5
assert final_model.options["beam_size"] == module.FINAL_BEAM_SIZE >= 2
assert final_model.options["temperature"] == module.FINAL_TEMPERATURE
assert final_model.options["temperature"][0] == 0.0
assert len(final_model.options["temperature"]) > 1
@ -511,6 +511,7 @@ def test_initial_prompt_is_env_overridable_and_default_primes_places(monkeypatch
# The default primes accented, capitalized place names across EN/ES/RU.
assert "Córdoba" in module.DEFAULT_INITIAL_PROMPT
assert "Москва" in module.DEFAULT_INITIAL_PROMPT
assert "Amy" in module.DEFAULT_INITIAL_PROMPT
assert module.INITIAL_PROMPT == module.DEFAULT_INITIAL_PROMPT
monkeypatch.setenv("HERMES_STT_INITIAL_PROMPT", "Custom prime.")