Признаки для расстановки ролей и оценка надёжности разделения
На записях с микрофоном на столе голоса участников для модели почти неразличимы: перебор четырёх моделей отпечатков и смена алгоритма кластеризации баланс улучшают, но роли всё равно скачут. Поэтому сервис теперь отдаёт то, на что можно опереться: акустику каждой реплики (громкость, доля высоких, центроид - они связаны с расстоянием до микрофона) и метрику separation_quality с флагом speakers_reliable. Ниже 0.35 разметка по говорящим случайна, и роли должна определять LLM по смыслу реплик. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4de6b14680
commit
e2db164f0b
@@ -158,3 +158,53 @@ class TestBenchmarkEndpoint:
|
||||
|
||||
with TestClient(main.app) as c:
|
||||
assert c.post("/v1/benchmark", files={"file": ("a.wav", b"x")}).status_code == 401
|
||||
|
||||
|
||||
class TestSeparationQuality:
|
||||
"""Метрика нужна, чтобы было видно, когда разметке по голосам верить нельзя."""
|
||||
|
||||
def test_distinct_voices_score_high(self):
|
||||
import numpy as np
|
||||
|
||||
from app.acoustics import separation_quality
|
||||
|
||||
emb = np.vstack([np.random.RandomState(0).randn(8, 64),
|
||||
np.random.RandomState(1).randn(8, 64) + 6])
|
||||
labels = np.array([0] * 8 + [1] * 8)
|
||||
assert separation_quality(emb, labels) > 0.4
|
||||
|
||||
def test_indistinguishable_voices_score_low(self):
|
||||
import numpy as np
|
||||
|
||||
from app.acoustics import separation_quality
|
||||
|
||||
emb = np.random.RandomState(2).randn(16, 64)
|
||||
labels = np.array([0] * 8 + [1] * 8)
|
||||
assert separation_quality(emb, labels) < 0.3
|
||||
|
||||
def test_too_few_segments_returns_zero(self):
|
||||
import numpy as np
|
||||
|
||||
from app.acoustics import separation_quality
|
||||
|
||||
assert separation_quality(np.random.randn(2, 64), np.array([0, 1])) == 0.0
|
||||
|
||||
def test_acoustics_reflect_high_frequency_content(self):
|
||||
import numpy as np
|
||||
|
||||
from app.acoustics import segment_acoustics
|
||||
|
||||
sr = 16000
|
||||
t = np.arange(sr) / sr
|
||||
low = np.sin(2 * np.pi * 300 * t).astype(np.float32)
|
||||
high = np.sin(2 * np.pi * 5000 * t).astype(np.float32)
|
||||
assert segment_acoustics(high)["hf_ratio"] > segment_acoustics(low)["hf_ratio"]
|
||||
|
||||
def test_acoustics_reflect_loudness(self):
|
||||
import numpy as np
|
||||
|
||||
from app.acoustics import segment_acoustics
|
||||
|
||||
loud = (np.random.RandomState(0).randn(16000) * 0.3).astype(np.float32)
|
||||
quiet = loud * 0.1
|
||||
assert segment_acoustics(loud)["loudness_db"] > segment_acoustics(quiet)["loudness_db"]
|
||||
|
||||
Reference in New Issue
Block a user