Модель шумоподавления выпускает новый чекпоинт. Голос 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) | да |
dnsmos | sig / bak / ovrl (качество речи / фоновый шум / общее) | ITU-T P.835 | да |
dnsmos_p808 | одна краудсорсинговая оценка MOS | ITU-T P.808 | да |
sigmos | 7 измерений (col, disc, loud, noise, reverb, sig, ovrl) | ITU-T P.804 | да |
nisqa | mos плюс разбивка noi/dis/col/loud | NISQA-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 / estoi | 0–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) | ниже лучше | частота ошибок по словам: замены + удаления + вставки, делённые на число слов в референсе |
cer | 0–1 | ниже лучше | та же идея на уровне символов — более снисходительна к небольшим расхождениям в написании/токенизации |
mer | 0–1 | ниже лучше | частота ошибок совпадения |
wil | 0–1 | ниже лучше | потерянная словесная информация |
wip | 0–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 везде, где под вопросом правильность
транскрипта. Именно это превращает «мы выбрали этот движок» в число, которое кто-то
другой может проверить.
Если вашему проекту нужен язык, движок или условие записи, оценённые таким образом, и это ещё не покрыто, свяжитесь с нами или посмотрите наши услуги.