논문제목: Deep Voice: Real-time Neural Text-to-Speech
저자: Sercan O Arık, Mike Chrzanowski, Adam Coates, Gregory Diamos, Andrew Gibiansky, Yongguo Kang, Xian Li, John Miller, Andrew Ng, Jonathan Raiman, Shubho Sengupta, Mohammad Shoeybi
소속: Baidu Research
논문: https://arxiv.org/abs/1702.07825
발표: ICML 2017
- Deep Voice 첫번째 버전
- TTS에서 구성성분을 5개의 블럭으로 구성하고 각각을 모두 NN으로 구현함. 여기서 phoneme boundary segmentation과audio synthesis 부분에 새로운 내용이 있음.
- 오디오 합성은 WaveNet[Oord16]을 수정하여 사용. 속도를 빠르게 하기 위하여 온갖 최적화 구현을 이용하여 오디오 생성 속도를 리얼타임 수준으로 올림
- 사실 결과 MOS는 별로임. 하지만 온갖 구현 노가다 및 5가지 부분을 모두 NN로 구현한 end-to-end 시스템을 제안했다는 것에 의미가 있음.
Story
TTS시스템 만드는 것은 어려움. 지금까지 개발된 일반적인 파이프라인을 따르면서도 각 모듈들을 모두 neural network으로 바꾸어보면 어떨까? 이전 연구들을 보니 모듈 하나 둘정도는 neural network을 쓰기는 하는데 전부다 쓰는 건 없었음. 이렇게 만들고 데이터셋만 바꿔서 다시 훈련하면 어떻게 되는지 한번 실험해봄. 또한 WaveNet[Oord16]이 좋긴 한데 느림. 이걸 최적화 구현의 힘으로 빨리만들어보겠음.
TTS System Components
전체 시스템은 5개의 블럭으로 구성: phoneme boundary segmentation model, grapheme-to-phoneme conversion model, phoneme duration prediction model, fundamental frequency prediction model, audio synthesis model.
1) Grapheme-to-Phoneme Model
english characters를 phonemes로 바꾸는 모델. GRU를 사용한 encoder-decoder모델을 이용. teacher forcing 방법으로 훈련하고, beam search(width = 5)을 사용해 디코딩됨.
2) Segmentation Model
phoneme boundary를 찾는 모델. CRNN에 CTC(connectionist temporal classification) 로스를 이용. 멜에 convolution + GRU를 사용. 그런데 하나의 phoneme을 예측하는 것이 아니라 phoneme pair를 예측하게 하면 두 phoneme사이의 boundary를 예측하게 하는 효과를 줄 수 있음.
3) Phoneme Duration Model & Fundamental Frequency Model
Phoneme Duration Model은 Phoneme sequence에서 각 phoneme의 길이를 예측하는 모델. Fundamental Frequency Model은 Phoneme이 voiced인지 아닌지 예측하고, 만일 그렇다면 $F_0$을 예측하는 모델. 하나의 네트워크로 두 가지를 예측하게 함. GRU + FC를 이용하는데, 아웃풋은 3가지(phoneme duration + voiced인지 아닌지 + duration 안에서 구한 $F_0$).
4) Audio Synthesis Model
각 모델을 더하여 최종 오디오를 만들어내는 모델. 원본 WaveNet에서는 업샘플링에 transposed convolution을 사용한데 반해 여기서는 bidirectional quasi-RNN 레이어[Bradbury16]을 썼는데 이게 더 좋았음. 속도 빨리하게 하는 것은 좀 더 아랫부분에 다시 설명.
Results
내부 영어 데이터(20시간)로 훈련. Blizzard 2013 데이터도 이용했음.
Segmentation Results: 14K정도에 수렴. phoneme boundary는 아주 정확하지 않아도 별 차이가 없었음.
Grapheme-to-Phoneme Results: CMUDict모델을 이용해 훈련. 20K정도에 끝남.
Phoneme Duration and Fundamental Frequency Results: 20K정도에 끝.
Audio Synthesis Results: 오디오를 1초 청크로 자르고 1/4초 silence를 더함. 20레이어 정도의 receptive field도 충분했음. 300K정도 훈련.
AMT로 MOS를 진행한 결과는 다음과 같음
일단 원본 오디오를 48kHz에서 16kHz로 다운샘플링하니 점수가 덜어짐. 뮤-law companding이랑 quantization하니 더 떨어졌음. 다음으로 이제 이 시스템으로 만든 오디오에 대한 실험인데, 먼저 인풋으로 GT duration과 $F_0$ 정보를 주고 합성하게 하니 3.94정도가 나왔음. 그다음에 계산한 $F_0$을 넣었더니 2.76, 계산한 Duration까지 넣었더니 2.00이 나왔음. 즉 TTS의 발전을 가장 크게 저해하고 있는 것이 duration가 $F_0$ 계산의 부정확성인 것 같음. 아직 여기에 대해서는 이 논문에서는 별다른 진전이 없었음. 또한 스피드를 높이는 방법을 사용하니 역시나 tradeoff가 있었음.
동일한 아키텍쳐와 파라미터로 Blizzard 2013 데이터셋에 대해서 다시 훈련을 했음. 이 데이터의 companded and expanded audio(16kHz)는 4.65, 여기서 합성한 오디오는 2.67의 값을 얻었음.
Optimizing Inference
CPU와 GPU에서 inference kernel의 최적화를 했는데 WaveNet 인퍼런스가 리얼타임보다 빠르게 만들 수가 있었음.
사용한 CPU는 Intel Xeon E5-2660 v3 Haswell (2.6GHz)이고 GPU는 GTX Titan X Maxwell GPU.
최적화 방법은 모든 recomputation을 피하고, cache를 최대한 쓰도록 하고, 멀티스래딩을 사용하고, nonlinearity FLOPs을 최소화하고, cache trashing이나 thread contention을 피하고, matrix multiplication과 convolution에서 hardware-optimized 루틴을 사용함. 열심히 했음. 논문에도 세세하게 설명을 하고 있음.
재미있는 것은 GPU에서 성능이 더 안나왔다는 것. CUDA kernel launch할때 시간이 많이 걸려 한번 launch에서 모든 샘플을 생성하게 했지만 여러가지 현실적인 제약때문에 코딩이 너무 힘들었다고 하며 최대한 노력한 것이 저 정도라고 적고 있음.
이때(2017년) 당시 옹이 이끌던 바이두에서 만든 최신식 TTS.
이후 TTS 시스템의 발전 방향을 보면 재미있음.
- [Bradbury16] Bradbury, James, Merity, Stephen, Xiong, Caiming, and Socher, Richard. Quasi-recurrent neural networks. arXiv preprint arXiv:1611.01576, 2016.
- [Oord16] A.van den Oord, S.Dieleman, H.Zen, K.Simonyan, O.Vinyals, A.Graves, N.Kalchbrenner, A.Senior, K.Kavukcuoglu. WaveNet: A generative model for raw audio. arXiv preprint arXiv:1609.03499, 2016. [논문리뷰]