Skip to main content

TTS Homework

Created on November 22|Last edited on November 24

FastSpeech: vanilla version

Воспроизводим архитектуру из статьи на основе семинарского кода:

Посмотрим по отдельности на каждый из блоков и sub-блоков.

Positional Encoding

В семинарском коде для positional encoding мы использовали обучаемый nn.Embedding, в качестве эксперимента можно попробовать более классический не-обучаемый подход с sin и cos (добавила в модель флажок для этого)

FFT Block

Изменения FFT Block:
  • самописные ScaledDotProductAttention и MultiHeadAttention были заменены на nn.MultiheadAttention из torch.
  • добавлен флажок use_flash_attention, если задать его как True, в форварде будет вызван внутренний _forward(...) из-под следующего контекстного менеджера:
with torch.backends.cuda.sdp_kernel(
enable_flash=True,
enable_math=True,
enable_mem_efficient=True
):


Length Regulator, Duration Predictor

Сама идея: phoneme durations мы получаем из авторегресионной модели (из tacotron), затем будем дублировать фонемы (их hidden-ы) столько раз, сколько предскажет duration predictor; при этом коэффициент α\alpha позволяет нам регулировать скорость речи спикера.
Единственное важное замечание: в Length Regulator предсказанные длины, умноженные на коэффициент α\alpha, нужно было перевести в int с математическим округлением, поэтому перед кастом к инту я прибавила к значениям 0.5.

Что получилось (не получилось)

Я провела несколько тестовых ранов с разными п��раметрами у лосса (MSE как в оригинальной статье и L1 как в коде с семинара), оказалось, что по какой-то причине плохо учится duration predictor. Я предположила, что дело в том, что я предсказываю логарифмы длительностей (как в статье), а в семинарском коде предсказывали обычные длительности, но замена логарифмов на обычные значения починить предиктор не помогла.
(Раны подписаны по тому, какой ран использовался и что именно из duration я предсказывала; неподписанный ран и ран fast-speech-one-batch-unfinished – это тестовые раны на маленьких данных)



FastSpeech2

Тут тоже пойдём прямо по статье и по отдельным модулям:


Variance Adaptor

Идейно тут всё просто: поочередно предсказываем длительности, pitch и энергию, потом складываем все эмбеддинги с hidden-ами фонем и возвращаем их, при этом длительности можем предсказывать прямо в Length Predictor, взятом из первого Fast Speech. Тонкости реализации относятся к предикторам, так что подробнее посмотрим на них

Predictors

Структура всех предикторов одинаковая и показана на картинке, поэтому опишу только особенности каждого из них.
Duration Predictor: по hidden-представлениям для фонем возвращаем логарифмы длительностей
Pitch Predictor: в последней версии статьи используется CWT (continious wavelet transform) и iCWT, меня, к сожалению, на это не хватило
Energy Predictor: измеряем L2-норму амплитуды каждой спектрограммы через STFT, эта L2-норма будет считаться энергией. Далее энергию пытаемся квантизовать, превратить в эмбеддинги и затем прибавить к hidden-представлениям фонем


Выводы

Получилось бы очень круто и интересно, если бы модель нормально завелась. В итоге я три дня провозилась с шаблоном и попытками пофиксить маленькие баги, поэтому времени на тесты со вторым Fast Speech не осталось :(