docs(diarization): собраны исследования и калибровка для карты #18

Merged
ddmitry merged 15 commits from feature/8-diarization-map into master 2026-08-14 17:19:15 +03:00
5 changed files with 110 additions and 8 deletions
Showing only changes of commit 99ddf77af3 - Show all commits
+2 -1
View File
@@ -61,4 +61,5 @@ uv run --with sherpa-onnx python .scratch/diarization/bench_conflict.py "<пут
на слух — тикет #12, и он намеренно идёт до калибровки.
- **Замер памяти чинился.** В разведке `psapi.GetProcessMemoryInfo` молча
возвращал ноль; `common.peak_rss_mb()` теперь зовёт `K32GetProcessMemoryInfo`
из kernel32 и проверяет код возврата.
из kernel32 и проверяет код возврата. На Linux и macOS используется
`resource.getrusage()` с поправкой на разные единицы измерения.
+11 -1
View File
@@ -64,12 +64,22 @@ class _ProcessMemoryCounters(ctypes.Structure):
def peak_rss_mb() -> float | None:
"""Пиковая рабочая память процесса в МБ; None, если снять не удалось.
Два подвоха, на которых замер в разведке 2026-08-12 вернул ноль:
На Linux ``ru_maxrss`` измеряется в КиБ, на macOS — в байтах. В Windows
используются системные счётчики процесса.
Два подвоха, на которых замер в разведке 2026-08-12 вернул ноль в Windows:
экспорт на современных Windows живёт в kernel32 как
``K32GetProcessMemoryInfo``, а без явных ``restype``/``argtypes``
псевдодескриптор процесса уезжает в вызов как 32-битное число и функция
молча не срабатывает.
"""
if sys.platform != "win32":
import resource
peak = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
divisor = 1024 * 1024 if sys.platform == "darwin" else 1024
return peak / divisor
kernel32 = ctypes.windll.kernel32
kernel32.GetCurrentProcess.restype = ctypes.c_void_p
handle = kernel32.GetCurrentProcess()
@@ -193,5 +193,7 @@ Silero VAD, то есть они проходят по тишине. В разг
- Проверить границы диаризации на слух или сверкой с внешним транскриптом:
совпадение числа говорящих не доказывает правильность интервалов.
- Сравнить эмбеддинги, обученные не только на английском, на русской речи.
- Измерить производительность на целевом Intel Core i5 11-го поколения.
- Измерить производительность на доступном слабом Intel baseline — выполнено в
[отдельном отчёте](2026-08-14-diarization-intel-i7.md); конкретный Core i5
11-го поколения недоступен.
- Измерить параллельный режим ASR и диаризации.
@@ -2,8 +2,8 @@
**Дата:** 2026-08-14
**Статус:** выбор конфигурации для проектирования. Не приёмка
производительности на целевом Intel Core i5 11-го поколения.
**Статус:** выбор конфигурации для проектирования. Производительность отдельно
проверена на [доступном старом Intel baseline](2026-08-14-diarization-intel-i7.md).
## Решение
@@ -166,8 +166,8 @@ Apache 2.0; в исходниках 3D-Speaker модель явно описа
| ERes2Net base zh | 0,152 | 1,29× |
CAMPPlus примерно на 30% быстрее WeSpeaker в этом эксперименте. Это плюс для
варианта с известным числом участников, но замер на AMD не заменяет приёмку на
целевом Intel Core i5 11-го поколения.
варианта с известным числом участников. Производительность выбранной WeSpeaker
отдельно проверена на доступном старом Intel Core i7.
## Воспроизводимость
@@ -200,7 +200,8 @@ uv run python scripts/benchmarks/diarization_calibration.py `
выпуском нужен слуховой контроль плотного диалога на финальной сборке.
- Калибровка выбирает эмбеддинги и кластеризацию, но не решает ошибки границ и
неполное распознавание наложений голосов.
- Производительность должна отдельно приниматься на целевом Intel Core i5.
- Производительность принята на доступном старом Intel Core i7; конкретный Core
i5 11-го поколения остаётся непроверенным, потому что такого устройства нет.
Для спецификации зафиксировать WeSpeaker + 0,89 как автоматический дефолт,
отдельную опцию явного числа участников и отсутствие автоматического
@@ -0,0 +1,88 @@
# Производительность диаризации на старом Intel Core i7
**Дата:** 2026-08-14
**Статус:** приёмка на доступном слабом Intel baseline. Не эквивалент замеру на
Intel Core i5 11-го поколения.
## Решение
Диаризация проходит по стоимости как **опциональная функция**. На доступном
ноутбуке обработка остаётся заметно быстрее реального времени: час записи
занимает около 23 минут при последовательном запуске ASR и диаризации.
Цена функции существенная: диаризация медленнее ASR и увеличивает полное время
примерно в 2,4 раза. Поэтому включать её без явного запроса пользователя нельзя.
Теоретическое совмещение независимых проходов уменьшило бы время часа записи до
примерно 13,6 минуты, но параллельный режим здесь не измерялся.
Запланированный Intel Core i5 11-го поколения недоступен и в обозримом будущем
не появится. Вместо бессрочного блокирующего требования принят доступный старый
Intel Core i7 как практический слабый baseline. Результат не переносится на
конкретный SKU i5 и не является сравнением микроархитектур.
## Оборудование и условия
- HP ZBook 17 G3, BIOS N81 01.61;
- Intel Core i7-6820HQ, 4 ядра / 8 логических процессоров, 2,7–3,6 ГГц;
- 29 ГиБ доступной RAM;
- Ubuntu, Linux 7.0.0-29-generic x86_64;
- питание от сети, профиль `balanced`, governor `powersave`;
- Python 3.13.13, `onnx-asr` 0.12.0, `onnxruntime` 1.28.0,
`faster-whisper` 1.2.1, `sherpa-onnx` 1.13.5, NumPy 2.4.3;
- 8 потоков CPU, порог кластеризации 0,89;
- прогоны последовательные, без намеренно запущенной конкурирующей нагрузки;
- модели после первого запуска находились в локальном кеше.
Использованы те же три записи и те же SHA-256, что в
[отчёте о калибровке](2026-08-14-diarization-calibration.md). Модель ASR —
`gigaam-v3-e2e-rnnt` INT8; диаризация — Pyannote segmentation 3.0 и WeSpeaker
ResNet34 LM.
## Результаты
Для самой длинной записи сделано три прогона каждого прохода. Для двух
остальных — по одному подтверждающему прогону: разброс трёх повторов был мал,
а коэффициенты на записях другой длины подтвердили линейное масштабирование.
| Запись | Длительность | ASR | RTFx ASR | Диаризация | RTFx диаризации |
|---|---:|---:|---:|---:|---:|
| Data Test | 26:00 | **257,1 с** (медиана: 261,2 / 257,1 / 253,7) | 6,1× | **352,6 с** (медиана: 352,6 / 349,8 / 358,8) | 4,4× |
| T2 BDMA | 14:51 | 149,0 с | 6,0× | 203,7 с | 4,4× |
| Yantar | 20:22 | 185,3 с | 6,6× | 276,0 с | 4,4× |
| **Взвешенно, три записи** | **61:13** | **591,4 с** | **6,2×** | **832,3 с** | **4,4×** |
Последовательная обработка трёх записей занимает около 1424 секунд, или
23,7 минуты, при общей длительности 61,2 минуты: **2,58× realtime**. В пересчёте
на час это около 9,7 минуты ASR и 13,6 минуты диаризации, всего **23,3 минуты**.
## Инициализация и память
| Проход | Инициализация из локального кеша | Peak RSS |
|---|---:|---:|
| ASR | 2,02,3 с | 9001035 МБ на тёплых прогонах |
| Диаризация | 0,2 с | 366469 МБ |
Первый ASR-запуск показал 23,6 секунды, но включал скачивание файлов модели,
поэтому не считается чистым cold start. Peak RSS этого процесса достиг 1174 МБ.
Пиковая память замерена отдельно для каждого последовательного прохода; для
будущего параллельного режима значения нельзя механически считать измеренным
общим пиком.
## Сопоставление с разведкой на Ryzen
На Ryzen 7 8845H для Data Test были получены 16,4× RTFx у ASR и 11,1× у
диаризации. На старом Intel оба прохода медленнее примерно в 2,6 раза, а их
соотношение почти не изменилось. Следовательно, слабое железо ухудшает абсолютное
время, но не меняет основной архитектурный вывод: диаризация дороже ASR, а
совмещение проходов потенциально полезно.
## Ограничения
- Core i7-6820HQ не моделирует производительность Core i5 11-го поколения;
- медиана трёх прогонов снята только на одной полной записи, на двух других есть
по одному подтверждающему прогону;
- чистый cold start ASR без скачивания, но с холодным файловым кешем не измерен;
- параллельный запуск ASR и диаризации не измерен;
- результат отвечает только на стоимость выбранных моделей и конфигурации, а не
на качество диаризации.