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.
This commit is contained in:
1 parent
95f295c37c
commit
1e14f2687a
8 files changed
+2704
-234
No files matched your search
@@ -2,6 +2,23 @@
|
||||
|
||||
**Статус**: Принято
|
||||
**Дата**: 2026-08-14
|
||||
**Обновлено**: 2026-08-30
|
||||
|
||||
## Решение
|
||||
|
||||
Диаризацию реализуем как явно включаемый пост-процессинг через `sherpa-onnx`.
|
||||
Говорящий назначается слову с временной привязкой, а не целому сегменту
|
||||
распознавания. Модель по умолчанию остаётся прежней: Pyannote Segmentation 3.0 FP32,
|
||||
WeSpeaker ResNet34 LM, порог кластеризации `0,89` и автоматическое число
|
||||
кластеров. Известное число говорящих можно передать явно.
|
||||
|
||||
Повторный CPU-тест FP32/INT8 × WeSpeaker/TitaNet не меняет это решение.
|
||||
INT8 с WeSpeaker дал только около 2% среднего ускорения без существенного
|
||||
выигрыша памяти и с худшими прокси-метриками. TitaNet оказался примерно на
|
||||
четверть быстрее, но потребовал ещё 147–149 МиБ RSS и не прошёл условие приёмки
|
||||
для общего автоматического порога. TitaNet можно исследовать только для режима
|
||||
с явно известным числом говорящих. Такой эксперимент должен завершиться
|
||||
слуховой проверкой. Код и модели по умолчанию на него не переключаем.
|
||||
|
||||
## Контекст
|
||||
|
||||
@@ -21,12 +38,20 @@
|
||||
## Эксперимент
|
||||
|
||||
Локальная связка `sherpa-onnx` с сегментацией Pyannote 3.0 и эмбеддингами
|
||||
WeSpeaker ResNet34 LM проверена на трёх записях с известным составом. Для
|
||||
автоматического определения числа голосовых кластеров выбран порог 0,89: это
|
||||
единственное проверенное значение, которое на трёх контрольных фрагментах дало
|
||||
3 / 2 / 2 кластера. На полной встрече втроём остался ложный кластер длительностью
|
||||
19,1 секунды; поэтому малые кластеры нельзя молча отбрасывать, а разметку нельзя
|
||||
считать эталоном точных границ и перекрывающейся речи.
|
||||
WeSpeaker ResNet34 LM проверена на трёх записях с известным составом. В исходной
|
||||
калибровке для автоматического определения числа голосовых кластеров выбран
|
||||
порог 0,89: среди проверенных тогда значений только он дал на трёх контрольных
|
||||
фрагментах `3 / 2 / 2` кластера. На полной встрече втроём остался ложный кластер
|
||||
длительностью 19,1 секунды; поэтому малые кластеры нельзя молча отбрасывать, а
|
||||
разметку нельзя считать эталоном точных границ и перекрывающейся речи.
|
||||
|
||||
В повторном CPU-переборе на тех же пятиминутных фрагментах FP32 + WeSpeaker
|
||||
прошёл условие приёмки `3 / 2 / 2` на плато `0,85–0,89`, а INT8 + WeSpeaker —
|
||||
на `0,85–0,90`.
|
||||
Это не отменяет порог 0,89: новый прогон не имел повторов и новой слуховой
|
||||
проверки. Обе связки TitaNet провалили условие приёмки во всех проверенных
|
||||
точках; число содержательных кластеров не использовалось как оправдание лишних
|
||||
голосовых кластеров.
|
||||
|
||||
Двуязычная CAMPPlus zh/en оказалась примерно на 30% быстрее и при известном
|
||||
числе участников улучшила прокси-метрику на двух записях, но для неё не нашлось
|
||||
@@ -44,6 +69,8 @@ WeSpeaker ResNet34 LM проверена на трёх записях с изв
|
||||
[калибровке](../benchmarks/2026-08-14-diarization-calibration.md),
|
||||
[смешении говорящих](../benchmarks/2026-08-14-asr-segment-speaker-mixing.md) и
|
||||
[производительности на Intel](../benchmarks/2026-08-14-diarization-intel-i7.md).
|
||||
Сравнение облегчённых моделей и границы его применимости описаны в
|
||||
[отдельном отчёте](../benchmarks/2026-08-30-lightweight-diarization-cpu.md).
|
||||
|
||||
### Сглаживание неизвестного говорящего
|
||||
|
||||
@@ -78,12 +105,7 @@ speaker Markdown хранит только начало реплики. Тем
|
||||
невозможна, потому что в нём уже потеряны доли секунды, конец слова и причина
|
||||
неопределённости.
|
||||
|
||||
## Решение
|
||||
|
||||
Диаризацию реализуем как явно включаемый пост-процессинг через `sherpa-onnx`.
|
||||
Первая версия использует Pyannote segmentation 3.0, WeSpeaker ResNet34 LM,
|
||||
порог кластеризации 0,89 и автоматическое число кластеров; известное число
|
||||
участников можно передать явно.
|
||||
## Сведение слов и разметки говорящих
|
||||
|
||||
Говорящий назначается [слову с временной
|
||||
привязкой](../../CONTEXT.md#language), а не сегменту распознавания. Каждый
|
||||
@@ -119,6 +141,9 @@ ASR-бэкенд приводит свой результат к общему н
|
||||
- Последовательный режим задаёт корректный baseline. Параллельный запуск и
|
||||
автоматическое включение на мощных устройствах требуют отдельных измерений
|
||||
после стабилизации.
|
||||
- Pyannote INT8 и TitaNet не становятся конфигурациями по умолчанию только на
|
||||
основании CPU-теста. Для TitaNet следующий допустимый эксперимент —
|
||||
режим с явно известным числом говорящих, повторами и слуховой проверкой.
|
||||
|
||||
## Отклонённые альтернативы
|
||||
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
# Облегчённые модели диаризации на старом 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, следующий эксперимент должен заранее требовать
|
||||
известное число говорящих, включать повторные прогоны с контролем порядка и
|
||||
температуры и завершаться слуховой проверкой всех трёх записей. До этого
|
||||
конфигурацию и модель по умолчанию не менять.
|
||||
@@ -0,0 +1,255 @@
|
||||
# Облегчённые модели диаризации: Pyannote INT8 и TitaNet small
|
||||
|
||||
**Дата:** 2026-08-29
|
||||
|
||||
**Статус:** исследовательская записка. Код, зависимости и рабочая конфигурация
|
||||
не менялись.
|
||||
|
||||
**Метод:** использованы только первичные публичные источники: документация,
|
||||
исходный код и выпуски sherpa-onnx, карточки владельцев моделей и исходная
|
||||
публикация TitaNet. Приватные медиа и опорные транскрипты Hypescribe не
|
||||
открывались.
|
||||
|
||||
## Краткий вывод
|
||||
|
||||
Sherpa-onnx официально документирует все четыре сочетания Pyannote
|
||||
Segmentation 3.0 FP32/INT8 с 3D-Speaker и `nemo_en_titanet_small.onnx`. В
|
||||
опубликованном разработчиками примере производительности переход FP32 → INT8
|
||||
сокращает
|
||||
RTF с 0,297 до 0,241 с 3D-Speaker и с 0,119 до 0,110 с TitaNet small. Но это
|
||||
одна 56,861-секундная китайская контрольная запись, известные четыре говорящих,
|
||||
CPU-провайдер и по одному потоку на сегментацию и эмбеддинги. Данных о
|
||||
конкретном CPU, повторностях, разбросе и качестве на русском материале страница
|
||||
не приводит. Поэтому цифры подтверждают совместимость и потенциал, но не
|
||||
заменяют локальный тест. Условия и результаты взяты с [официальной
|
||||
страницы sherpa-onnx](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html).
|
||||
|
||||
Официальные файлы выпусков доступны под следующими именами:
|
||||
|
||||
- `sherpa-onnx-pyannote-segmentation-3-0.tar.bz2` содержит
|
||||
`model.onnx` (FP32) и `model.int8.onnx`;
|
||||
- `nemo_en_titanet_small.onnx` поставляется отдельным ONNX-файлом.
|
||||
|
||||
GitHub API не публикует `digest` ни для одного из этих файлов. Ниже зафиксированы
|
||||
SHA-256 байтов, скачанных 2026-08-29 с официальных URL, и точные размеры,
|
||||
совпавшие с GitHub API. Эти хеши пригодны для закрепления текущей поставки, но
|
||||
получены в этой проверке и не заявлены разработчиками как контрольные суммы.
|
||||
|
||||
## Официальная поддержка и точные артефакты
|
||||
|
||||
### Pyannote Segmentation 3.0: FP32 и INT8 в одном архиве
|
||||
|
||||
Официальная документация sherpa-onnx называет модель
|
||||
`sherpa-onnx-pyannote-segmentation-3-0`, указывает, что она конвертирована из
|
||||
[`pyannote/segmentation-3.0`](https://huggingface.co/pyannote/segmentation-3.0),
|
||||
ссылается на [официальный каталог скриптов
|
||||
конвертации](https://github.com/k2-fsa/sherpa-onnx/tree/master/scripts/pyannote/segmentation)
|
||||
и показывает оба файла, `model.onnx` и `model.int8.onnx`, в одном архиве
|
||||
([документация и команда загрузки](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#download-the-model)).
|
||||
|
||||
Точное имя и URL:
|
||||
|
||||
```text
|
||||
sherpa-onnx-pyannote-segmentation-3-0.tar.bz2
|
||||
https://github.com/k2-fsa/sherpa-onnx/releases/download/speaker-segmentation-models/sherpa-onnx-pyannote-segmentation-3-0.tar.bz2
|
||||
```
|
||||
|
||||
На момент проверки [GitHub Releases
|
||||
API](https://api.github.com/repos/k2-fsa/sherpa-onnx/releases/tags/speaker-segmentation-models)
|
||||
сообщает размер файла `6 958 444` байта,
|
||||
`created_at=2024-10-08T12:54:09Z`, `updated_at=2024-10-08T12:54:10Z` и
|
||||
`digest=null`; сам [официальный выпуск](https://github.com/k2-fsa/sherpa-onnx/releases/tag/speaker-segmentation-models)
|
||||
содержит этот файл, а документация даёт тот же URL загрузки.
|
||||
|
||||
Проверенное содержимое архива:
|
||||
|
||||
| Файл | Размер | SHA-256 |
|
||||
|---|---:|---|
|
||||
| `model.onnx` | 5 992 913 байт | `220ad67ca923bef2fa91f2390c786097bf305bceb5e261d4af67b38e938e1079` |
|
||||
| `model.int8.onnx` | 1 540 506 байт | `d582f4b4c6b48205de7e0643c57df0df5615a3c176189be3fc461e9d18827b5d` |
|
||||
|
||||
Архив также содержит `LICENSE`, `README.md` и скрипты экспорта/проверки. Это
|
||||
согласуется с опубликованным sherpa-onnx листингом: примерно 5,7 МБ для FP32 и
|
||||
1,5 МБ для INT8
|
||||
([официальный листинг](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#download-the-model)).
|
||||
|
||||
### NeMo TitaNet small: отдельная модель эмбеддингов
|
||||
|
||||
Официальная страница примеров загружает `nemo_en_titanet_small.onnx` из выпуска
|
||||
моделей распознавания говорящих и использует его как `--embedding.model` вместе с
|
||||
обоими вариантами Pyannote
|
||||
([FP32](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#nemo-model-onnx),
|
||||
[INT8](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#nemo-model-int8-onnx)).
|
||||
Отдельная [страница моделей NeMo в sherpa-onnx](https://k2-fsa.github.io/sherpa/onnx/nemo/index.html)
|
||||
перечисляет это точное имя среди поддерживаемых моделей эмбеддингов говорящих.
|
||||
|
||||
Точное имя и URL:
|
||||
|
||||
```text
|
||||
nemo_en_titanet_small.onnx
|
||||
https://github.com/k2-fsa/sherpa-onnx/releases/download/speaker-recongition-models/nemo_en_titanet_small.onnx
|
||||
```
|
||||
|
||||
Опечатка `recongition` является частью официальной метки выпуска и URL; исправлять
|
||||
её на `recognition` нельзя. На момент проверки [GitHub Releases
|
||||
API](https://api.github.com/repos/k2-fsa/sherpa-onnx/releases/tags/speaker-recongition-models)
|
||||
сообщает размер файла
|
||||
`40 257 283` байта, `created_at=2024-10-14T07:03:02Z`,
|
||||
`updated_at=2024-10-14T07:03:03Z` и `digest=null`; [выпуск
|
||||
sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx/releases/tag/speaker-recongition-models)
|
||||
предупреждает, что лицензия у каждой модели своя и её нужно искать в исходном
|
||||
репозитории модели.
|
||||
|
||||
## Контекст опубликованных результатов
|
||||
|
||||
### Пример производительности sherpa-onnx
|
||||
|
||||
Все четыре числа ниже опубликованы в одном примере sherpa-onnx. В нём используется
|
||||
`0-four-speakers-zh.wav` длительностью 56,861 с, явно задано
|
||||
`--clustering.num-clusters=4`, а распечатанная конфигурация показывает CPU
|
||||
провайдер и `num_threads=1` отдельно для сегментации и эмбеддингов. Страница не
|
||||
указывает модель CPU, не описывает прогрев, число повторов или дисперсию и не
|
||||
публикует метрику качества против эталонной разметки
|
||||
([полный пример](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#sherpa-onnx-pyannote-segmentation-3-0)).
|
||||
|
||||
| Segmentation | Embedding | Время | RTF |
|
||||
|---|---|---:|---:|
|
||||
| Pyannote FP32 `model.onnx` | 3D-Speaker ERes2Net base | 16,870 с | 0,297 |
|
||||
| Pyannote INT8 `model.int8.onnx` | 3D-Speaker ERes2Net base | 13,679 с | 0,241 |
|
||||
| Pyannote FP32 `model.onnx` | NeMo TitaNet small | 6,756 с | 0,119 |
|
||||
| Pyannote INT8 `model.int8.onnx` | NeMo TitaNet small | 6,231 с | 0,110 |
|
||||
|
||||
По опубликованным RTF мы пересчитали относительное ускорение. INT8 ускоряет
|
||||
сочетание с 3D-Speaker примерно на 18,9%, а сочетание с TitaNet small —
|
||||
примерно на 7,6%. Замена 3D-Speaker на TitaNet small при сохранении FP32 даёт
|
||||
около 59,9%, а сочетание TitaNet small + INT8 относительно исходного FP32 +
|
||||
3D-Speaker — около 63,0%. Здесь сравнивается только время выполнения на
|
||||
указанной записи. По этим цифрам нельзя судить о DER, переносимости ускорения
|
||||
на другой CPU или качестве на русском языке
|
||||
([исходные времена и RTF](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#sherpa-onnx-pyannote-segmentation-3-0)).
|
||||
|
||||
### Что означает «small» в публикации TitaNet
|
||||
|
||||
Исходная статья определяет TitaNet-S как вариант с 256 каналами и 6,4 млн
|
||||
параметров. Для очищенного набора VoxCeleb1 в задаче верификации говорящих она
|
||||
сообщает EER 1,15% при сравнении по косинусному сходству. Для диаризации авторы
|
||||
используют эталонный детектор голосовой активности (oracle SAD), кластеризацию
|
||||
NME-SC, допуск 0,25 с и исключают перекрытия из подсчёта DER. При
|
||||
известном числе говорящих DER TitaNet-S равен 6,37 / 2,00 / 2,22 / 1,11% на
|
||||
NIST-SRE-2000 / AMI-Lapel / AMI-MixHeadset / CH109; при оценённом числе —
|
||||
5,49 / 2,30 / 1,97 / 1,42%. Это тест архитектуры и исходной контрольной точки
|
||||
NeMo в другом конвейере диаризации, не тест ONNX-экспорта внутри
|
||||
sherpa-onnx
|
||||
([первичная публикация TitaNet](https://arxiv.org/abs/2110.04410)).
|
||||
|
||||
Карточка NVIDIA NGC подтверждает назначение `titanet_small` для верификации
|
||||
говорящих, диаризации и извлечения 192-мерных эмбеддингов, но её
|
||||
раздел Performance содержит внутренне противоречивую фразу «TitaNet-L» рядом с
|
||||
6,4 млн параметров. Поэтому для чисел TitaNet-S выше использована исходная
|
||||
статья вместо этой фразы карточки
|
||||
([официальная карточка NGC](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/nemo/models/titanet_small)).
|
||||
|
||||
## Происхождение моделей и лицензии
|
||||
|
||||
### Pyannote Segmentation 3.0
|
||||
|
||||
Исходная карточка Pyannote описывает 10-секундный mono-вход 16 кГц и powerset
|
||||
выход из семи классов: тишина, три одиночных говорящих и три пары перекрывающихся
|
||||
говорящих. Модель обучил Séverin Baroudi в `pyannote.audio` 3.0.0 на сочетании
|
||||
AISHELL, AliMeeting, AMI, AVA-AVD, DIHARD, Ego4D, MSDWild, REPERE и VoxConverse
|
||||
([карточка исходной модели](https://huggingface.co/pyannote/segmentation-3.0)).
|
||||
|
||||
Исходный репозиторий помечает модель лицензией MIT и требует принять условия
|
||||
доступа к его файлам на Hugging Face. Публичный архив sherpa-onnx включает
|
||||
собственный `LICENSE` с текстом MIT; в проверенном архиве copyright указан как
|
||||
`Copyright (c) 2022 CNRS`, тогда как текущий LICENSE исходного репозитория
|
||||
указывает 2023. Тип лицензии совпадает, но при дальнейшей поставке следует
|
||||
сохранять именно `LICENSE` из закреплённого архива
|
||||
([лицензия и условия исходной модели](https://huggingface.co/pyannote/segmentation-3.0),
|
||||
[текущий LICENSE upstream](https://huggingface.co/pyannote/segmentation-3.0/blob/main/LICENSE)).
|
||||
|
||||
### NeMo TitaNet small
|
||||
|
||||
Sherpa-onnx публикует [скрипт экспорта](https://github.com/k2-fsa/sherpa-onnx/blob/master/scripts/nemo/speaker-verification/export-onnx.py),
|
||||
который загружает `EncDecSpeakerLabelModel.from_pretrained(model_name="titanet_small")`,
|
||||
экспортирует `nemo_en_titanet_small.onnx` и добавляет ONNX metadata с framework
|
||||
`nemo`, language `English`, source URL NGC, sample rate и размерностью embedding.
|
||||
[README каталога экспорта](https://github.com/k2-fsa/sherpa-onnx/tree/master/scripts/nemo/speaker-verification)
|
||||
также прямо называет NGC `titanet_small` источником модели.
|
||||
|
||||
Карточка NGC называет актуальную опубликованную версию `1.19.0`, обновлённую
|
||||
7 июня 2023 года, и описывает обучение на VoxCeleb 1/2, RIR noise, Fisher,
|
||||
Switchboard и LibriSpeech. Реализация NeMo связывает имя `titanet_small` с
|
||||
checkpoint `titanet-s.nemo` версии `1.19.0`
|
||||
([карточка NVIDIA NGC](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/nemo/models/titanet_small),
|
||||
[официальный реестр pretrained-моделей NeMo](https://github.com/NVIDIA-NeMo/Speech/blob/main/nemo/collections/asr/models/label_models.py)).
|
||||
|
||||
NGC говорит, что использование модели регулируется лицензией NeMo; ссылка из
|
||||
карточки ведёт на Apache License 2.0. Сам файл выпуска sherpa-onnx — одиночный
|
||||
ONNX-файл без соседнего LICENSE, а описание выпуска перекладывает проверку
|
||||
лицензии на пользователя. Поэтому при включении модели в приложение нужно
|
||||
зафиксировать происхождение NVIDIA NeMo/TitaNet-S и приложить лицензию Apache-2.0,
|
||||
а не считать общий LICENSE sherpa-onnx лицензией весов
|
||||
([секция Licence карточки NGC](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/nemo/models/titanet_small),
|
||||
[LICENSE NeMo](https://github.com/NVIDIA-NeMo/Speech/blob/main/LICENSE),
|
||||
[предупреждение release sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx/releases/tag/speaker-recongition-models)).
|
||||
|
||||
Происхождение нельзя воспроизвести полностью: текущий `run.sh` sherpa-onnx
|
||||
устанавливает NeMo из ветки `main` без закрепления коммита или метки, затем
|
||||
вызывает экспорт
|
||||
для `titanet_small`. Он документирует процесс, но сам по себе не доказывает,
|
||||
из какого коммита NeMo был создан файл от 2024-10-14. Для побайтовой
|
||||
воспроизводимости следует считать официально скачанный ONNX плюс SHA-256 ниже
|
||||
канонической единицей, пока разработчики не опубликуют данные закреплённой сборки
|
||||
([официальный `run.sh`](https://github.com/k2-fsa/sherpa-onnx/blob/master/scripts/nemo/speaker-verification/run.sh)).
|
||||
|
||||
## Проверенные SHA-256
|
||||
|
||||
Файлы скачаны 2026-08-29 напрямую с двух URL выше в `/tmp`; размер каждого
|
||||
сверен с полем `size` GitHub Releases API. Архив дополнительно проверен командой
|
||||
`bzip2 -t`. Поле `digest` в API было `null` для обоих файлов, поэтому ни один из
|
||||
следующих хешей нельзя называть опубликованной контрольной суммой.
|
||||
|
||||
```text
|
||||
24615ee884c897d9d2ba09bb4d30da6bb1b15e685065962db5b02e76e4996488 sherpa-onnx-pyannote-segmentation-3-0.tar.bz2
|
||||
ad4a1802485d8b34c722d2a9d04249662f2ece5d28a7a039063ca22f515a789e nemo_en_titanet_small.onnx
|
||||
```
|
||||
|
||||
Внутри проверенного Pyannote-архива:
|
||||
|
||||
```text
|
||||
220ad67ca923bef2fa91f2390c786097bf305bceb5e261d4af67b38e938e1079 model.onnx
|
||||
d582f4b4c6b48205de7e0643c57df0df5615a3c176189be3fc461e9d18827b5d model.int8.onnx
|
||||
```
|
||||
|
||||
Команда проверки после загрузки:
|
||||
|
||||
```bash
|
||||
sha256sum \
|
||||
sherpa-onnx-pyannote-segmentation-3-0.tar.bz2 \
|
||||
nemo_en_titanet_small.onnx
|
||||
```
|
||||
|
||||
## Результат локальной проверки
|
||||
|
||||
[Прогон на Core i7-6820HQ](../benchmarks/2026-08-30-lightweight-diarization-cpu.md)
|
||||
не подтвердил опубликованное ускорение INT8: сочетание с WeSpeaker выиграло
|
||||
только 2,1%, а с TitaNet стало на 5,7% медленнее. TitaNet ускорил обработку в
|
||||
среднем на 24,3%, но потребовал примерно на 147–149 МиБ больше RSS и не прошёл
|
||||
приёмку общего автоматического порога.
|
||||
|
||||
## Практический вердикт
|
||||
|
||||
1. Для минимального эксперимента можно заменить только путь Pyannote
|
||||
`model.onnx` на `model.int8.onnx`: это официально поставляемый вариант того же
|
||||
архива и не требует менять модель эмбеддингов
|
||||
([официальный пример INT8](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#d-speaker-model-int8-onnx)).
|
||||
2. Для большего потенциального ускорения sherpa-onnx официально принимает
|
||||
`nemo_en_titanet_small.onnx` с обоими вариантами Pyannote, но опубликованный
|
||||
пример производительности не измеряет DER и не относится к русской речи
|
||||
([официальные примеры NeMo](https://k2-fsa.github.io/sherpa/onnx/speaker-diarization/models.html#nemo-model-onnx)).
|
||||
3. Для воспроизводимой поставки следует закрепить точные URL, размеры и SHA-256,
|
||||
хранить MIT LICENSE из Pyannote-архива и явно приложить сведения об авторстве
|
||||
и лицензии Apache-2.0 для TitaNet/NeMo. До локальной калибровки нельзя
|
||||
переносить ни коэффициент ускорения, ни порог кластеризации, ни качество с
|
||||
опубликованной контрольной записи на целевые русскоязычные созвоны.
|
||||
Reference in new issue
Block a user