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

в 17:58, , рубрики: diy или сделай сам, natural language processing, text-to-speech, TTS, голосовые интерфейсы, звук, машинное обучение, синтез речи

hero_image

В нашей прошлой статье про синтез речи мы дали много обещаний: убрать детские болячки, радикально ускорить синтез еще в 10 раз, добавить новые "фишечки", радикально улучшить качество.

Сейчас, вложив огромное количество работы, мы наконец готовы поделиться с сообществом своими успехами:

  • Снизили размер модели в 2 раза;
  • Научили наши модели делать паузы;
  • Добавили один высококачественный голос (и бесконечное число случайных);
  • Ускорили наши модели где-то примерно в 10 раз (!);
  • Упаковали всех спикеров одного языка в одну модель;
  • Наши модели теперь могут принимать на вход даже целые абзацы текста;
  • Добавили функции контроля скорости и высоты речи через SSML;
  • Наш синтез работает сразу в трех частотах дискретизации на выбор — 8, 24 и 48 килогерц;
  • Решили детские проблемы наших моделей: нестабильность и пропуск слов, и добавили флаги для контроля ударения;

Это по-настоящему уникальное и прорывное достижение и мы не собираемся останавливаться. В ближайшее время мы добавим большое количество моделей на разных языках и напишем целый ряд публикаций на эту и смежные темы, а также продолжим делать наши модели лучше (например, еще в 2-5 раз быстрее).

Попробовать модель как обычно можно в нашем репозитории и в колабе.

Как попробовать

Для самых нетерпеливых — вот основные примеры звучания:

Как обычно, все инструкции можно найти:

  • В нашем публичном репозитории по ссылке. Вам нужны модели для синтеза V3;
  • Или можно прямо в колабе;

Вот самый минималистичный пример вызова модели:

import torch

device = torch.device('cpu')
torch.set_num_threads(4)
speaker = 'xenia'  # 'aidar', 'baya', 'kseniya', 'xenia', 'random'
sample_rate = 48000  # 8000, 24000, 48000

model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models',
                                     model='silero_tts',
                                     language='ru',
                                     speaker='ru_v3')
model.to(device)
audio = model.apply_tts(text=example_text,
                        speaker=speaker,
                        sample_rate=sample_rate)

Спикеров и принимаемые символы для каждой модели можно посмотреть в свойствах модели model.speakers и model.symbols.

Или вот такой пример, если вы хотите скачать модель к себе более явно в кеш:

import os
import torch

device = torch.device('cpu')
torch.set_num_threads(4)
local_file = 'model.pt'
speaker = 'xenia'  # 'aidar', 'baya', 'kseniya', 'xenia', 'random'
sample_rate = 48000  # 8000, 24000, 48000

if not os.path.isfile(local_file):
    torch.hub.download_url_to_file('https://models.silero.ai/models/tts/ru/ru_v3.pt',
                                   local_file)  

model = torch.package.PackageImporter(local_file).load_pickle("tts_models", "model")
model.to(device)

audio = model.apply_tts(text=example_text,
                        speaker=speaker,
                        sample_rate=sample_rate)

Как обычно, больше примеров вы можете найти по ссылкам в репозитории или в статье ниже. Все дальнешие примеры мы будем приводить без импортов для экономии места. С недавнего времени у моделей также появился своё pip-пакет, аналогичный по функционалу импорту через torch.hub.

Новые фишки и примеры аудио

Перечислим еще раз все нововведения вместе и более подробно пройдемся по каждому из них ниже с примерами:

  • Снизили размер модели в 2 раза (ненарочно);
  • Научили наши модели делать паузы;
  • Добавили один высококачественный голос (и бесконечное число случайных);
  • Ускорили наши модели где-то примерно в 10 раз (!);
  • Упаковали всех спикеров одного языка в одну модель;
  • Наши модели теперь могут принимать на вход даже целые абзацы текста;
  • Добавили функции контроля скорости и высоты речи через SSML;
  • Наш синтез работает сразу в трех частотах дискретизации на выбор — 8, 24 или 48 килогерц;
  • Решили детские проблемы наших моделей: нестабильность и пропуск слов, и добавили флаги для контроля ударения;

Ускорение моделей в 10 раз

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

Скорость мы измеряем в секундах сгенерированного аудио в секунду, ограничивая число потоков в PyTorch (1 ядро = 2 потока) на процессоре Intel.

Так например, скорость V3 модели для 8 kHz в 50 секунд аудио в секунду означает, что аудио длиной в 5 секунд будет сгенерировано примерно за 100 ms.

V1 модель V1 модель V3 модель V3 модель
1 поток 4 потока 1 поток 4 потока
8 kHz 1.9 4.2 15 — 25 30 — 60
16 kHz 1.4 3.1 - -
24 kHz - - 10 15 — 20
48 kHz - - 5 10

Так как на CPU задержка и скорость напрямую зависят от длины генерируемого аудио, новые цифры указаны в виде интервалов. Скорость выходит на плато примерно на длительности аудио в 5 секунд. Задержка, понятно, линейно зависит от длины генерируемого аудио.

Тут интересно также посмотреть на задержку — её легко посчитать в уме, просто поделив нужную длину аудио на скорость. По ряду технических причин, наши модели теперь не принимают списки текстов и не работают с батчами.

В ближайшем будущем мы уже планируем (и самое главное — знаем как) ускорить модель еще в 2-5 раз. Также вышло снизить размер модели в 2 раза, но мы особо этим не занимались целенаправленно. Пока есть определенные проблемы с квантизацией и конвертацией в ONNX, но в теории минимальный возможный размер модели находится в районе 5-10 мегабайт. Вы всегда можете помочь нам профинансировать соответствующие исследования.

Пробуем разные высококачественные голоса

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

В этот раз мы готовы представить 4 высококачественных голоса, послушать можно по ссылке:

Для добавления нового голоса xenia нам потребовалось записать всего лишь 2 часа аудио, и это не предел.

Спикер явным образом указывается при вызове модели:

...
speaker = 'xenia'  # 'aidar', 'baya', 'kseniya', 'xenia', 'random'
...
audio = model.apply_tts(text=example_text,
                        speaker=speaker,
                        sample_rate=sample_rate)

Синтезируем аудио разного качества

Мы можем синтезировать аудио с частотой дискретизации на выбор: 8, 24 или 48 килогерц. Предсказуемо, скорость работы моделей линейно меняется в зависимости от этого параметра.

Частота дискретизации тоже явным образом указывается при вызове модели:

...
sample_rate = 48000  # 8000, 24000, 48000
...
audio = model.apply_tts(text=example_text,
                        speaker=speaker,
                        sample_rate=sample_rate)

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

Управляем речью и генерируем целые абзацы текста с помощью SSML

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

Тег Пример тега Возможные значения Комментарий
Пауза <break time="2000ms"/> 5s, 500ms Целое число секунд или миллисекунд
Скорость речи <prosody rate="x-fast"> … </prosody> x-slow, slow, medium, fast, x-fast rate и pitch можно комбинировать
Высота речи <prosody pitch="x-high"> … </prosody> x-low, low, medium, high, x-high, robot rate и pitch можно комбинировать
Предложение <s> … </s> - Эквивалентен точке
Абзац <p> … </p> - Эквивалентен длинной паузе

Более подробную документацию по тегам можно найти тут.

Основные теги на примерах:

Пример работы с SSML тегами можно увидеть ниже:

ssml_sample = """
              <speak>
              <p>
                  Когда я просыпаюсь, <prosody rate="x-slow">я говорю довольно медленно</prosody>.
                  Потом я начинаю говорить своим обычным голосом,
                  <prosody pitch="x-high"> а могу говорить тоном выше </prosody>,
                  или <prosody pitch="x-low">наоборот, ниже</prosody>.
                  Потом, если повезет – <prosody rate="fast">я могу говорить и довольно быстро.</prosody>
                  А еще я умею делать паузы любой длины, например две секунды <break time="2000ms"/>.
                  <p>
                    Также я умею делать паузы между параграфами.
                  </p>
                  <p>
                    <s>И также я умею делать паузы между предложениями</s>
                    <s>Вот например как сейчас</s>
                  </p>
              </p>
              </speak>
              """

sample_rate = 48000
speaker = 'xenia'              
audio = model.apply_tts(ssml_text=ssml_sample,
                        speaker=speaker,
                        sample_rate=sample_rate)

Управляем ударением

Мы добавили возможность авторасстановки ударений ещё в прошлой версии, но в новом релизе стало доступно явно управлять флагами ударения и простановки буквы ё:

  • put_accent — флаг автоматической простановки ударения;
  • put_yo — флаг автоматической простановки буквы ё;

Вручную ударение, как и раньше, можно проставлять с помощью символа +.

Вот примеры — нет ударения вовсе, автоматическое ударение, автоматическое ударение + пара правок:

Пример управления ударением:

ssml_sample = """
<speak>
  В недрах тундры выдры в гетрах тырят в ведрах ядра к+едров!
  Выдрав с выдры в тундре гетры, вытру выдрой ядра к+едра.
  Вытру гетрой выдре морду, +ядра - в в+ёдра, выдру в тундру.
</speak>
"""

sample_rate = 48000
speaker = 'aidar'              

audio = model.apply_tts(ssml_text=ssml_sample,
                        speaker=speaker,
                        sample_rate=sample_rate,
                        put_accent=True,
                        put_yo=True)

display(Audio(audio, rate=sample_rate))      

Единственная загвоздка состоит в том, что мы смогли добиться точности только в 80% в простановке ударения на омографах, и поэтому новая версия модели не вошла в этот релиз. Наша цель — точность на уровне 90-95%. Также в следующей версии мы увеличим словарь словоформ до 4 миллионов штук.

Дополнительные прикольные возможности

Среди дополнительных фишечек есть:

  • Возможность говорить "как робот" (с помощью тега prosody с pitch="robot");
  • Возможность генерации и сохранения бесконечного количества "случайных" спикеров;
  • Возможность клонировать интонацию некой "модельной" фразы (в непубличной версии модели);

Пример генерации, сохранения и загрузки случайного спикера:

sample_rate = 48000
speaker = 'random'              
audio = model.apply_tts(ssml_text=ssml_sample,
                        speaker=speaker,
                        sample_rate=sample_rate)

model.save_random_voice('test_voice.pt') 

audio = model.apply_tts(ssml_text=ssml_sample,
                        speaker=speaker,
                        voice_path='test_voice.pt')

Также можно послушать как работает перенос интонаций на известных и неизвестных спикерах:

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

Типичные проблемы публичных решений и индустрии

Часто после какой-то очередной пиар акции очередного инвестиционного стартапа, мне пишут люди, мол смотрите какие классные вещи люди делают.

На практике оказывается, что кто-то просто скопировал код самой модной статьи, прикрутил к нему CLI и теперь люди могут по-настоящему делать качественные, быстрые и демократичные модели!

В реальности такие решения долго тренируются, спроектированы на работу на карточках по типу RTX 3090 — A100 — V100 (то есть, имеющих более 16 GB VRAM) и уступают уже существующим решениям.

Вот недавно мы сравнивали новую модную модель VITS:

  • В статье авторы пишут про инференс только на картах по типу V100;
  • На практике на инфересе нужно более 16 GB VRAM для фраз нетривиальной длины (я не понимал зачем на инференсе такие карты до этого теста);
  • Скорость уступает более простым решениям;

Самое печальное, что зачастую такие статьи написаны таким образом, чтобы нельзя было понять, какие элементы моделей на самом деле "тащат". Отчасти поэтому новые релизы занимают столько времени.

image

Max VRAM, MB
VITS 16,301
Fast Pitch 3,215

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

Дальнейшие планы

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

Мы гордимся нашей командой и тем, что мы сделали по-настоящему уникальный продукт.

Мы верим, что только так мы все вместе можем бороться с игом корпораций, особенно иностранных.

Именно по синтезу, дальше мы планируем:

  • Ускорить наш синтез еще в 2-5 раз;
  • Прикрутить квантизацию и ONNX и тем самым возможно ускорить синтез еще в 2-4 раза;
  • Добавить возможность использовать фонемы напрямую для синтеза для произношения сложных слов и аббревиатур;
  • Довести до конца работу по автоматической простановке ударения в предложениях с омографами и достичь точности в 90-95% на омографах;
  • Обновить модели для имеющихся у нас языков СНГ (если вы хотите записать какие-то новые — добро пожаловать), включая украинский;
  • Обновить модели для английского и основных европейских языков (мы пока не решили каких именно);
  • Сделать модель для индийских языков;
  • И есть еще пара секретных фановых мини проектов, о которых я не буду вам рассказывать =);
  • Нам и так потребовалась буквально пара часов для добавления нового высококачественного голоса и мы уже можем генерировать бесконечные случайные голоса. Возможно мы снизим штатное количество аудио для добавления нового высококачественного голоса до нескольких минут вместе с возможностью использования фонем;

Автор: Alexander Veysov

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js