Files
local-transcriber/docs/benchmarks/2026-08-30-lightweight-diarization-cpu.md
T
Dmitry Dementiev 1e14f2687a test(diarization): добавлен стенд сравнения CPU-моделей
- Зачем:
  - требовалось сравнить облегченные модели диаризации на старом 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.
2026-08-30 12:02:34 +03:00

15 KiB
Raw Blame History

Облегчённые модели диаризации на старом 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 на трёх пятиминутных русскоязычных рабочих созвонах из исходной калибровки. Число говорящих в них известно как 3 / 2 / 2. Это сравнительный прогон моделей диаризации, а не новая приёмка готовых транскриптов.

В частности:

  • новой слуховой проверки не было;
  • полные записи не прогонялись;
  • у каждой ячейки один запуск, без повторов и случайного перемешивания порядка;
  • влияние порядка, прогрева и температуры отдельно не измерено;
  • ASR выполнен один раз на запись и не входит во время ячеек диаризации;
  • параллельные ASR и диаризация, GPU, NPU и другие CPU не проверялись.

Происхождение, лицензии и закреплённые SHA-256 моделей описаны в исследовательской записке, а смысл mapped speaker purity и ограничения опорной разметки — в исходной калибровке. Здесь эти сведения не дублируются.

Методика

Каждая измеряемая ячейка запускалась в новом дочернем процессе. До измеряемого интервала загружались 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-приёмке, но условия нельзя считать побайтовым повтором: там отдельно зафиксированы 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. Условия исходного примера и границы такого сравнения разобраны в исследовательской записке.

За скорость 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, следующий эксперимент должен заранее требовать известное число говорящих, включать повторные прогоны с контролем порядка и температуры и завершаться слуховой проверкой всех трёх записей. До этого конфигурацию и модель по умолчанию не менять.