Windows10,WSL2でESPNetのVITS学習レシピを実行する【音声合成】

# はじめに

Windows10,WSL2上でESPNetの環境構築が終わっていることを前提としています。
[前回の記事](https://qiita.com/seichi25/items/fc6c22042f926baa08e6)をまだ読んでいない方は先にそちらを読むことを推奨します。

この記事ではESPNetでVITSモデルをファインチューニングする方法について紹介します。

# 1. 概要
学習の大まかな仕組みについて説明します。実際の操作を知りたい方は<b>[2. VITSをファインチューニングする](#2-vitsをファインチューニングする)</b>のところまで飛ばしてください。
<b>※ディープラーニングについては本筋ではないので、厳密な説明はしていません。ご了承ください。</b>
## 1.1 ディープラーニング
ディープラーニングにあまり馴染みのない方向けに、VITSの仕組みを大雑把に表した図を以下に示します。

テキストを数値に変換し、VITSに入力することでたくさんの変換を経て最終的に音声として出力します。
ディープラーニングにおける学習とは、このたくさんの変換をするパラメータを最適な値に近づくように自動調整することを言います。

図では簡略化のため、白丸や線の数が数えるほどしかありませんが、実際には何百、何千、何万と存在します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/d2213d5d-1126-a64f-eb83-0dad6d9e40b3.png)

## 1.2 事前学習

ディープラーニングでは大量のデータを用いて、パラメータを調整していきます。
しかし、大量のデータを個人が用意するのは難しいので、JSUTなどの公開されている大量のデータを利用して学習します。

今回はこの事前学習に要する時間を省くため、[zenodo](https://zenodo.org/)で公開されている事前学習済みのモデルをダウンロードして利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/8efa8302-08bf-d71c-0123-0e6136362680.png)

## 1.3 ファインチューニング
事前学習のモデルでは、JSUTの女性話者の声でしか音声合成することができません。
(そうなるように学習させたのだから当たり前)


そこで、しゃべらせたい声の音声データを<b>最低でも100文（約10分）以上</b>用意して、これを用いて再学習させます。

<details><summary><b>なんで最初からしゃべらせたい声で学習しないの？</b></summary>
理由は主に3つあります。

- データが少ないと学習がうまくいかないことが多い
- 学習にとても時間がかかる
- データを大量に用意するのは大変

モデルをゼロから学習させる場合、パラメータの初期値はランダムに設定され、その値から少しずつ調整していくことになります。
ランダムなので最適な値とは程遠いところからのスタートになり、データが少ないと最適な値に近づきづらく、データが大量に用意できたとしても、それを学習させるのにとても時間がかかります。(つよつよのGPUがあれば早くできますが、そんなものは到底個人では運用できないので)

そこで、大量のデータで学習済みのモデルを持ってきて、その学習済みのパラメータを初期値として学習させることで、これらの問題を改善しようということです。

</details>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/f9f70a79-192d-6f3b-3ca9-6f487e1b8959.png)

# 2. VITSをファインチューニングする

## 2.1 自動設定スクリプトをダウンロードする

私が学習用のフォルダの作成やシェルスクリプトを自動で構築するシェルスクリプトを書きましたのでそちらをダウンロードします。

<font color='Red'><b>ただし、このスクリプトは[前回の記事](https://qiita.com/seichi25/items/fc6c22042f926baa08e6)の環境に依存します。</b></font>

<details>

- `ESPNET_ROOT`という環境変数に、espnetディレクトリの絶対パスを登録してあります
- espnetディレクトリに`data_root`というフォルダを作成してあります
- `TTS_DATA_ROOT`という環境変数に`data_root`の絶対パスを登録してあります

</details>

左下の検索バーに`ubuntu`と入力してエンター。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/eaf3f5a4-b2f8-af4a-5d25-2e626fbee24d.png)

---

ubuntuが立ち上がったら、以下のコマンドを実行します。
<b>※ペーストは右クリックです</b>
<b>※ペーストした後にエンターを押してください</b>

```
wget "https://drive.google.com/uc?export=download&id=1O__heHGit7JkFzl1rWZke-eUa8wehrk0" -O create_recipe.sh
chmod +x create_recipe.sh
```

## 2.2 音声,テキストデータを用意する

以下の画像と同様の構造でデータを用意してください

- <font color='Blue'><b>NAME</b></font>_voice_dataを作成(<b><font color='Blue'>NAME</font>は任意</b>)
- <font color='Blue'><b>NAME</b></font>_voice_dataの中にvoiceというフォルダ、voice_text.txtというテキストファイルを作成
- voiceの中に音声ファイルをすべて入れる
- voice_text.txtに「<b>音声ファイル名(.wavは書かない):発話内容</b>」の形式で記述

![tree_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/1a4e6ae4-f6fe-6509-8a70-188245b60ea8.png)

![tree_sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/6b9c87d8-e620-e737-f1aa-aa2d5735041e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/d5f34ed3-323c-7b75-8ce3-08bd21ace1bf.png)


---

データ用意したら、data_rootフォルダにこれをコピーします。

- エクスプローラーを開く
- アドレスバーに「\\wsl$\Ubuntu\home」と入力してエンター<b>(画像1)</b>
- espnet→data_root　とフォルダを開き、そこにペースト<b>（画像2~5)</b>

<details><summary><b>参考画像</b></summary>

---

### 画像1
アドレスを入力

![adress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/7ff383a6-a848-fb45-20a4-6822aa681be4.png)

---

### 画像2
ユーザのフォルダを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/1c6a0d7c-e8ce-0c48-bdc0-b14d46e810fa.png)

---

### 画像3
espnetのフォルダを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/154da430-9897-3662-8abd-a3a3e254c022.png)

---

### 画像4
data_rootフォルダを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/831ec009-4451-2146-4f30-d4790eb2552b.png)

---

### 画像5
データをコピーする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/a51422da-fe43-0e60-6f86-a95c5e858a3e.png)

</details>

## 2.3 create_recipe.shを実行する
Ubuntuのウィンドウに戻って、
```
./create_recipe.sh NAME
```
と入力してエンター。

:::note warn
<b>注意</b>
<b>コマンドの NAME 部分は[2.2](#22-音声テキストデータを用意する)で作成したフォルダの<font color='Blue'> NAME </font>と同じにしてください</b>
:::

## 2.4 all_run.shを実行する
以下のコマンドを実行すると学習を開始することができます。
※2022/03/14コマンド修正
```
conda activate espnet
cd $ESPNET_ROOT/egs2/NAME/tts1
./all_run.sh
```

:::note warn
<b>注意</b>
<b>コマンドの NAME 部分は[2.2](#22-音声テキストデータを用意する)で作成したフォルダの<font color='Blue'> NAME </font>と同じにしてください</b>
:::

:::note info
<b>実行前にウィンドウの横幅を十分広くしておいてください</b>
事前学習モデルをダウンロードする処理が含まれます。
ウィンドウの横幅が狭いと、進捗バーが画面に収まらず確認できないので、あらかじめウィンドウの横幅を広くしておいてください。
:::

学習が開始されるとこのような画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/a7f8c0a1-40e6-6d9f-8807-4dd7bacd45d9.png)

# 3. 学習の様子を監視する

学習を開始したUbuntuのウィンドウはそのままにしておいて、
左下の検索バーにUbuntuと入力して、新たにUbuntuのウィンドウを立ち上げます。
このウィンドウで学習の様子を監視します。


学習の様子は逐次`train.log`というファイルに記録されます。
<details><summary>旧</summary>

このファイルから学習の様子を逐次表示するコマンドを以下に示します。
```
tail -f $ESPNET_ROOT/egs2/NAME/tts1/exp/tts_full_band_vits/train.log | grep -oP "2.*INFO:([^=]*=[^=]|[^=]*seconds|[^=]*minutes)"
```

</details>

<b>※2022/03/13追記</b>
logを表示するコマンドを使いやすくするシェルスクリプトを書きました。以下のコマンドでダウンロードできます。
```
wget "https://drive.google.com/uc?export=download&id=1z5Ma94NUqTphFM0J3z9vONgN9HYM78K7" -O log_viewer.sh
chmod +x log_viewer.sh
```

使い方は以下の通りです。

```
./log_viewer.sh NAME
```

:::note warn
<b>注意</b>
<b>コマンドの NAME 部分は[2.2](#22-音声テキストデータを用意する)で作成したフォルダの<font color='Blue'> NAME </font>と同じにしてください</b>
:::

実行するとこのような画面になります。
画像はコマンドを直接打っているので赤字ですが、シェルスクリプトを使った場合は白字で表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1604294/8c1e2b9a-afd9-a821-cce3-637ed01abaaf.png)

# おわりに
これでエラーが出なければ自作の音声合成モデルが作れます。学習完了までにかかる時間はおそらく１日程度です。
その間は放置でいいので何か別のことをして気長に待ちましょう。

ただし、PCのスペックが低いと、メモリやGPUの専用メモリをほとんど占有してしまうので、負荷の高い作業をするのはおすすめしません...

ゲームなどは相当軽いものでない限り重すぎてできないでしょう。ブラウジングやyoutubeなどの動画視聴は問題なくできるかと思います。(あくまで私の環境では)

参考までに私の環境を書いておきます。

- CPU : AMD Ryzen 5 3600 6-Core Processor 3.59 GHz
- RAM : 16.0 GB
- GPU : NVIDIA GeForce GTX 1660 Super
- OS : Windows 10 Home バージョン21H2 ビルド19044.1586

# 参考
https://github.com/espnet/espnet/tree/master/egs2/tsukuyomi/tts1

https://qiita.com/RRR_troisR/items/6288b9bdc6e725aa8440

https://tech.fusic.co.jp/posts/2021-08-03-espnet/

https://kan-bayashi.github.io/asj-espnet2-tutorial/

https://github.com/espnet/espnet