docs(diarization): зафиксированы результаты приёмки и анализа

- Зачем:
  - решения по неопределённым словам и CPU-стоимости должны быть проверяемыми до публикации реализации.
- Что:
  - задокументировано отклонение post-hoc сглаживания Speaker ? по соседним кластерам.
  - добавлено исследование стоимости каскада и облегчённых embedding-моделей.
- Проверка:
  - `git diff --cached --check` — без ошибок.
This commit is contained in:
Dmitriy Dementiev
2026-08-14 21:56:10 +03:00
parent 726718197f
commit 98baf55572
2 changed files with 233 additions and 0 deletions
@@ -45,6 +45,39 @@ WeSpeaker ResNet34 LM проверена на трёх записях с изв
[смешении говорящих](../benchmarks/2026-08-14-asr-segment-speaker-mixing.md) и
[производительности на Intel](../benchmarks/2026-08-14-diarization-intel-i7.md).
### Сглаживание неизвестного говорящего
После приёмки отдельно проверена идея автоматически назначать `Speaker ?`
известному говорящему, если короткий неизвестный фрагмент находится между двумя
репликами одного и того же `Speaker N`. На трёх контрольных транскриптах найдено
143 таких неизвестных фрагмента, содержащих 309 слов. У 79 фрагментов соседи
имели одинаковую метку, у 64 — разные.
Для T2 BDMA и Yantar результат грубо сопоставлен с независимыми Hypescribe-
транскриптами. Это не gold-разметка: их границы округлены до секунды, а готовый
speaker Markdown хранит только начало реплики. Тем не менее эвристика не показала
достаточной селективности:
| Эвристика | Изменённых фрагментов на трёх записях | Совпадение на двух записях с опорой |
|---|---:|---:|
| Все неизвестные между одинаковыми соседями | 79 | 22 / 42 (52%) |
| Только один неизвестный word | 35 | 11 / 20 (55%) |
| Не больше двух words | 50 | 15 / 30 (50%) |
| Одинаковый отображённый timestamp | 42 | 14 / 22 (64%) |
Короткие `Да`, `Нет` и `Угу` часто являются самостоятельной репликой другого
участника. В одном из контрольных случаев неизвестный фрагмент `— Угу. — А`
даже содержал границу двух голосов, хотя с обеих сторон находился один и тот же
кластер. Поэтому post-hoc сглаживание по соседям скрывает полезную
неопределённость и не применяется. `Speaker ?` остаётся явным результатом ничьей
или отсутствия временного перекрытия.
Если к этой задаче возвращаться, проверять нужно исходные границы `Word` и
`SpeakerInterval` до группировки: отдельно различать нулевой timestamp, реальный
зазор между интервалами и ничью перекрытий. По готовому Markdown такая проверка
невозможна, потому что в нём уже потеряны доли секунды, конец слова и причина
неопределённости.
## Решение
Диаризацию реализуем как явно включаемый пост-процессинг через `sherpa-onnx`.
@@ -97,3 +130,4 @@ ASR-бэкенд приводит свой результат к общему н
| `pyannote.audio` | Тянет PyTorch и требует Hugging Face token с принятием лицензии |
| Сборка поверх приватных деталей `onnx-asr` | Экономит небольшую отдельную зависимость ценой нестабильного внутреннего API и собственной кластеризации |
| Параллельные проходы в первой версии | Нет прямого benchmark и измеренного общего пика памяти; сначала нужен корректный последовательный baseline |
| Автоматически назначать `Speaker ?` одинаковому соседнему кластеру | На двух записях с независимой опорой совпало только 52% назначений; лимиты по словам и округлённому времени не отделили короткие ответы другого участника |