VITS2で​TTSの​モデルを​学習させた​話

4 min read
vits2

VITS2

VITS2は日本語デフォルト対応の、TTSモデルです。

で、Style Bert VITS2はその辺の学習だったり、音声合成をやってくれるユーティリティツールです。もし、日本語で音声を学習させてTTSをしたいのであればVITS2は最有力の選択肢になるでしょう。

データセット

ChatGPTによると30~40分程度の長さの音声があれば良いとのことです。

仮に一つの学習データが5秒だとすると、2000秒程度確保すればいいので400件ほどあれば十分ということになります。

今回は学習のために某ゲームからデータセットを抜き出すことにしました。言うまでもないことですが、これはあくまでも研究・学習を目的とした私的利用であることを念押ししておきます。

VITS2は一つのモデルデータに複数の話者を登録可能なので、今回は15話者登録しました。学習時間は話者数に比例するので、15倍かかるということです。

学習方法

自分はCLIの手順通りに進めました。

ただ、バグなのかアクセントの判定がpyopenjtalkから返ってくるものが正しくパースできません。

style_bert_vits2/nlp/japanese/g2p.pyに以下の変更を加え、読み方を認識できるようにします。

elif yomi == "?":
assert word == "?", f"yomi `?` comes from: {word}"
yomi = "?"
elif yomi == "!":
assert word == "!", f"yomi `!` comes from: {word}"
yomi = "!"

ちなみに、事前にデータは、

Terminal window
Data/
└── model_name/
├── raw/
└── *.ogg
└── esd.list

のような構成になっていれば良いです。

複数話者学習させたい場合には各話者のesd.listrawを作っておき、マージすれば良いです。

初期化

Terminal window
python initialize.py

最初に学習済みモデルをダウンロードします。

音声データ編集

Terminal window
python slice.py --model_name <model_name>

ゲームなどの場合はそもそもノーマライズはされているので、余計な無音などを削除すればよいでしょう。で、これも私の場合は事前にやっていたのでここもスキップしました。

文字書き起こし

Terminal window
python transcribe.py --model_name <model_name>

TTSの学習では「台本」と「音声」がセットの教師あり学習なので、音声がなんと喋っているのかのテキストデータが必要になります。

が、これも事前にWhisperで書き起こしし、手動である程度修正していたので不要でした。本レポジトリでは軽量化モデルしか使えないようで、ガッツリlarge-v3で書き起こししたものに比べて精度で劣る部分が見られました。

前処理

Terminal window
python preprocess_all.py -m <model_name> --use_jp_extra --freeze_JP_bert --yomi_error skip

今回は日本語しか喋らせないので--use_jp_extraを指定しました。日本語の発音をあまり変えたくなかったので--feeze_JP_bertを入れましたが、なくても良かったかも知れません。

--yomi_error skipはほぼ必須で、これがないと辞書にない単語などがあったときにエラーで止まります。前処理はめちゃくちゃ時間がかかるので、途中で止まるとガックリきます。有効にしておきましょう。

学習

事前に準備できたアセット数は約16000で、これをエポック数50で回しました。

Terminal window
python train_ms_jp_extra.py

これで学習を実行します。VRAMが12GBあるRTX 4070Tiだとバッチサイズは3が限界で、4でも一応動きましたが途中で落ちたので安定を求めて3にしました。処理速度的には3.6it/s程度で、全部で26万ステップくらい回す必要があったので、完了までに20時間くらいかかりました。

冬場だったので良かったですが、夏場だと家がホカホカになります。

おまけ

あまりに時間がかかるので大規模リソースでどうなるのか検証するために、H100x1とA100x8で実験しました。

デバイスエポック数VRAMバッチ数処理時間
RTX 4070Ti5012320時間
H1005080323.5時間
A100x810080321.8時間

H100だと全く同じデータでRTX 4070Tiの5~6倍程度、A100x8の構成だと設定ミスでエポック数を倍にしてしまったのですが、H100の半分くらいの時間で終わりました。

H100だと一時間辺り200円くらいで借りられるので、さっさとやってしまいたい場合には十分選択肢になると思います。本当はH100x8もやりたかったのですが、リソースが空いていなかったので検証できませんでした。

まあでも30分か40分くらいで終わるんじゃないかと思います。ちなみに学習データですが、エポック数が50でも100でもあんまり違いがわからなかったので、とりあえず50くらいで試せばいいのではないかと思います。100は過剰すぎる可能性があります。

複数GPUで学習させる方法は、既存のコードをベースにLLMに作成してもらいました。

まとめ

話者によっては5000件以上のデータがあったのですが、短いデータを抜きすぎたせいか「感嘆符」のような短いセリフに関しては学習が不十分になってしまい、あまり似ていない結果になりました。

また、エポック数が100で過学習してしまったのか、途中からズレていった話者もいました。この辺りは調整が必要なのかも知れません。

学習したモデルデータの公開予定はありません

記事は以上。