近日,浙江大學和微軟亞洲研究院聯合推出了一篇論文,關於快速的端到端的語音合成系統,論文的鏈接如下:

FastSpeech: Fast, Robust and Controllable Text to Speech?

arxiv.org

下面是筆者閱讀論文後對論文方法的總結和思考,不當之處歡迎指正。

論文首先指出了端到端自回歸(Auto Regressive)的語音合成系統存在的問題:

  1. 推理階段速度過慢(traditional Transformer雖然訓練的速度很快,但是推理階段仍然需要上一時間步的輸出,無法做到真正的並行);
  2. 生成的語音不是魯棒的,有一些單詞會被跳過或者重複地生成(這一點筆者在實驗的時候真的是深有體會啊,而造成這一原因主要是因為傳統語音合成系統的Alignment是隱式的,在推斷的過程中,存在著錯誤對齊的情況);
  3. 無法做到可控(這裡筆者的可控應該主要指的是生成的語速方面,因為在Prosody的層面已經有工作做到了很好的效果)。

於是論文針對上述三個問題,基於Transformer,重新設計了模型。模型的示意圖如下:

圖一

首先,為了加速推斷的速度,論文採用了non auto-regressive的seq-to-seq模型(如圖一的(a)),不需要依賴上一個時間步的輸入,可以讓整個模型真正的並行化。論文中non auto-regressive的seq-to-seq模型的設計方法類似於論文Non-Autoregressive Neural Machine Translation。

圖二 論文Non-Autoregressive Neural Machine Translation結構圖示

text(phoneme)首先經過Encoder得到Encoder Output,由於phoneme的長度往往小於梅爾聲譜圖的長度,為了適應Decoder的Input的長度,模型在這裡有一個Length Regulator,這裡,把Encoder Output進行智能化的填充,使之長度等於梅爾聲譜圖的長度,讓填充過的Encoder Output直接作為Decoder的Input輸入Decoder。值得注意的是,論文作者用1D Conv代替了Transformer中的全連接網路(如圖一(b)),並闡明瞭原因

The motivation is that the adjacent hidden states are more closely related in the character/phoneme and mel-spectrogram sequence in speech tasks.

隨後,論文詳細地介紹了Length Regulator的設計方法(如圖一(c))。Length Regulator的作用是將Encoder Output智能地填充到與Mel Spectrogram一致的長度,Encoder Output先進入Duration Predictor,Duration Predictor根據Encoder Output輸出一組數字,如[2,3,1,2,3],然後Length Regulator將Encoder Output的第一個向量複製1次,第二個向量複製三次,第三個不複製,第四個複製1次,最後一個複製2次,這樣,2+3+1+2+3=11等於目標梅爾聲譜圖的長度。

Duration Predictor(如圖一(d))負責根據Encoder Output預測出每個向量對應需要複製的次數。這裡,作者為了改變傳統seq-to-seq模型隱式的Alignment,加入了顯式的Alignment的標籤(如圖一最右側),該標籤由Transformer-TTS(可參見筆者的另一篇博文基於Transformer的語音合成系統)的Attention部分提供。因為Transformer是Multi-Head,論文作者制定了標準,選擇了一個Head用作Alignment,Duration Extractor這一部件用於從此Head的Attention Matrix中提取目標。Duration Predictor的預測結果與目標做MSELoss,在整個訓練過程進行反向傳播。

這一部分具體地闡述了Duration Predictor和Extractor的設計

至此,論文已經解決了之前提到了兩個問題。至於最後一個Controllability,只需要對Duration Predictor的預測結果進行人為幹預,即可做到控制合成語音的語速快慢。

論文作者的實驗充分驗證了上述設計的有效性,首先是合成速度有了巨大地提高:

其次,魯棒性也有了較大地提升:

總的來說,這篇論文是一個非常好的工作,提出了一種有效地加快合成速度的方法,並提高了合成的準確性,因為模型結構的紅利,該模型還可以對合成聲音的語速進行控制。但是也存在問題,模型使用了Transformer-TTS的Alignment作為Target,而Transformer-TTS的Alignment是隱式的,也就是說,模型將隱式的Alignment作為顯式的Alignment的Target。


今天(2019-5-29)發現百度也出了一篇non auto-regressive TTS的model:

Parallel Neural Text-to-Speech?

arxiv.org

粗略看了一下論文,整體架構基於DeepVoice3,Decoder Input使用Position Embedding代替,個人覺得這種方式過於人工。模型的整體架構如圖:

論文還提出了一個並行化的Vocoder,取名WaveVAE。


復現筆記參見:

星辰漫遊者:FastSpeech復現筆記?

zhuanlan.zhihu.com
圖標

class FastSpeech(nn.Module):
""" FastSpeech """

def __init__(self):
super(FastSpeech, self).__init__()

self.encoder = Encoder()
self.length_regulator = LengthRegulator()
self.decoder = Decoder()

self.mel_linear = Linear(hp.decoder_output_size, hp.num_mels)
self.postnet = PostNet()

def forward(self, src_seq, src_pos, mel_max_length=None, length_target=None, alpha=1.0):
encoder_output, encoder_mask = self.encoder(src_seq, src_pos)

if self.training:
length_regulator_output, decoder_pos, duration_predictor_output = self.length_regulator(
encoder_output,
encoder_mask,
length_target,
alpha,
mel_max_length)
decoder_output = self.decoder(length_regulator_output, decoder_pos)

mel_output = self.mel_linear(decoder_output)
mel_output_postnet = self.postnet(mel_output) + mel_output

return mel_output, mel_output_postnet, duration_predictor_output
else:
length_regulator_output, decoder_pos = self.length_regulator(
encoder_output, encoder_mask, alpha=alpha)

decoder_output = self.decoder(length_regulator_output, decoder_pos)

mel_output = self.mel_linear(decoder_output)
mel_output_postnet = self.postnet(mel_output) + mel_output

return mel_output, mel_output_postnet

推薦閱讀:

相關文章