Tacotron2を日本語で学習してみる(0から学習編)

はじめに

NVIDIA社が公開しているTacotron2は英語モデルです。

そのため、今回は自分でTacotron2の日本語モデルを作ってみようと思いました。

ちなみに、先に言ってしまうと今回の設定は上手く行きませんでした。上手くいったパターンは次回の記事「Tacotron2を日本語で学習してみる(転移学習編)」で記述するつもりです。

Tacotron2とは

Tacotron2に関する説明は以下で行っています。

shirowanisan.com

使用する日本語音声データセット 

以下の音声データセットで日本語のTacotron2を作成してみようと思います。

www.kaggle.com

これは、夏目漱石の明暗を朗読したデータセットで、6841個のwavファイルで構成されています。音声データの中身を、例として載せておきます。

学習のためのfilelistの作成

tacotron2で学習するためにはwavファイルとテキストの対応を示すfilelistを作る必要があります。そのため、データセットに含まれていたtextからtacotron2用のfilelistを作成しました。

before(データセットに含まれていたtext)

meian/meian_0000.wav|この前探った時は、途中に瘢痕の隆起があったので、ついそこが行きどまりだとばかり思って、ああ云ったんですが、|kono mae sagut ta toki wa 、 tochu- ni hankon no ryu-ki ga at ta node 、 tsui soko ga yukidomari da to bakari omot te 、 a- yut ta n desu ga 、|8.77
meian/meian_0001.wav|今日疎通を好くするために、そいつをがりがり掻き落して見ると、まだ奥があるんです」|kyo- sotsu- wo yoku suru tame ni 、 soitsu wo garigari kaki otoshi te miru to 、 mada oku ga aru n desu|7.48

after(tacotron2用に変えたもの)

meian/meian_0000.wav|konomaesaguttatokiwa,tochu-nihankonnoryu-kigaattanode,tsuisokogayukidomaridatobakariomotte,a-yuttandesuga,
meian/meian_0001.wav|kyo-sotsu-woyokusurutameni,soitsuwogarigarikakiotoshitemiruto,madaokugaarundesu

音素の変換は行わなくても学習できるかもしれませんが、私は以下のように一部音素を変換しました。

変換前 変換後
,
.
' n
―― <削除>
<削除>
<削除>
<半角空白> <削除>

データセットのサンプリングビット数の変換

データセットのwavファイルはサンプリングビットが32なのですが、このままでは上手く学習できなかったため、サンプリングビットを16に変換しました。サンプリングビットの変換方法については以下で説明しています。

shirowanisan.com

データセットの分割

データセットはtrainとvalを以下のように分割しました。

項目
train 6800
val 41

Tacotron2のハイパーパラメータの設定

日本語で学習するにあたり、以下のハイパーパラメータを変更しました。

text_cleanersは、今回はローマ字で音素を示すためbasic_cleanersに変更、

batch_sizeは、GPUのメモリが足りなかったので32にしました。

項目 デフォルト値 設定値
text_cleaners ['english_cleaners'] ['basic_cleaners']
batch_size 64 32

学習結果

trainのlossの結果です。0.325ぐらいで収束しています。

f:id:shirowanisan:20201205180229p:plain

valのlossの結果です。これも収束していそうです。

f:id:shirowanisan:20201205180446p:plain

音声生成

学習は上手くできていたように思えましたが、意外にも音声生成結果は散々なものでした。以下は「今日はいい天気ですね」で音声生成したときのメルスペクトグラムとアライメントです。アライメントはテキストとメルスペクトグラムの対応を示していますが、上手く対応付けできていないことがわかります。

原因はデータセット 、ハイパーパラメータと色々考えられますが、今回は細かく調査しないことにします。理由は、次に英語モデルを初期値とした転移学習を試した結果、そちらでは上手く音声生成できたからです。

f:id:shirowanisan:20201205180543p:plain

まとめ

日本語音声データセットを用いて、0からTacotron2を学習してみたのですが、データセット 、または、ハイパーパラメータの影響で上手く音声生成できませんでした。

しかし、この後に英語モデルを初期値とした転移学習では、上手く音声生成できました。これは次回の記事「Tacotron2を日本語で学習してみる(転移学習編)」で記述していこうと思います。

参考文献

Tacotron2で始める日本語音声合成 - Qiita

Tacotron2系における日本語のunidecodeの不確かさ - Qiita

pythonでwavファイルのサンプリングビット数(量子化ビット数)を変換する

はじめに

pythonでwavファイルのサンプリングビット数(量子化ビット数)を変換します。

簡単にできるかと思いきや、調べてもあまり見つからなかったので自分でもまとめておきます。

やり方

PySoundFileライブラリで実現できるようなので、インストールします。

PySoundFile — PySoundFile 0.9.0 documentation

$ pip install pysoundfile

以下が実際のpythonのコードです。wavファイルを読み込み、サンプリングビット数をsubtypeで指定して書き込み。これで完了です。読み込み時のwavファイルは16, 24, 32bitのどれでも16bitとして書き込みできそうです。私は「32bit読み込み → 16bit書き込み」しか試していません。

import soundfile

data, fs = soundfile.read('input.wav')
soundfile.write('output.wav', data, fs, subtype='PCM_16')

指定できるサンプリングビット数は以下のようです。32bitはないんですね。読み込み時は32bitのwavファイルでも問題なく読み込めました。

subtype 説明
PCM_24 Signed 24 bit PCM
PCM_16 Signed 16 bit PCM
PCM_S8 Signed 8 bit PCM

参考文献

python - python3で24ビットのwavファイルを16または32ビットのファイルに変換する方法 - ITツールウェブ

NVIDIAのTacotron2モデルを再現してみた

Tacotron2とは

Tacotron2に関しては以下の記事で説明しています。

shirowanisan.com

目的

  • NVIDIA/tacotron2ソースコードの説明に従いモデルを作成し、NVIDIA提供モデルと同じモデルが作れるのかを明らかにする。
  • Tacotron2のクオリティに必要な学習数を明らかにする。

github.com

データセット 

NVIDIA提供モデルで使用していたデータセットはLJ Speech datasetという、英語のスピーチを13100個のwavファイルで提供しているものです。以下からダウンロード可能です。

keithito.com

 

サンプルデータとして1つ載せておきます。

"Printing, in the only sense with which we are at present concerned, differs from most if not from all the arts and crafts represented in the Exhibition"

 

NVIDIA/tacotron2では以下の割合でデータセットをtrain、val、testに分割しています。

分割 サンプル点数
train 12500
val 100
test 500

今回は学習のみ行うため、trainとvalのみ使用します。

ハイパーパラメータ

NVIDIA/tacotron2のハイパーパラメータはhprams.pyで管理されています。今回は何も修正せずに学習してみます。

https://github.com/NVIDIA/tacotron2/blob/master/hparams.py

step数とepoch数について

NVIDIA/tacotron2ではstep数とepoch数は以下のように扱われています。設定ではepoch数のみ指定し、step数はepoch数から決まります。

項目 説明
step

重みの更新を行った回数。

デフォルトのbach_size=64の場合、64サンプル点ごとに重みを更新するため、

1stepは64サンプル分学習する。

epoch

trainサンプルを何周したか。

trainサンプル点数12500でbach_size=64の場合は、

約195stepでtrainサンプルを一周するため、1epochは約195stepとなる。

デフォルトの設定では500epochでstep数は約97500stepとなります。

500epochの学習時間は、GPU RTX3090でだいたい3日〜4日くらいです。

学習結果

trainingとvalidationのlossを確認してみます。横軸がstep、縦軸がlossです。

グラフを確認すると、lossは約0.3あたりで減少しなくなっているように見えます。そのため、50k step(256epoch)程度で十分学習しているように思えます。

f:id:shirowanisan:20201122162559p:plain

f:id:shirowanisan:20201122162612p:plain

各stepの生成音声を確認してみる

各stepのモデルでテキストから音声生成を行い、クオリティを確認します。

読み上げるテキストは「くまのプーさん」の原作「Winnie-the-Pooh」の以下の一節にします。

 

"Here is Edward Bear, coming downstairs now, bump, bump, bump, on the back of his head, behind Christopher Robin."

 

各stepモデルでの生成音声、メルスペクトグラム、アライメントを載せます。アライメントはテキストとメルスペクトグラムの対応を示しています。アライメントが綺麗な右肩上がりになっている場合は、対応が問題なく行われていることが確認できます。

 

step 10k

f:id:shirowanisan:20201122164625p:plain

 

step 20k

f:id:shirowanisan:20201122164647p:plain

 

step 30k

f:id:shirowanisan:20201122164703p:plain

 

step 50k

f:id:shirowanisan:20201122164725p:plain

 

step 90k

f:id:shirowanisan:20201122164738p:plain

 

NVIDIA提供モデル

f:id:shirowanisan:20201122164826p:plain

 

step 10kではアライメントが上手くできておらず、生成された音声も不安定です。

step 20k、30kあたりから生成音声としては問題なさそうですが、まだ安定していない印象もあります。

step 50kからはNVIDIA提供モデルとあまり差がなさそうです。

まとめ

  • NVIDIA/tacotron2ソースコードの説明に従いモデルを作成すると、NVIDIA提供のモデルとほぼ同じモデルが作れた
  • Tacotron2のクオリティに必要なstepは50k(256epoch)で十分そう。ただし、これはtrainデータセットのサンプル点数、batch_sizeに応じて変わる。

Ubuntu18.04のインストールからGPUで機械学習をするまで

目次

f:id:shirowanisan:20201113223013p:plain

UbuntuのインストールからGPUで機械学習をするまでに必要なことを記述します。流れは以下となっています。

  1. WindowsでUbuntuインストールUSBメディアを作成
  2. Ubuntuのインストール・初期設定
  3. 機械学習のためのGPUドライバ・CUDA・cuDNNの設定
  4. pyenvによるpythonのインストール
  5. 機械学習モデルの実行
  6. おまけ:Ubuntuにリモート接続

WindowsでUbuntuインストールUSBメディアを作成

Ubuntu18.04のダウンロード

下記よりUbuntu18.04 LTSをダウンロードします。

Ubuntu Desktop 日本語 Remixのダウンロード | Ubuntu Japanese Team

f:id:shirowanisan:20201109201900p:plain

インストールUSBメディアを作成するためのソフトウェアをダウンロード

下記よりソフトウェア「Rufus」をダウンロード、インストールします。

rufus.ie

Rufusを使ってインストールUSBメディアを作成する

Rufusを起動し、画像のようにUbuntuのイメージを選択してインストールUSBメディアを作成します。

f:id:shirowanisan:20201109223549p:plain

Ubuntuのインストール

USBメディアからUbuntuをインストール

USBメディアからUbuntuを起動し、手続きにしたがってUbuntuをインストールします。

Ubuntuの解像度がおかしいときの対応

Ubuntuの解像度がおかしくない場合はこちらの手順は省略して大丈夫です。

GPU等の関係により、画像のようにUbuntuの解像度が600x800で固定され、GPUドライバをインストールしても解決しない場合があります。その場合の対処方を記述します。

f:id:shirowanisan:20201110214038p:plain

まずは、システムファイルを修正できるようにvimをインストールします。

$ sudo apt install vim

続いてgrubファイルを編集します。

$ sudo vim /etc/default/grub

以下の行を追加します。

GRUB_GFXMODE=1920x1080

f:id:shirowanisan:20201110220633p:plain

最後に、grubを更新して再起動します。

$ sudo update-grub
$ sudo reboot

Ubuntuのソフトウェアアップデート

画像のように選択し、Ubuntuのソフトウェアをアップデートします。

f:id:shirowanisan:20201110221502p:plain

f:id:shirowanisan:20201110221601p:plain

インストール後、再起動が必要です。

再起動後、ついでにパッケージリストとパッケージの更新も行っておきます。

$ sudo apt update
$ sudo apt upgrade

機械学習のためのGPUドライバ・CUDA・cuDNNの設定

機械学習のために必要なもの

GPUで機械学習するために以下をインストールします。

  1. GPUドライバ(GPUの機能を使うために必要。)
  2. CUDA Toolkit(GPUで機械学習をするために必要。)
  3. cuDNN(ニューラルネットワークの計算を高速化するために必要。高速化が目的のため、インストールしなくても機械学習は可能。)

GPUドライバのインストール

以下のコマンドを入力して、適切なGPUドライバを確認します。

$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt update
$ ubuntu-drivers devices

recommendedが付いているドライバをインストールします。 

f:id:shirowanisan:20201110223157p:plain

インストール後、再起動します。

$ sudo apt install nvidia-455
$ sudo reboot

以下のコマンドでドライバがインストールされていることを確認できます。

$ nvidia-smi

CUDAのインストール

CUDAはGPUで機械学習するために必要です。

以下からCUDAをダウンロードします。基本的にCUDAのバージョンはnvidia-smiで表示されるバージョンが推奨です。ここではCUDA 11.1.1を選びます。

developer.nvidia.com

今回はrunfileでのインストールを選択します。

f:id:shirowanisan:20201111001138p:plain

上記で表示されたコマンドを打ち込みます。

$ wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda_11.1.1_455.32.00_linux.run
$ sudo sh cuda_11.1.1_455.32.00_linux.run

runfileを実行すると以下の表示がでます。

f:id:shirowanisan:20201111102745p:plain
「既にドライバーがインストールされているけど大丈夫?ドライバを削除してからインストールすることを強く勧めます。」
と表示されています。

これは、上記でインストールしたGPUドライバのことだと思われます。ただし、CUDAと同時にドライバをインストールする場合、GPUとそのドライバに互換性がない場合もあります。この場面の最適解は、ドライバのインストールもCUDAで行うことかもしれませんが、ここでは「Continue」で進めます。

ライセンス表示の場面では「accept」と入力します。

f:id:shirowanisan:20201111103326p:plain

続いて、今回は既にドライバを入れているため、Driverのチェックのみを外して「install」を選択します。(CUDAと同時にドライバをインストールする場合はチェックが必要です。)

f:id:shirowanisan:20201111103400p:plain

これでCUDAのインストールは完了です。

cuDNNのインストール

cuDNNはニューラルネットワークの計算を高速化するために必要です。高速化が目的のため、インストールしなくても機械学習は可能です。

cuDNNのダウンロードには、NVIDIAのアカウントとログインが必要です。また、ダウンロード時にアンケートに答える必要があります。

下記のサイトでダウンロードします。今回はCUDA11.1を選択します。

https://developer.nvidia.com/rdp/cudnn-download

f:id:shirowanisan:20201113175610p:plain

以下のコマンドでインストールします。

# 解答
$ tar -xzvf cudnn-11.1-linux-x64-v8.0.5.39.tgz

# ローカルのCUDAフォルダにコピー(インストール)
$ sudo cp cuda/include/cudnn*.h /usr/local/cuda/include
$ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64

# 読み取り権限付与
$ sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

pyenvによるpythonのインストール

pyenvとは

pyenvはpythonのバージョン管理ツールです。python3.7、python3.8といった別バージョンのpythonを簡単に切り替えたいときに使います。コードによってはpython3.7では動くがpython3.8では動かないということがあるため、そういった場面で役に立ちます。

pythonのバージョンは1つで十分という方はpyenvではなく、普通にpythonのインストールで問題ありません。

pyenvのインストール

pyenvに必要なパッケージをインストールします。 

$ sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git

gitでpyenvをダウンロードします。

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

.bash_profileにpyenvの設定を書きこみます。

$ vim ~/.bash_profile

以下の内容を書き込み、保存しましょう。

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

.bash_profileを反映させ、pyenvのバージョンが確認できればインストール完了です。

$ source ~/.bash_profile
$ pyenv -v

pyenvでのpythonのインストール

以下のコマンドでインストールできるpythonを確認できます。

$ pyenv install --list

今回はpython3.8.6をインストールします。

$ pyenv install 3.8.6

インストールしたpythonを使うように指定します。

$ pyenv global 3.8.6

pythonのバージョンが確認できればインストール完了です。

$ python --version

機械学習モデルの実行

Tacotron2を動かしてみる

今回は音声合成モデルのTacotron2を動かしてみようと思います。Tacotron2に関しては以下の記事で説明しています。

shirowanisan.com

pytorchのインストール

tacotron2を動かすためには、pythonにpytorchライブラリをインストールする必要があります。まずは、pythonのpipとsetuptoolsのアップデートを行っておきます。

$ pip install --upgrade pip
$ pip install --upgrade setuptools

続いて、pytorchをインストールします。

以下のサイトを参考に、インストールコマンドを打ち込みます。今回、UbuntuにインストールされているのはCUDA11.1ですが、pytorchがCUDA11.0までしかないため、11.0を選択してインストールします。本当はCUDAとpytorchのバージョンを揃えた方が良いと思いますが、この構成でも動くためこのまま進めます。

https://pytorch.org/

f:id:shirowanisan:20201111163330p:plain

$ pip install torch==1.7.0+cu110 torchvision==0.8.1+cu110 torchaudio===0.7.0 -f https://download.pytorch.org/whl/torch_stable.html

これでpytorchのインストール完了です。

他にもTacotron2を動かすために必要なパッケージもインストールしておきます。

$ pip install numpy scipy librosa unidecode inflect librosa

Tacotron2を動かしてみる

以下のリンクを参考にTacotron2を動かすコードを書いてみます。

Tacotron 2 | PyTorch

今回は以下のようなpythonファイルを作成しました。

$ vim tacotron2-test.py
import torch
tacotron2 = torch.hub.load('nvidia/DeepLearningExamples:torchhub', 'nvidia_tacotron2')

import numpy as np

tacotron2 = tacotron2.to('cuda')
tacotron2.eval()

text = "hello world, I missed you"

# preprocessing
sequence = np.array(tacotron2.text_to_sequence(text, ['english_cleaners']))[None, :]
sequence = torch.from_numpy(sequence).to(device='cuda', dtype=torch.int64)

# run the models
with torch.no_grad():
    _, mel, _, _ = tacotron2.infer(sequence)

print(mel)

2020年11月現在、RTX30系(もしくはCUDA11系)でwaveglowがエラーになる問題があります。そのため、このコードはTacotron2のみを動かし「hello world, I missed you」のメルスペクトログラムの取得までとしました。

実行してみると、メルスペクトログラムの予測ができていることがわかります。これでGPUを用いての予測が確認できました。

$ python tacotron2-test.py

f:id:shirowanisan:20201111171007p:plain

おまけ:Ubuntuにリモート接続

Ubuntuをリモート接続できるようにします。Ubuntuの設定の共有より、画像のように設定します。

f:id:shirowanisan:20201113182651p:plain

f:id:shirowanisan:20201113182705p:plain

以下のコマンドを打ち込み再起動します。

$ sudo gsettings set org.gnome.Vino require-encryption false
$ sudo reboot

Macからリモート接続をする場合はFinderタブの「移動→サーバへ接続」で画像のようにIPアドレスを入力することで接続可能です。

f:id:shirowanisan:20201113183440p:plain

インストールUSBメディアの作成はWindows、リモート接続はMacという不思議な構成で説明を行いましたが、私の開発スタイルに合わせた結果この構成となりました。

参考文献 

WindowsでUbuntuのインストールUSBメディアを作成する – diagnose-fix.com

Ubuntu18.04で突然解像度がおかしくなったときの対処法 - Qiita

ubuntu18.04LTS インストール後はSoftware Updateしましょう

Ubuntu18.04 LTSのインストールからNVIDIA GPU Driverのインストールまで - Qiita

Windows環境へのCUDA・cuDNNのインストール | ネジと銀

Installation Guide :: NVIDIA Deep Learning cuDNN Documentation

Ubuntu 18.04にpyenvをインストールする|setoyama60jp|note

Ubuntu に pyenv を利用して Python をインストールする - MathPython

Common build problems · pyenv/pyenv Wiki · GitHub

Windows10もしくはMacOSからUbuntu 18.04 LTSにリモート接続(リモートデスクトップ)してみた - いろいろ試してみる

Tacotron2による音声合成を体験する

Tacotron2とは

f:id:shirowanisan:20201108152347p:plain

Tacotron2Google社が提案したテキストから音声に変換するアルゴリズム」です。

論文発表は2017年。しかし、2020年11月現在でも、その生成音声は最高水準の品質です。

下記にその生成音声を載せておきます。肉声と違いがわからないかもしれません。

 

"This is a pen."

 

Tacotron2の仕組み

f:id:shirowanisan:20201108202551p:plain

Tacotron2を使ってテキストを音声に変換する場合は「テキストからメルスペクトログラムへの変換」のあとに「メルスペクトログラムから音声への変換」を行います。

メルスペクトログラムとは、とてもざっくり説明すると声の設計図のようなものです。

Tacotron2は「テキストからメルスペクトログラムへの変換」のみを行います。

「メルスペクトログラムから音声への変換」は、Tacotron2の論文ではWaveNet、NVIDIA社のソースコードではWaveGlowというアルゴリズムを用いています。

WaveGlowは、WaveNetの処理を軽量化したものです。

Tacotron2のソースコード

Tacotron2のアルゴリズムはGoogle社から提案されましたが、その実装ソースコードはNVIDIA社が公開しています。

以下より、NVIDIA社のTacotron2+WaveGlowのソースコードをダウンロード可能です。

ただし、ソースコードの実行にはNVIDIA社のGPUが必要です。

github.com

github.com

クラウドでTacotron2+WaveGlowを使う

GPUを持っていなくても、Tacotron2はクラウドでのコード実行環境「Google Colab(無料)」で実行することが可能です。手順は以下の通りです。

  1. 下記のリンクにアクセスする
  2. タブの「編集→ノートブック」ハードウェアアクセラレータをGPUに変更
  3. 上から順番にコードを実行する
  4. コード内のtext変数の値を変えることで好きな言葉での音声生成が可能

colab.research.google.com

Tacotron2の学習を行う

f:id:shirowanisan:20201108171830p:plain

Tacotron2の学習に必要なものは音声ファイルと、それに対応するテキストのみです。

下記のリンクのように音声ファイルのパステキストをまとめたファイルで指定します。 

https://raw.githubusercontent.com/NVIDIA/tacotron2/master/filelists/ljs_audio_text_train_filelist.txt

自分の好きな声を生成するTacotron2を作る

好きな声の音声ファイルでTacotron2を学習させれば、その声質のTacotron2が作れます。

下記の動画は、私が作ったTacotron2に話させたものです。

ちなみに、WaveGlowはNVIDIA社公開のモデルを使い、自分で学習させていません。

「メルスペクトログラムから音声への変換」非話者依存なので、好きな声に変えたいという目的においては、再学習の必要はありません。

まとめ

Tacotron2は入力にイントネーションの情報がないため、イントネーションが安定しないことがあります。

今後は、このイントネーションをどう安定させるかが課題ですね。

参考文献

[1712.05884] Natural TTS Synthesis by Conditioning WaveNet on Mel Spectrogram Predictions

エンタメ活用へ向けたAIによる音声生成(Part1) · DeNA Engineers' Blog

美少女声への変換と合成. Introduction | by Lento | Medium

DeepLearning でアニメキャラのボイロを作った話 【モデル作成編 その1】 - MLエンジニアのモノづくり日記

Tacotron2を調べてみた1 - やってみた!