Как стать автором
Обновить

Проблема омографов в ударениях и как я ее решал

Уровень сложностиПростой
Время на прочтение8 мин
Количество просмотров17K

Меня зовут Денис (tg: @chckdskeasfsd), и это история о том, почему в опенсурсе нет TTS с нормальными ударениями, и как я пытался это исправить.

Обзор проблемы

Одной из немаловажных задач в синтезе речи является подготовка текста, а именно расстановка ударений в словах. Если по ударениям в обычных словах все более менее понятно (можно решать с помощью словарей), то с некоторыми "особенными" словами все немного сложнее. Эти особенные слова - омографы (за́мок/замо́к, ду́хи/духи́), а также ё-омографы (не́бо/нё́бо, все/всё́, пе́ред/перё́д, бе́рег/берё́г). Буква Ё часто используется в речи, но всё реже в текстах, потому найти качественные данные становится непростой задачей.

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

С этого и начинается история длиною в 2 месяца о том, как я пытался решать данную задачу.

Сравнение различных TTS

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

Протестированы были следующие TTS:

  1. Yandex TTS

  2. Silero TTS

  3. SberDevices TTS

  4. Ruaccent-big и Ruaccent-poetry. BIG училась только на прозе, а POETRY на поэзии и прозе. (Мои модели разрешения омографов)

Silerо-v4

Sber

Yandex

Ruaccent-big

Ruaccent-poetry

Обычные слова (30 предложений)

3

0

0

0

0

Омографы (30 предложений)

16

5

4

6

3

Стихи (13 предложений)

29

4

2

2

1

Итог

48

9

6

8

4

Хочу подметить, что в стихах ruaccent ошибся в слове, которого не было в словаре омографов (авторское ударение) и ударение проставлено было по словарю, но я честно засчитал это за ошибку.

Даже на таком небольшом тесте мы видим, как отстает силеро. Конечно, такое небольшое сравнение не сможет показать всей картины, но мы уже видим примерное качество. Да и размечать это все занятие очень трудоемкое, т.к. делать приходится все вручную из-за того, что у нас есть только аудио. Не совсем корректно, сравнивать акцентуатор и весь TTS, но я думаю было бы интересно узнать отставание опенсурса от прода больших компаний.

Силеро

Я не питаю к Silerо tts никакого негатива, но после слов про 100% решения ударений в этой статье, и убедившись в обратном на основании результатов теста, слегка разочарован.

Хорошо, в силеро вроде и не заявлялась интеллектуальная обработка омографов, только на основе частотности употребления, НО, во время работы с силеро я нашел и некоторые проблемы:

  1. Регулярное гудение, шипение и т.д

  2. Ошибки на обычных словах. Математикой 5-го класса мы высчитываем, что на каждое предложение в среднем у нас по 2.2 ошибки в слове (в стихах)

  3. Зачастую модель скатывается в месиво, где ещё попробуй разбери слова. Особенно это происходит в стихах (ссылка на пример)

  4. Модель часто игнорирует знаки препинания

Если вы хотите продолжать использовать силеро, то не используйте модель v4, v3_1 в разы лучше.

Искренне надеюсь, что у коммерческой модели качество лучше, нежели в бесплатном демо-боте и открытой модели.

Демо Silero TTS

Яндекс

В этой статье Яндекс говорили, что получают эмбеддинги от энкодера модели переводчика, но как это реализовано в их TTS сейчас, мне не известно.

Общее впечатление по качеству ударений и синтезу целом:

  1. Ошибается меньше всех (за исключением RuAccent)

  2. Шипение замечено не было

  3. Хорошо соблюдает паузы в стихах

Демо Yandex TTS

Сбер

Статей или публикаций о решении от сбера я не нашел, но на сколько выяснил, они также как и я используют дообученный BERT, но с contrastive loss.

Общее впечатление по качеству ударений и в целом

  1. Сбер зайки, отставание от яндекса по омографам не большое, вероятно обучали только на популярные.

  2. Иногда ставит ударения лучше, чем остальные (например в Седины´ не возвращают. Нам потерянных годов), когда другие ставят седи´ны

  3. Голос немного шипит

Демо SberDevices TTS

Ruaccent

Пакет состоит из 2-х нейросетей. Одна нейросеть отвечает за расстановку ударений в омографах, а другая в неизвестных словах или во всех словах, если использование словаря запрещено.

Блок схема работы:

Демо TeraTTS с RuAccent-poetry

Почему в opensource нет готовых решений?!

И так мы, протестировали TTS, поняли проблему с ударениями, но почему она все еще не решена, почему нет опенсурс решений?

  1. Открытые датасеты

Для обучения модели нужны датасеты, с их поисков я и решил начать. Но оказалось, что…

Их действительно нет, в смысле вообще. Хорошо, ну хоть что-то же есть, да?

Известно, что Яндекс постарались и сделали НКРЯ. Когда я впервые увидел, был несказанно рад, подумал "какая замечательная вещь", но оказалось к нему нельзя вот так просто взять и получить к нему доступ.

Как уже было озвучено ранее, данная проблема уже обсуждалась и ожидалось, что НКРЯ решит ее в какой-то мере, но сами НКРЯ делиться данными почему-то не хотят.

Одним прекрасным утром проснулся и понял, что мне приснился датасет. Сон я тщательно переписал и сел изучать, но изучив полученный датасет оказался слегка обескуражен. Подробнее об НКРЯ в роли датасета чуть позже, в отдельной главе.

Хорошо, пускай у нас нет НКРЯ, может есть еще что-то? С обычными ударениями мы можем еще что-то да поделать, у нас есть словарь Зализняка, а также Wiktionary, из которых я и взял словари для ударений. Из него же получил словарь омографов.

Но отсутствие уже готовых пакетов для расстановки ударений с обработкой омографов означает, что уже не выйдет расставить ударения для обучения своей нейронной сети.

  1. Компании не хотят публиковать свои наработки в открытый доступ, а также все проприетарные ударяторы работают в совокупности с TTS, что не дает “спарсить” результаты их работы и использовать в целях обучения нейросети.

  2. В интернете нет ни одного открытого пакета для разрешения омографов, по крайнем мере, я таковых не нашел. Был только mashapo/russtress, который учился на данных НКРЯ, но на данный момент он или просто игнорирует омографы или выдает неверные предсказания.

Что не так с НКРЯ?

Были озвучены сомнения в качестве НКРЯ, наверняка это какая-то ошибка… или нет? Давайте разбираться

На данной диаграмме видно, что большую часть НКРЯ составляют стихи.

Всего 134 млн предложений:

  1. Наивная поэзия - 1 236 966

  2. Поэзия - 97 702

  3. Устная публичная речь - 860

  4. Речь кино - 690

  5. Устная непубличная речь - 441

  6. Художественное чтение - 42

  7. Авторское чтение - 22

  8. Театральная речь – 16

На этой диаграмме показано сколько данных получилось у меня. Даже с учетом того, что наивной поэзии собрано примерно половина (больше не получалось по неизвестным причинам) и прозы здесь намного больше (около 112000 документов, против 2071 по данным НКРЯ)

Что же это за стихи?

Пример текста раздела “Наивная поэзия”, который составляет большую всего объема датасета.

Помимо неправильных ударений, в НКРЯ много и просто странных предложений, где в нескольких местах стоят ударения.

Вот данный стих на сайте НКРЯ

На этом рисунке мы видим неправильно расставленные ударения. Слово седины в викисловаре. Нет ни одной реальной ситуации, где было бы на Е, помимо стихов, но даже учитывая это, тут явно ошибка.

Еще битые примеры

Тогда я решил прочитать историю НКРЯ и сначала показалось, что Яндекс на свои деньги сделал себе библиотеку, а потому не удивительно, что ей и не хотят делиться.

“Еще в 1980-е годы первые отечественные корпусные лингвисты задались вопросом, каким должен быть «машинный фонд» русского языка. Все началось в Центре лингвистической документации (кружок московских лингвистов на базе МЦНМО); РАН и ОТиПЛ МГУ тоже работали над Корпусом. А программно-техническую и финансовую поддержку НКРЯ оказала компания Яндекс.”

Также

“По мнению Ивана, данные и исходный код проекта должны стать открытыми. В ответ на это представитель Яндекса заявил, что выложить код в opensource сейчас невозможно, поскольку проект содержит большое количество внутренних инструментов, открывать которые Яндекс не готов.”

Источник: ссылка

Но когда я увидел это (новость от августа 2020 года), был сильно удивлен, узнав, что ныне оно спонсировалось государством объемом в 236 млн рублей:

“В Минобрнауки России подведены итоги конкурса, победители которого получат гранты на реализацию крупных научных проектов…

Объем финансирования на три года составит 236 млн рублей.

Грант выделен на комплексную работу, связанную с обновлением платформы Национального корпуса русского языка - информационно-справочной системы, основанной на собрании русских текстов разных типов и жанров в электронной форме..”

Источник: новость

236 миллионов рублей на такой криво размеченный датасет... либо я просто чего-то не понимаю.

Как я датасет готовил

  1. Обычные слова и омографы

Разработка началась не с НКРЯ, сначала я пробовал собрать корпус используя датасет mc4, а также искал корпуса на форумах.

Получилось около 100 тысяч предложений (больше даже словосочетаний). Результат на выходе, мягко говоря, не очень. Модель работала, если в предложении была пара-тройка слов, но на реальных предложениях качество оставляло желать лучшего.

Также было ещё несколько экспериментов по обучению:

Самый первый я уже описал, вышло плохо. Потому что в датасете были неправильные примеры, да и сами данные были далеки от нормальных текстов (предложения в 2-3 слова).

В качестве базовой модели использовал ai-forever/Rubert-base

  1. Добавил весь НКРЯ + старый датасет

Итог: Вышло плохо. Лучше, чем без НКРЯ, но все равно плохо

  1. Эксперимент только с НКРЯ

Качество выросло сильнее, но стихи опять же портили метрики. Также я только потом узнал о проблеме, что мой обработчик данных работает не совсем так, как нужно.

Модель на одном НКРЯ также путалась из-за стихов в обучающих данных, еще кривая подготовка данных портила метрики (наверное). Об ошибках при подготовке данных в следующем разделе.

  1. Модель, которая используется сейчас.

Также переработал скрипт подготовки данных таким образом, что если в тексте больше одного омографа, то этот текст трансформируется в такое количество примеров, сколько омографов в этом тексте.

Гистограмма точности моделей на 100 размеченных примерах.

Ошибки во время подготовки данных

  1. Я не предусмотрел момент, что в предложении может быть несколько омографов и они все одновременно помечались, из-за чего модель путалась. я повесил замки на двери -> я повесил <w>замки</w> на <w>двери</w>

Здесь все очевидно, останавливаться не будем.

  1. При фильтрации данных я совершил не самую очевидную, но фатальную ошибку, которая по итогу значительно испортила качество.

Попробуйте найти её в этом коде:

def  replace_accents(input_str):
	return input_str.replace('\u0300', '+').replace('\u0301','+')
def  rotate_stress(word):
	replacements = {'а+': '+а', 'е+': '+е', 'ё+': '+ё', 'и+': '+и', 'о+': '+о',
	'у+': '+у', 'ы+': '+ы', 'э+': '+э', 'ю+': '+ю', 'я+': '+я', 'А+': '+А', 'Е+': '+Е', 'Ё+': '+Ё', 'И+': '+И', 'О+': '+О',
	'У+': '+У', 'Ы+': '+Ы', 'Э+': '+Э', 'Ю+': '+Ю', 'Я+': '+Я'}
	for old, new in replacements.items():
		word = word.replace(old, new)
	return word

Не выходит?) А проблема в том, что заменяться ударение будет более одного раза. Например, в слове стои+т -> сто+ит (правильный формат), а потом ст+оит, т.к эта буква стоит сразу после И. Ошибка тупая и для меня с ходу не очевидная.

Небольшой обзор модуля

Установить пакет можно командой:

pip install ruaccent
from ruaccent import RUAccent

accentizer = RUAccent()

accentizer.load(omograph_model_size='big_poetry', use_dictionary=True)
text = 'на двери висит замок.'
print(accentizer.process_all(text))
  • На данный момент доступно 6 моделей. big (рекомендуется к использованию), medium и small. Рекомендуются к использованию модели версии poetry. Их названия big_poetry, medium_poetry, small_poetry.

  • Модель big имеет 178 миллионов параметров, medium 85 миллионов, а small 42 миллиона

  • Переменная use_dictionary отвечает за загрузку всего словаря (требуется больше ОЗУ), иначе все ударения расставляет нейросеть.

  • custom_dict отвечает за добавление своих вариантов ударений в словарь. Формат такой: {'слово': 'сл+ово с удар+ением'}

Итог

Конечно, даже с помощью довольно больших нейросетей не получится полностью решить акцентуацию, например, банально из-за того, что корпус НКРЯ покрывает не все омографы (а их больше 10000). Также, пока не получилось достичь приемлемого качества на Ё-омографах, но даже модель обученная на TTS датасете Natasha (а он не очень хороший, мягко говоря) уже сносно расставляет Ё. В планах эксперименты с дистилляцией моделей в более маленькие, чтобы увеличить скорость работы.

GitHub: RuAccent. Буду благодарен фидбеку.
Демо на HF с TeraTTS: ссылка
Телеграм бот с TeraTTS и RuAccent: ссылка

Теги:
Хабы:
Всего голосов 61: ↑54 и ↓7+64
Комментарии19

Публикации

Истории

Работа

Data Scientist
69 вакансий

Ближайшие события

2 – 18 декабря
Yandex DataLens Festival 2024
МоскваОнлайн
11 – 13 декабря
Международная конференция по AI/ML «AI Journey»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань