Все статьи

· Casimiro Ferreira· 8 мин чтения

Измерение качества речи без панели слушателей

  • speechonnxmetrics
  • TTS
  • ONNX
  • evaluation

Модель шумоподавления выпускает новый чекпоинт. Голос TTS переобучается на большем объёме данных. Конвейер клонирования голоса меняет вокодер. В каждом случае кто-то должен ответить: результат стал лучше или хуже, чем раньше? «Мне кажется, звучит лучше» не масштабируется. Это ломается в тот момент, когда язык не тот, на котором вы говорите, в тот момент, когда нужно сравнить двадцать чекпоинтов вместо двух, или в тот момент, когда изменение нужно проверять при каждом коммите, а не один раз вручную.

Строгий ответ на вопрос «звучит ли это лучше» — это Mean Opinion Score (MOS): поставить аудио перед панелью слушателей, попросить каждого оценить от 1 до 5 и усреднить оценки. MOS — стандартная метрика качества речи именно потому, что задаёт вопрос, который имеет значение, — сочтёт ли это приемлемым человек — вместо суррогата этого вопроса. Она же и дорога. Набор панели, её последовательное проведение и повторение для каждого языка, каждого условия записи и каждой версии модели, которую выпускает небольшая команда, — это не то, за чем панель слушателей может успевать.

speechonnxmetrics — это библиотека для приближения этого суждения без панели, на каждой сборке. Она группирует свои метрики в три семейства, и выбор правильного семейства для ситуации важнее любого отдельного числа.

Три семейства, три вопроса

Безреференсные предикторы MOS — это нейросети, обученные предсказывать, что сказала бы панель слушателей, используя только аудио. Им не нужен чистый оригинал — только результат, который вы хотите оценить. Используйте это семейство, когда нет эталона для сравнения: оценка результата системы TTS или проверка реальной, уже деградировавшей записи после шумоподавления.

Интрузивные метрики требуют совпадающего чистого референса и измеряют расстояние между ним и деградировавшим сигналом. Используйте это семейство, когда вы сами создали деградацию и всё ещё храните чистый оригинал: вы пропустили заведомо хорошую запись через кодек, модель расширения полосы пропускания или преобразователь голоса и хотите знать, насколько результат отклонился от источника.

Текстовые метрики на основе ASR транскрибируют результат распознавателем речи и сравнивают транскрипт с ожидаемым текстом. Это отлавливает то, что не могут два других семейства: аудио, которое звучит совершенно естественно и чисто, но говорит не те слова. Безреференсный предиктор MOS оценивает естественность, а не правильность — беглое неверное произношение оценивается хорошо. Интрузивной метрике нужна референсная волновая форма, а не референсное предложение. Только сравнение текста отлавливает неверное слово.

Библиотека раскрывает всё это через одну функцию:

import speechonnxmetrics as s

# No-reference: only the output needed, no ground truth exists
s.score("output.wav", ["utmos"])

# Intrusive: needs a clean reference, ref= is required
s.score("degraded.wav", ["stoi", "mcd", "si_sdr"], ref="clean.wav")

Текстовые метрики находятся в отдельном модуле, speechonnxmetrics.asr, потому что они сравнивают строки, а не аудио — s.score() диспетчеризует только метрики, принимающие волновую форму.

Безреференсный MOS: чтение чисел

Поставляются четыре предиктора MOS, каждый возвращает значения по шкале 1-5, где выше лучше — та же шкала, что использует человеческая панель:

метрикаизмеренияобучена накоммерческое использование
utmosодна оценка естественностисинтезированная речь (VoiceMOS Challenge)да
dnsmossig / bak / ovrl (качество речи / фоновый шум / общее)ITU-T P.835да
dnsmos_p808одна краудсорсинговая оценка MOSITU-T P.808да
sigmos7 измерений (col, disc, loud, noise, reverb, sig, ovrl)ITU-T P.804да
nisqamos плюс разбивка noi/dis/col/loudNISQA-v2нет — CC BY-NC-SA 4.0

nisqa — единственная метрика во всей библиотеке с некоммерческими весами. Остальные четыре лицензированы по MIT. speechonnxmetrics не фильтрует это за вас; она указывает лицензию и оставляет выбор за вызывающей стороной.

Вот что показывает реальное аудио. Прогон собственных встроенных фикстур библиотеки — чистой записи (source.wav) и ресинтеза того же клипа нейросетевым кодеком (facodec_aria.wav) — через UTMOS:

>>> s.score("source.wav", ["utmos"])
{'utmos': 4.41}
>>> s.score("facodec_aria.wav", ["utmos"])
{'utmos': 3.21}

Чистая запись оказывается близко к верху шкалы, как и должно быть — это настоящая человеческая речь, не синтезированная. Ресинтез кодеком падает более чем на целый пункт. Этот разрыв, больше, чем любое из чисел по отдельности, — полезный сигнал: он говорит, что кодек вносит слышимую деградацию, и даёт число для отслеживания по мере настройки кодека.

DNSMOS на той же чистой записи:

>>> s.score("source.wav", ["dnsmos"])
{'dnsmos.sig': 3.45, 'dnsmos.bak': 3.60, 'dnsmos.ovrl': 2.93}

Три числа, не одно, и они расходятся — ovrl заметно ниже и sig, и bak. Это расхождение информативно, а не баг: ovrl — это оценка P.835 общего впечатления от прослушивания, и она склонна наказывать запись сильнее, чем предполагала бы любая из отдельных оценок компонентов, особенно для записи из реального мира, а не студийной. Когда bak низок, ищите фоновый шум. Когда sig низок, ищите артефакты уровня голоса — клиппинг, пропуски, роботизированный тембр. Сообщайте более одного предиктора для одного и того же клипа: они обучены на разных данных и расходятся информативным образом, и большой разрыв между двумя независимыми предикторами на одном клипе — это сигнал пойти и послушать.

Интрузивные метрики: чтение чисел

Одиннадцать референсных метрик измеряют расстояние от чистого оригинала. Те, что стоит знать в первую очередь:

метрикадиапазоннаправлениечто измеряет
stoi / estoi0–1выше лучшекратковременная объективная разборчивость — сколько содержания уцелело, независимо от того, насколько естественно оно звучит
si_sdr / sdr / snrдБ, неограниченовыше лучшеотношение сигнал/искажение, сигнал/шум
mcdдБ, неограниченониже лучшемел-кепстральное искажение — расстояние спектральной огибающей, классическая метрика качества TTS/VC
log_f0_rmseнеограниченониже лучшеошибка контура высоты тона
lsd / msdдБниже лучшелог-спектральное / мел-спектральное расстояние

Обратите внимание, что направление меняется: STOI и семейство SDR растут, когда качество лучше; MCD, ошибка высоты тона и спектральное расстояние падают. Перепутать их при чтении таблицы — лёгкая ошибка.

Оценка того же ресинтеза кодеком против его чистого источника:

>>> s.score("facodec_aria.wav", ["stoi", "mcd", "si_sdr"], ref="source.wav")
{'stoi': 0.662, 'mcd': 10.46, 'si_sdr': -26.94}

STOI 0.66 по шкале 0–1, где 1.0 — идеальное совпадение, говорит о том, что разборчивость реально пострадала — это заметно ниже того, что показала бы легко обработанная запись. SI-SDR примерно −27 дБ подтверждает это: SI-SDR отрицателен, когда энергия искажения превышает сигнал, и большое отрицательное число означает сильное структурное изменение, а не просто добавленный шум. MCD 10.46 дБ высок; опубликованные системы TTS, которые звучат явно синтетически, но всё же согласованно с диктором, обычно оказываются в однозначных числах, так что 10+ указывает на существенный дрейф спектральной огибающей между ресинтезом и оригиналом.

Метрики на основе ASR: чтение чисел

Пять текстовых метрик получены из одного выравнивания по Левенштейну между референсным транскриптом и гипотезой (тем, во что аудио было фактически транскрибировано):

метрикадиапазоннаправлениезначение
wer≥ 0 (обычно 0–1, может превышать 1)ниже лучшечастота ошибок по словам: замены + удаления + вставки, делённые на число слов в референсе
cer0–1ниже лучшета же идея на уровне символов — более снисходительна к небольшим расхождениям в написании/токенизации
mer0–1ниже лучшечастота ошибок совпадения
wil0–1ниже лучшепотерянная словесная информация
wip0–1выше лучшесохранённая словесная информация (1 − wil)

Разобранный пример: референс «the quick brown fox jumps over the lazy dog» против гипотезы «the quick brown fox jumped over a lazy dog» (одна замена, «jumps» → «jumped», одно удаление «the»):

>>> from speechonnxmetrics import asr
>>> from speechonnxmetrics.asr import BASIC
>>> asr.wer(reference, hypothesis, normalizer=BASIC)
0.222
>>> asr.cer(reference, hypothesis, normalizer=BASIC)
0.116

WER 0.22 означает, что примерно одно слово из пяти неверно — заметно, стоит послушать. CER ниже на той же паре, потому что посимвольная оценка трактует однословную замену как горстку символьных правок внутри гораздо более длинной символьной строки, а не как целый пропущенный токен; CER и WER отвечают на разные вопросы и напрямую не сравнимы друг с другом. WER выше примерно 0.3–0.4 на естественной речи обычно означает, что у системы ASR или у транскрибируемого ею аудио есть реальная проблема, а не ошибка округления.

speechonnxmetrics никогда не нормализует текст за вас — необработанное сравнение считает регистр и пунктуацию ошибками, что редко является тем, что вам нужно при оценке произношения, а не точного форматирования транскрипции. Передайте нормализатор явно: BASIC приводит к нижнему регистру и схлопывает пробелы, STRICT также раскрывает сокращения и убирает диакритику, пунктуацию и слова-паразиты.

Самая важная оговорка

Каждое безреференсное число MOS в этой библиотеке — это предсказание модели, а не измерение факта. UTMOS, DNSMOS, SIGMOS и NISQA каждый обучен на конкретном наборе данных прослушивающих тестов, на конкретных языках и в конкретных условиях записи. Предиктор, обученный в основном на английских студийных записях, может неверно оценить язык, которого никогда не видел при обучении, акцент, который его обучающая панель никогда не оценивала, или условие записи — телефонное аудио, шумную комнату, низкокачественный микрофон — вне его обучающего распределения. Модель не лжёт; она экстраполирует, а экстраполяция по незнакомым входам — это именно там, где нейросетевые предикторы наименее надёжны.

Относитесь к предсказанному MOS как к свидетельству, а не как к истине. Он заслуживает доверия в том, в чём хорош: отлавливание крупных регрессий, ранжирование нескольких кандидатов друг против друга и пометка прогона, который требует, чтобы человек действительно послушал. Это не замена реальной панели слушателей, когда решение имеет высокую ставку, и это не должно быть последним словом по языку или условию, для оценки которых базовая модель не обучалась. Сообщение нескольких предикторов вместе и трактовка расхождения между ними как повода послушать, а не как шума, который нужно усреднить, — это практическая мера смягчения.

Почему именно это делает сравнение пригодным для использования

Ничто из этого не полезно в изоляции. Это становится полезным в тот момент, когда несколько движков нужно сравнить на равных условиях — какой движок TTS, какой движок STT, какую модель улучшения использовать по умолчанию. Библиотеки речи на чистом ONNX, для оценки которых была построена speechonnxmetrics — TTS, ASR, шумоподавление, клонирование голоса — публикуют сравнения по движкам, произведённые именно теми метриками выше: безреференсный MOS для систем без эталона, интрузивные метрики там, где существует чистый референс, WER/CER везде, где под вопросом правильность транскрипта. Именно это превращает «мы выбрали этот движок» в число, которое кто-то другой может проверить.

Если вашему проекту нужен язык, движок или условие записи, оценённые таким образом, и это ещё не покрыто, свяжитесь с нами или посмотрите наши услуги.