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 = "!"ちなみに、事前にデータは、
Data/└── model_name/ ├── raw/ │ └── *.ogg └── esd.listのような構成になっていれば良いです。
複数話者学習させたい場合には各話者のesd.listとrawを作っておき、マージすれば良いです。
初期化
python initialize.py最初に学習済みモデルをダウンロードします。
音声データ編集
python slice.py --model_name <model_name>ゲームなどの場合はそもそもノーマライズはされているので、余計な無音などを削除すればよいでしょう。で、これも私の場合は事前にやっていたのでここもスキップしました。
文字書き起こし
python transcribe.py --model_name <model_name>TTSの学習では「台本」と「音声」がセットの教師あり学習なので、音声がなんと喋っているのかのテキストデータが必要になります。
が、これも事前にWhisperで書き起こしし、手動である程度修正していたので不要でした。本レポジトリでは軽量化モデルしか使えないようで、ガッツリlarge-v3で書き起こししたものに比べて精度で劣る部分が見られました。
前処理
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で回しました。
python train_ms_jp_extra.pyこれで学習を実行します。VRAMが12GBあるRTX 4070Tiだとバッチサイズは3が限界で、4でも一応動きましたが途中で落ちたので安定を求めて3にしました。処理速度的には3.6it/s程度で、全部で26万ステップくらい回す必要があったので、完了までに20時間くらいかかりました。
冬場だったので良かったですが、夏場だと家がホカホカになります。
おまけ
あまりに時間がかかるので大規模リソースでどうなるのか検証するために、H100x1とA100x8で実験しました。
| デバイス | エポック数 | VRAM | バッチ数 | 処理時間 |
|---|---|---|---|---|
| RTX 4070Ti | 50 | 12 | 3 | 20時間 |
| H100 | 50 | 80 | 32 | 3.5時間 |
| A100x8 | 100 | 80 | 32 | 1.8時間 |
H100だと全く同じデータでRTX 4070Tiの5~6倍程度、A100x8の構成だと設定ミスでエポック数を倍にしてしまったのですが、H100の半分くらいの時間で終わりました。
H100だと一時間辺り200円くらいで借りられるので、さっさとやってしまいたい場合には十分選択肢になると思います。本当はH100x8もやりたかったのですが、リソースが空いていなかったので検証できませんでした。
まあでも30分か40分くらいで終わるんじゃないかと思います。ちなみに学習データですが、エポック数が50でも100でもあんまり違いがわからなかったので、とりあえず50くらいで試せばいいのではないかと思います。100は過剰すぎる可能性があります。
複数GPUで学習させる方法は、既存のコードをベースにLLMに作成してもらいました。
まとめ
話者によっては5000件以上のデータがあったのですが、短いデータを抜きすぎたせいか「感嘆符」のような短いセリフに関しては学習が不十分になってしまい、あまり似ていない結果になりました。
また、エポック数が100で過学習してしまったのか、途中からズレていった話者もいました。この辺りは調整が必要なのかも知れません。
学習したモデルデータの公開予定はありません
記事は以上。