やってみた!

やってみた!

試したことを中心に、書評や興味のあること、思ったこととか

音声合成を試す1 Tacotron2 + WaveGlow

 ディープラーニングによって音声合成も目覚ましく進歩しているようです。
 2019年4月に発表されたマイクロソフトAIりんなの歌の完成度は非常に高く、人と区別つきません。まだ、誰もが使える技術ではありませんが、いつかは誰もがつかえるようになるでしょう。

www.youtube.com

 とりあえず、試せる範囲で音声合成技術に触れてみたいと思います。

1.Text to speechの概要

 テキストから音声への変換はText to speechと呼びます。ここではTacotron2 + WaveglowのNVIDIA実装を使ってみます。ソースのリンクはこちら。

github.com

Tacotron2
 2017年にGoogleが発表したTTSの手法。Tacotron2はテキストからメル スペクトログラム(mel-spectrogram)を生成します。
 論文のリンクはこちらです。

arxiv.org

Waveglow
 メル スペクトログラムから音声波形への変換を行います。この分野では高品質な音声出力で有名なWaveNetに比べかなりの軽量化がされているにもかかわらず、品質も良好とのこと。論文はこちら。

arxiv.org

 詳しくは後にして、まずはGoogle Colaboratoryで動かしてみましょう。

 手順はNVIDIAのサイトにあるREADME.md、inference.ipynbをベースにしています。そのままでは動かなかったので一部変更しました。今後も、Colaboratory、Tacotron2、WaveGlowが更新されるとエラーが出るようになるかも知れません・・・。

2.Googleドライブに学習済みデータをアップロードする

(1)Googleドライブのトップにtacotron2フォルダを作成します。

(2)パソコンに次をダウンロードします。

・tacotron2学習済みweights tacotron2_statedict.pt 約108MByte
https://drive.google.com/file/d/1c5ZTuT7J08wLUoVZ2KkUs_VdZuJ86ZqA/view?usp=sharing

・WaveGlow学習済みweights waveglow_256channels_ljs_v3.pt 約644MByte
https://ngc.nvidia.com/catalog/models/nvidia:waveglow_ljs_256channels

(3)上記2つのファイルをGoogleドライブのtacotron2フォルダにアップロードします(ドラッグ&ドロップ)。やや時間がかかります。

(4)Googleドライブで右クリックして新規Colaboratoryを開きます。

(5)ランタイム-ランタイムのタイプを変更でハードウェアアクセラレータをGPUにします。

3.Gitダウンロード

 今回はソースファイルをGoogleドライブに置かないで毎回Gitからダウンロードすることにしました。

(1)tacotron2

!git clone https://github.com/NVIDIA/tacotron2.git

(2)submodule(waveglowなど)導入
waveglowを最新版にしないと後でdenoiserが無いというエラーが出るので、--remote --mergeで最新版に更新しています。

%cd /content/tacotron2
!git submodule init
!git submodule update --remote --merge

4.Apexインストール

!git clone https://github.com/NVIDIA/apex
%cd apex
!pip install -v --no-cache-dir ./
%cd ..

5.各種パッケージインストール

(1)パッケージインストール

 とりあえず、以下の組み合わせで動きました。

%cd /content/tacotron2
!pip install matplotlib==3.0.0
!pip install tensorflow
!pip install inflect==0.2.5
!pip install librosa==0.6.0
!pip install scipy==1.0.0
!pip install tensorboardX==1.8
!pip install Unidecode==1.0.22
!pip install pillow
!pip install torch==1.0
!pip install torchvision==0.3.0

(2)ランタイム再起動
 ランタイムーランタイムを再起動で再起動します。ファイル等には影響ありません。

6.学習データをコピー

 2.項でGoogleドライブのtacotron2フォルダにアップロードした学習済みweightsをColaboratoryのディスクにコピーします。

(1)Googleドライブ接続

from google.colab import drive
drive.mount('/content/drive')

(2)学習データコピー

!cp /content/drive/My\ Drive/tacotron2/tacotron2_statedict.pt /content/tacotron2/
!cp /content/drive/My\ Drive/tacotron2/waveglow_256channels_ljs_v3.pt /content/tacotron2/

 7.実行します

(1)ディレクト

%cd /content/tacotron2

(2)ライブラリのインポート

import matplotlib
%matplotlib inline
import matplotlib.pylab as plt

import IPython.display as ipd

import sys
sys.path.append('waveglow/')
import numpy as np
import torch

from hparams import create_hparams
from model import Tacotron2
from layers import TacotronSTFT, STFT
from audio_processing import griffin_lim
from train import load_model
from text import text_to_sequence
from denoiser import Denoiser

(3)plot_data関数

def plot_data(data, figsize=(16, 4)):
    fig, axes = plt.subplots(1, len(data), figsize=figsize)
    for i in range(len(data)):
        axes[i].imshow(data[i], aspect='auto', origin='bottom', 
                       interpolation='none')

(4)Setup hparams設定 サンプリングレート 22.05k

hparams = create_hparams()
hparams.sampling_rate = 22050

(5)Load model tacotron2

checkpoint_path = "tacotron2_statedict.pt"
model = load_model(hparams)
model.load_state_dict(torch.load(checkpoint_path)['state_dict'])
_ = model.cuda().eval().half()

(6)Load WaveGlow for mel2audio synthesis and denoiser

#waveglow_path = 'waveglow_256channels.pt'
waveglow_path = 'waveglow_256channels_ljs_v3.pt'
waveglow = torch.load(waveglow_path)['model']
waveglow = waveglow.remove_weightnorm(waveglow)
waveglow.cuda().eval().half()
for k in waveglow.convinv:
    k.float()
denoiser = Denoiser(waveglow).cuda()

(7)Prepare text input

text = "Waveglow is really awesome!"
sequence = np.array(text_to_sequence(text, ['english_cleaners']))[None, :]
sequence = torch.autograd.Variable(
    torch.from_numpy(sequence)).cuda().long()

(8)Decode text input and plot results メルスペクトログラムを生成します

mel_outputs, mel_outputs_postnet, _, alignments = model.inference(sequence)
plot_data((mel_outputs.float().data.cpu().numpy()[0],
           mel_outputs_postnet.float().data.cpu().numpy()[0],
           alignments.float().data.cpu().numpy()[0].T))

 生成されたメル スペクトログラムが表示されます。左側がpost-processing無し、真ん中がpost-processing後(最終出力)です。この図ではあまり違いは良くわかりません。

f:id:akifukka:20191109150303j:plain

(9)Synthesize audio from spectrogram using WaveGlow メルスペクトログラムから音声波形を生成します

with torch.no_grad():
    audio = waveglow.infer(mel_outputs_postnet, sigma=0.666)
ipd.Audio(audio[0].data.cpu().numpy(), rate=hparams.sampling_rate)


再生すると音声が出ます ”Waveglow is really awesome!"

f:id:akifukka:20191109160333j:plain
 ここまでのノートブックを貼っておきます。

https://drive.google.com/file/d/1UPdfws9DJqrp-HYa7TOHmORplJUiuHYV/view?usp=sharing

 

つづく

音声合成 カテゴリーの記事一覧へ