fix(gallery): calibrate preview guard against shipped speech fixtures

This commit is contained in:
Palash Debnath
2026-09-07 11:07:16 +05:30
parent 0581fb69fd
commit 2229a68cfc
3 changed files with 44 additions and 36 deletions
+6 -15
View File
@@ -57,21 +57,12 @@ _PREVIEW_SEED = 42
# 32 reliably converges to speech across the gallery's instruct/script space
# at a one-time (cached) render cost.
_PREVIEW_NUM_STEP = 32
# Spectral-flatness floor below which a render is a degenerate tonal artifact
# rather than speech. Real, mastered speech sits ~0.040.07; a tonal buzz
# collapses to <0.005. 0.015 separates the two with wide margin and sits well
# below even breathy/whisper voices (which are broadband → high flatness).
# Reject below this MEAN FRAMED spectral flatness (see _spectral_flatness).
# Calibrated against measurements, not intuition — the previous 0.015 was set
# from a synthetic speech stand-in and sat in the middle of the real-speech
# range, so it rejected most legitimate renders (Japanese/Korean/English
# previews alike). Measured on this engine's own output:
# pure tone 80 Hz 2.6e-10 | two-tone buzz 3.3e-09
# quietest REAL speech 2.0e-04 (VoxCPM2 ko, verified by ASR)
# 1e-5 sits ~3000x above the tonal cases and ~20x below the quietest real
# render — wide margin on both sides. Keep it there unless new measurements
# (not synthetic signals) say otherwise.
_DEGENERATE_FLATNESS = 1e-5
# Reject near-pure tonal artifacts using mean framed spectral flatness.
# Calibrated against the tracked speech demos exercised by
# test_archetype_preview_quality.py: the quietest (Mandarin dubbing, 44.1 kHz)
# measures ~7.7e-6, while the worst tested tonal buzz measures ~3.3e-9.
# 1e-7 leaves >10x margin on both sides without rejecting low-flatness speech.
_DEGENERATE_FLATNESS = 1e-7
def _preview_key(a: dict) -> str:
+34 -21
View File
@@ -7,13 +7,15 @@ old silence-only guard missed it (the buzz is loud, not silent) so the garbage
was cached and served.
These tests cover the fix *without the 5 GB model / a GPU*: they drive the pure
``_spectral_flatness`` / ``_is_unusable_audio`` helpers with synthetic signals,
and assert the render constants didn't regress. The real end-to-end render is
verified manually (spectral flatness back in the speech range + Whisper ASR).
``_spectral_flatness`` / ``_is_unusable_audio`` helpers with synthetic tones and
tracked speech demo renders, and assert the render constants did not regress.
"""
from __future__ import annotations
import math
from pathlib import Path
import soundfile as sf
import pytest
@@ -93,14 +95,9 @@ def test_speech_like_is_usable():
# ── Threshold stays between the two things it has to separate ───────────────
# The original 0.015 was calibrated against `_speech_like()` below, which is two
# orders of magnitude flatter than real speech, so the threshold landed inside
# the real-speech range and rejected legitimate previews (Japanese, Korean and
# English alike — ASR transcribed every one of them correctly).
#: Flattest REAL render observed, measured on engine output and confirmed to be
#: speech by transcribing it (VoxCPM2, ko). Re-measure with real renders — never
#: with a synthetic signal — before changing it.
MEASURED_SPEECH_FLOOR = 2.0e-4
# Synthetic broadband speech has much higher flatness than real voiced audio.
# Measure both sides of the threshold against actual inputs, including the
# existing demo renders that the old thresholds rejected.
def test_tonal_ceiling_is_measured_not_assumed():
@@ -119,17 +116,33 @@ def test_tonal_ceiling_is_measured_not_assumed():
assert max(tones) * 10 < arch._DEGENERATE_FLATNESS
def test_threshold_clears_the_measured_real_speech_floor():
"""The speech side of the margin cannot be synthesized — that IS the bug.
_SAMPLES = Path(__file__).resolve().parents[1] / "assets" / "samples"
_SPEECH_FIXTURES = [
"demo_voice.wav",
"demo_clone_output.wav",
*[f"voice_design/demo_voice_design_{name}.wav" for name in (
"audiobook_uk_narrator", "aussie_podcaster", "bedtime_storyteller",
"gravelly_villain", "indian_support_agent", "mandarin_sichuan", "us_news_anchor",
)],
*[f"dictation/{name}.wav" for name in (
"en_conversational", "en_technical", "fr_reservation",
)],
*[f"demo/dubbing/{name}.src.wav" for name in (
"source", "dubbed_es", "dubbed_fr", "dubbed_ja", "dubbed_zh",
)],
]
Shipping a real render as a fixture would add a binary to a suite whose
whole point is running without one, so the measurement is recorded in
``MEASURED_SPEECH_FLOOR`` and the assumption behind it is asserted here:
the synthetic stand-in sits nowhere near the real floor, which is exactly
why it cannot stand in for it.
"""
assert arch._DEGENERATE_FLATNESS < MEASURED_SPEECH_FLOOR / 10
assert arch._spectral_flatness(_speech_like()) > MEASURED_SPEECH_FLOOR * 10
@pytest.mark.parametrize("fixture", _SPEECH_FIXTURES)
def test_real_shipped_speech_clears_quality_floor(fixture):
# These are existing tracked demo renders, not synthesized stand-ins or
# asserted measurements. Loading PCM needs neither a model nor a network.
audio, _sample_rate = sf.read(_SAMPLES / fixture, dtype="float32", always_2d=True)
speech = torch.from_numpy(audio.T)
flatness = arch._spectral_flatness(speech)
assert flatness is not None
assert flatness > arch._DEGENERATE_FLATNESS * 10
assert arch._is_unusable_audio(speech) is False
def test_flatness_is_not_clip_length_dependent():
+4
View File
@@ -128,3 +128,7 @@ for Chinese — the model auto-fixes mismatches).
- **Case-insensitive**: `"Male"`, `"MALE"`, and `"male"` are all accepted, the code will normalize them to lower case.
- **Accent vs Dialect**: English accents are only applied to English speech, Chinese dialects are only applied to Chinese speech.
Gallery previews reject silent output and near-pure tonal buzz. The quality
check measures short audio frames rather than the whole clip, so longer or
softly voiced speech is not rejected merely for having low spectral flatness.