- Зачем: - требовалось сравнить облегченные модели диаризации на старом CPU без изменения рабочей конфигурации. - Что: - добавлен воспроизводимый и возобновляемый прогон матрицы Pyannote FP32/INT8 с WeSpeaker и TitaNet. - зафиксированы измерения 108 ячеек, ограничения эксперимента и решение сохранить модель по умолчанию. - локальные записи в каталоге tmp исключены из индекса Git. - Проверка: - .venv/bin/python -m pytest. - /tmp/local-transcriber-ruff-bin/ruff check scripts/benchmarks/diarization_calibration.py tests/test_diarization_calibration.py.
189 lines
15 KiB
Markdown
189 lines
15 KiB
Markdown
# Облегчённые модели диаризации на старом Intel Core i7
|
||
|
||
**Дата:** 2026-08-30
|
||
|
||
**Статус:** сравнительный CPU-тест. Конфигурация по умолчанию не менялась.
|
||
|
||
## Решение
|
||
|
||
Сохранить модель по умолчанию: Pyannote Segmentation 3.0 FP32, WeSpeaker
|
||
ResNet34 LM, общий порог автоматической кластеризации `0,89`. Новый прогон
|
||
подтвердил для этой связки точное число голосовых кластеров `3 / 2 / 2` на всех
|
||
трёх контрольных фрагментах.
|
||
|
||
Pyannote INT8 с WeSpeaker не заменяет FP32. Среднее ускорение составило только
|
||
2,1%, средний пиковый RSS по ячейкам снизился примерно на 4 МиБ, а средняя
|
||
чистота сопоставленных говорящих и число слов без говорящего стали хуже.
|
||
|
||
TitaNet small в среднем быстрее WeSpeaker на 24,3%, но требует примерно на
|
||
147–149 МиБ больше RSS и не находит правильное число кластеров ни в одной
|
||
проверенной точке общего автоматического порога. Его можно рассматривать только
|
||
как кандидата для режима с явно известным числом говорящих. Следующий эксперимент
|
||
должен завершиться отдельной слуховой проверкой. По этому тесту менять код,
|
||
модели или пороги нельзя.
|
||
|
||
## Границы вывода
|
||
|
||
Проверялись только четыре CPU-сочетания Pyannote FP32/INT8 ×
|
||
WeSpeaker/TitaNet на трёх пятиминутных русскоязычных рабочих созвонах из
|
||
[исходной калибровки](2026-08-14-diarization-calibration.md). Число говорящих в
|
||
них известно как `3 / 2 / 2`. Это сравнительный прогон моделей диаризации, а не
|
||
новая приёмка готовых транскриптов.
|
||
|
||
В частности:
|
||
|
||
- новой слуховой проверки не было;
|
||
- полные записи не прогонялись;
|
||
- у каждой ячейки один запуск, без повторов и случайного перемешивания порядка;
|
||
- влияние порядка, прогрева и температуры отдельно не измерено;
|
||
- ASR выполнен один раз на запись и не входит во время ячеек диаризации;
|
||
- параллельные ASR и диаризация, GPU, NPU и другие CPU не проверялись.
|
||
|
||
Происхождение, лицензии и закреплённые SHA-256 моделей описаны в
|
||
[исследовательской записке](../research/2026-08-29-lightweight-diarization-models.md),
|
||
а смысл `mapped speaker purity` и ограничения опорной разметки — в
|
||
[исходной калибровке](2026-08-14-diarization-calibration.md). Здесь эти сведения
|
||
не дублируются.
|
||
|
||
## Методика
|
||
|
||
Каждая измеряемая ячейка запускалась в новом дочернем процессе. До измеряемого
|
||
интервала загружались WAV, модели и сэмплы; полное время, CPU и пиковый RSS
|
||
считались вокруг одного вызова `diarizer.process(samples)`. Отладочный журнал
|
||
`sherpa-onnx` 1.13.5 дал время сегментации, извлечения эмбеддингов, кластеризации
|
||
и всего вызова.
|
||
Декодирование, загрузка моделей, сериализация и ASR во время не входят.
|
||
|
||
Автоматический перебор прямоугольный: каждый порог сочетания проверен на всех
|
||
трёх записях с `num_clusters=-1`. Для сочетания выбирался один общий порог.
|
||
Условие приёмки считалось выполненным только при полном совпадении общего числа
|
||
кластеров с
|
||
`3 / 2 / 2`; число содержательных кластеров оставалось диагностикой и не могло
|
||
оправдать лишний кластер. После выбора порога каждое сочетание ещё раз прошло
|
||
три записи с известным числом кластеров.
|
||
|
||
Итого сохранено 108 успешных ячеек без ошибок:
|
||
|
||
- 96 с автоматическим числом кластеров: по 18 для каждого сочетания с
|
||
WeSpeaker и по 30 для каждого сочетания с TitaNet;
|
||
- 12 с известным числом кластеров: по три для каждого из четырёх сочетаний.
|
||
|
||
Отдельно сохранены четыре результата выбора общего порога. Они описывают
|
||
агрегацию автоматических ячеек и в число 108 не входят.
|
||
|
||
Во всех 108 ячейках совпала последовательность 1853 распознанных слов после
|
||
удаления Unicode-пробелов. Инвариантность текста не нарушена.
|
||
|
||
## Оборудование и условия
|
||
|
||
- Intel Core i7-6820HQ, 4 ядра / 8 логических процессоров;
|
||
- Linux 7.0.0-30-generic x86_64;
|
||
- питание от сети, системный профиль `balanced`;
|
||
- Python 3.13.13, `sherpa-onnx` 1.13.5, `onnxruntime` 1.28.0,
|
||
NumPy 2.4.3;
|
||
- CPU provider и 8 потоков для segmentation и embedding;
|
||
- mono PCM16, 16 кГц, длительность каждого фрагмента 300 секунд.
|
||
|
||
Это тот же ноутбук, что в [предыдущей Intel-приёмке](2026-08-14-diarization-intel-i7.md),
|
||
но условия нельзя считать побайтовым повтором: там отдельно зафиксированы
|
||
governor `powersave` и урезанная доступная мощность, а версия ядра была
|
||
7.0.0-29. Во время нового перебора ночная пауза произошла до сохранения текущей
|
||
ячейки. Продолжение началось после возврата профиля `balanced`; ячеек,
|
||
измеренных в энергосберегающем профиле, в итоговом результате нет.
|
||
|
||
## Производительность полного автоматического перебора
|
||
|
||
Числа ниже — средние по всем автоматическим ячейкам сочетания. Это не повторы
|
||
одной ячейки. «Средний пиковый RSS» — среднее пикового RSS каждой ячейки;
|
||
соседний столбец показывает наибольший такой максимум во всём переборе.
|
||
|
||
| Сегментация + эмбеддинги | Ячеек | Время, с | RTF | CPU, ядер | Средний пиковый RSS, МиБ | Максимальный пиковый RSS, МиБ | Сегментация, с | Эмбеддинги, с |
|
||
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
||
| FP32 + WeSpeaker | 18 | 72,486 | 0,24162 | 6,84 | 254,55 | 265,61 | 15,295 | 56,837 |
|
||
| INT8 + WeSpeaker | 18 | 70,969 | 0,23656 | 6,94 | 250,40 | 263,00 | 17,094 | 53,524 |
|
||
| FP32 + TitaNet | 30 | 52,797 | 0,17599 | 6,80 | 401,80 | 428,11 | 14,724 | 37,723 |
|
||
| INT8 + TitaNet | 30 | 55,792 | 0,18597 | 6,70 | 399,10 | 419,71 | 17,125 | 38,278 |
|
||
|
||
INT8 ускорил сочетание с WeSpeaker на 2,1%, но сегментация стала медленнее, а
|
||
выигрыш возник на извлечении эмбеддингов. Такой результат не даёт практического
|
||
основания заменять FP32. У TitaNet FP32 оказался быстрее INT8. Относительно
|
||
соответствующей связки WeSpeaker ускорение TitaNet составило 27,2% для FP32 и
|
||
21,4% для INT8.
|
||
Среднее для двух вариантов точности — 24,3%.
|
||
|
||
Опубликованное ожидание ускорения от INT8 локально не подтвердилось. Вместо
|
||
18,9% с 3D-Speaker получено 2,1% с WeSpeaker, а с TitaNet INT8 оказался на 5,7%
|
||
медленнее FP32. Условия исходного примера и границы такого сравнения разобраны
|
||
в [исследовательской записке](../research/2026-08-29-lightweight-diarization-models.md).
|
||
|
||
За скорость TitaNet платит памятью: средний пиковый RSS выше WeSpeaker на 147,25
|
||
МиБ с FP32 и на 148,70 МиБ с INT8. Поэтому на слабом CPU его нельзя считать
|
||
безусловно облегчённым вариантом.
|
||
|
||
## Автоматический порог и диагностика качества
|
||
|
||
`Mapped speaker purity` усреднена только по T2 BDMA и Yantar, для которых есть
|
||
грубая опорная разметка. Это сравнительная прокси-метрика, не DER и не точность
|
||
по выверенной разметке.
|
||
|
||
| Сочетание | Выбранный порог | Приёмка `3 / 2 / 2` | Кластеры | Средняя purity | Слов без говорящего, из 1853 | Максимальный остаток сверх ожидаемых |
|
||
|---|---:|:---:|---|---:|---:|---:|
|
||
| FP32 + WeSpeaker | 0,85 | да | 3 / 2 / 2 | 0,82950 | 71 | 0% |
|
||
| INT8 + WeSpeaker | 0,85 | да | 3 / 2 / 2 | 0,81028 | 104 | 0% |
|
||
| FP32 + TitaNet | 1,10 | **нет** | 5 / 3 / 3 | 0,82287 | 76 | 3,89% |
|
||
| INT8 + TitaNet | 1,10 | **нет** | 3 / 2 / 3 | 0,79315 | 109 | 12,12% |
|
||
|
||
У FP32 + WeSpeaker условие приёмки проходит на плато `0,85–0,89`, у INT8 +
|
||
WeSpeaker — на `0,85–0,90`. Автоматический выбор дал `0,85` по общей
|
||
лексикографической оценке, но это не аргумент менять рабочий порог `0,89`:
|
||
новый перебор не содержит повторов или слуховой проверки, тогда как действующее
|
||
решение опирается также на предыдущую калибровку полных записей и слуховую
|
||
проверку плотного диалога.
|
||
|
||
TitaNet не прошёл условие приёмки ни в одной точке проверенной сетки `0,50–1,10`.
|
||
Порог `1,10` — лишь наименее плохая точка перебора; допустимой автоматической
|
||
конфигурацией она не является. Содержательные `3 / 2 / 3` кластера у FP32 TitaNet не отменяют
|
||
лишние голосовые кластеры: диагностический фильтр не заменяет условие приёмки.
|
||
|
||
«Максимальный остаток сверх ожидаемых» — наибольшая по трём записям доля слов,
|
||
которые попали в кластеры сверх известного числа говорящих. Метрика описывает
|
||
объём лишних кластеров, а не их количество: один крупный лишний кластер может
|
||
дать больший процент, чем несколько малых.
|
||
|
||
## Режим с известным числом говорящих
|
||
|
||
Ячейки с известным числом говорящих использовали тот же выбранный порог и
|
||
меняли только `num_clusters` на известные `3 / 2 / 2`. Все четыре сочетания
|
||
вернули точное число кластеров на всех трёх записях.
|
||
|
||
| Сочетание | Точное число кластеров | Точное число содержательных кластеров | Средняя purity |
|
||
|---|---:|---:|---:|
|
||
| FP32 + WeSpeaker | 3 / 3 записей | 3 / 3 записей | 0,82950 |
|
||
| INT8 + WeSpeaker | 3 / 3 записей | 3 / 3 записей | 0,81028 |
|
||
| FP32 + TitaNet | 3 / 3 записей | 2 / 3 записей | 0,83057 |
|
||
| INT8 + TitaNet | 3 / 3 записей | 3 / 3 записей | 0,79721 |
|
||
|
||
Близкая средняя purity FP32 TitaNet и FP32 WeSpeaker не доказывает равноценное
|
||
качество. У FP32 TitaNet на Data Test один из трёх принудительных кластеров не
|
||
достиг диагностического порога содержательности, а новой слуховой проверки не
|
||
было. Поэтому TitaNet остаётся только направлением будущего эксперимента с
|
||
обязательным известным числом говорящих.
|
||
|
||
## Ограничения и следующий шаг
|
||
|
||
- Три записи относятся к одному типу рабочих созвонов; результат не переносится
|
||
автоматически на другие языки, микрофоны и акустические условия.
|
||
- Две опорные разметки имеют секундную точность и не позволяют считать DER.
|
||
- Средние значения полного времени и RSS объединяют разные записи и пороги.
|
||
Без повторов они не оценивают дисперсию и не отделяют порядок, прогрев или
|
||
влияние температуры.
|
||
- Новый прогон не заменяет прежнюю слуховую проверку и не даёт слуховых данных
|
||
для TitaNet или INT8.
|
||
- Результат относится к последовательной CPU-диаризации на одном Core
|
||
i7-6820HQ и не предсказывает конкретный Core i5 11-го поколения.
|
||
|
||
Если возвращаться к TitaNet, следующий эксперимент должен заранее требовать
|
||
известное число говорящих, включать повторные прогоны с контролем порядка и
|
||
температуры и завершаться слуховой проверкой всех трёх записей. До этого
|
||
конфигурацию и модель по умолчанию не менять.
|