【備忘録】Style-Bert-VITS2で音声合成モデルを作成してみた

# はじめに
Cotomo[^1]が流行った時期に音声合成をやってみようと思い、**Style-Bert-VITS2**を試していたので、その内容をまとめました。
日本語版の**Style-Bert-VITS2**が既に作成されていたので、コードはこちらを使わせていただきました。

https://zenn.dev/litagin/articles/034819a5256ff4


## 想定読者
- 音声合成やったことないけど、音声合成やってみたい人
- テキスト生成と音声合成を組み合わせてみたい人

## 実行環境
- Google Colab

# VITS2
今回実行する**Style-Bert-VITS2** の基になっている手法になります。論文は以下になります。

https://arxiv.org/abs/2106.06103

特徴としては以下の3つになります。
- TTS（Text To Speech）とSTS（Speech To Speech）ができる
- 複数話者の音声合成を1つのモデルでできる
- 高品質かつ高速

※著者が音声合成分野について詳しくないため、誤っていたらご指摘ください


# コード
https://github.com/litagin02/Style-Bert-VITS2

# 音声データ
**つくよみちゃんコーパス（CV.夢前黎）** を使わせていただきました。

https://tyc.rei-yumesaki.net/material/corpus/

音声データの公開ありがとうございます。
今回は「おまけ：WAV（+12dB増幅＆高音域削減）」を利用しています。

# 実行手順
学習～推論までのコードがまとめられているColabをベースに実行する。

https://colab.research.google.com/github/litagin02/Style-Bert-VITS2/blob/master/colab.ipynb

音声データを指定のディレクトリに格納することで様々な音声データに対応が可能。Googleドライブのマイドライブ上に```Style-Bert-VITS2```というディレクトリを作成。さらに```Style-Bert-VITS2```内に```Data```,```input```,```model_assets```を作成。
音声データのみだと、whisperを使って、STT（Speech To Text）した内容から音素データを作成しているようです。
```python
dataset_root = "/content/drive/MyDrive/Style-Bert-VITS2/Data"
```

## 推論
モデルの学習が終わったら、Colab上の以下のコードを実行するとWebUIが起動できます。public URLが表示されるので、アクセスすることで、学習したモデルを試すことができます。
```python
!python app.py --share
```

```result
Running on public URL: https://9b94edec92afd092af.gradio.live
```

また、以下のコードを使うことで学習したモデルをローカル環境で実行することも可能です。
学習したモデルは```Googleドライブ/マイドライブ/Style-Bert-VITS2/model_assets/モデル名/```にあるので、ダウンロードし、ローカルのmodel_assetsフォルダに格納。```config.json```,```style_vectors.npy```,```モデル名_eエポック数_sステップ数.safetensors```の3つが必要です。

https://github.com/litagin02/Style-Bert-VITS2/blob/master/library.ipynb

### テキスト生成+音声合成
library.ipynbを参考にOpenAIのAPIを使って、テキスト生成→音声合成するコードを作成しました。

```python
from style_bert_vits2.tts_model import TTSModel
import openai
import json
from IPython.display import Audio, display

assets_root = Path("model_assets")

# 学習したモデルの情報
model_file = "XXXX.safetensors"
config_file = "config.json"
style_file = "style_vectors.npy"

model = TTSModel(
    model_path=assets_root / model_file,
    config_path=assets_root / config_file,
    style_vec_path=assets_root / style_file,
    device="cpu"
)

openai.api_key = "sk-XXXXXXXX"

client = openai.OpenAI(api_key=openai.api_key)

# https://tyc.rei-yumesaki.net/about/data/profile/
system_prompt = """以下のプロフィールのキャラクターになりきって会話をしてください。
■年齢：人間で言うと14歳くらい
■身長：148cm（可変）
■性格：素直で頑張り屋
■特技：営業スマイル
■口調：敬語／一人称は「私（わたし）」
■座右の銘：鏡花水月
■好きな食べ物：絵に描いた餅（本物のお餅は食べられない）
"""

response = client.chat.completions.create(
  model="gpt-4-turbo",
  messages=[
    {"role": "system", "content": system_prompt},
    {"role": "user", "content": "あなたの好きな食べ物は何ですか？"}
  ]
)


response_json = json.loads(response.json())
text = response_json["choices"][0]["message"]["content"]
# 私の好きな食べ物は絵に描いた餅です。本物のお餅は食べられないのですが、絵に描かれた餅はどんなにたくさん見ても飽きませんし、いろいろな形や大きさを想像できて楽しいですよ。

sr, audio = model.infer(text=text)
display(Audio(audio, rate=sr))
```

## 小ネタ（Colab）
Google Colabは無料アカウントだと、1日あたりのリソースに最大12時間という上限があるようなので、save_stepは細かいほうがいいかもしれません。1モデルあたり約200MBでした。

https://research.google.com/colaboratory/faq.html?hl=ja

## 参考情報
https://zunko.jp/multimodal_dev/login.php

https://voice-statistics.github.io/

https://qiita.com/seichi25/items/75db3910d2a0965bbc89


# 最後に
音声合成を全くやったことないのですが、かなり手軽に試すことができました。
普段はテキスト処理系を主にやっているのですが、音声合成とテキスト生成を組み合わせると新鮮味が増して面白かったです。
今後はdifyを使って作成したアシスタントの応対結果を音声合成することにも取り組んでいる内容を紹介します。


[^1]: https://cotomo.ai/