Bert-VITS2 ver2.2の複数話者学習用の前処理【音声合成】

[litaginさんの解説記事](https://zenn.dev/litagin/articles/b1ddc1da5ea2b3)にver2.2対応の解説が追記されたので、**Bert-VITS2 Ver2.2**の[つくよみちゃんJVSコーパス](https://tyc.rei-yumesaki.net/material/corpus/)と[あみたろさんのITAコーパス](https://amitaro.net/voice/corpus-list/ita/)を使った複数話者学習のシェルスクリプトを作成しました。**これらを実行するだけでとりあえず学習が回ります**

# 環境構築
以下を前提条件とします。
- linuxもしくはwsl2
- CUDAドライバがインストール済み
- python3.9以上がインストール済み

### git clone
リポジトリをcloneして、依存ライブラリをpip installするところまで（pythonの仮想環境は各自で）
```bash
git clone https://github.com/fishaudio/Bert-VITS2.git
cd Bert-VITS2
git checkout v2.2
pip3 install torch torchvision torchaudio
pip install -r requirements.txt
```

# 事前準備
preprocess.shという名前のファイルを作成し、以下を張り付けて保存してください。
```bash
> preprocess.sh # 空のファイルを作成
```
```bash:preprocess.sh
model_name=tsukuami-chan

# download pretrain models
[ ! -e "Data/${model_name}/models/" ] && mkdir -p Data/${model_name}/models/
[ ! -e "Data/${model_name}/models/DUR_0.pth" ] && wget -O "DUR_0.pth" https://huggingface.co/OedoSoldier/Bert-VITS2-2.2-CLAP/resolve/main/DUR_0.pth?download=true
[ ! -e "Data/${model_name}/models/D_0.pth" ] && wget -O "D_0.pth" https://huggingface.co/OedoSoldier/Bert-VITS2-2.2-CLAP/resolve/main/D_0.pth?download=true
[ ! -e "Data/${model_name}/models/G_0.pth" ] && wget -O "G_0.pth" https://huggingface.co/OedoSoldier/Bert-VITS2-2.2-CLAP/resolve/main/G_0.pth?download=true
mv DUR_0.pth D_0.pth G_0.pth Data/${model_name}/models/


# download & unzip tsukuyomi-chan corpus
if [ ! -e "downloads/つくよみちゃんコーパス Vol.1 声優統計コーパス（JVSコーパス準拠）" ];
then
    wget https://tyc.rei-yumesaki.net/files/sozai-tyc-corpus1.zip -O tsukuyomi.zip && unzip tsukuyomi.zip -d downloads && rm tsukuyomi.zip
fi

# download & unzip amitaro-ITA corpus
if [ ! -e "downloads/ITAcorpus_amitaro_2.1" ];
then
    wget https://amitaro.net/download/corpus/ITAcorpus_amitaro_2.1.zip -O amitaroITA.zip && unzip amitaroITA.zip -d downloads/ITAcorpus_amitaro_2.1 && rm amitaroITA.zip
fi

# prepare wav file
[ ! -e "Data/${model_name}/audios/raw" ] && mkdir -p Data/${model_name}/audios/raw
[ ! -e "Data/${model_name}/filelists" ] && mkdir -p Data/${model_name}/filelists

# JVS corpus
## tsukuyomi-chan
cp "downloads/つくよみちゃんコーパス Vol.1 声優統計コーパス（JVSコーパス準拠）/おまけ：WAV（+12dB増幅＆高音域削減）/WAV（+12dB増幅＆高音域削減）"/* "Data/${model_name}/audios/raw/"

## ITA corpus
### amitaro
location="downloads/ITAcorpus_amitaro_2.1"
spk_name="amitaroITA_normal"
#### recitation
for f in $(find $location -type f -iname "*rec*" | sort)
do
    # 拡張子直前の連続した数字を取得
    idx=$(echo $f | sed 's/.*\([^0-9]\)\([0-9]*\)\.[a-zA-Z0-9]*$/\2/' | sed 's/^0*//')
    # 3桁の0パティング
    pad_idx=$(printf "%03d" "$idx")
    echo $spk_name: ${f##*/}

    cp $f Data/${model_name}/audios/raw/${spk_name}_RECITATION324_${pad_idx}.wav
done

#### emotion
for f in $(find $location -type f -iname "*emo*" | sort)
do
    # 拡張子直前の連続した数字を取得
    idx=$(echo $f | sed 's/.*\([^0-9]\)\([0-9]*\)\.[a-zA-Z0-9]*$/\2/' | sed 's/^0*//')
    # 3桁の0パティング
    pad_idx=$(printf "%03d" "$idx")
    echo $spk_name: ${f##*/}
    
    cp $f Data/${model_name}/audios/raw/${spk_name}_EMOTION100_${pad_idx}.wav
done


# prepare text file
[ -e "filelists/text.list" ] && rm filelists/text.list

# JVS corpus
## tsukuyomi-chan
spk_name="tsukuyomi-chan"
while read line
do
    file_name=${line%:*}
    text=${line#*:}
    data_dir="Data/${model_name}/audios/wavs"
    file_path=${data_dir}/${file_name}.wav
    lang="JP"
    echo "${file_path}|${spk_name}|${lang}|${text}" >> Data/${model_name}/filelists/text.list
done < "downloads/つくよみちゃんコーパス Vol.1 声優統計コーパス（JVSコーパス準拠）/04 台本と補足資料/★台本テキスト/01 補足なし台本（JSUTコーパス・JVSコーパス版）.txt"

## ITA
[ ! -e "recitation_transcript_utf8.txt" ] && wget https://raw.githubusercontent.com/mmorise/ita-corpus/main/recitation_transcript_utf8.txt
[ ! -e "emotion_transcript_utf8.txt" ] && wget https://raw.githubusercontent.com/mmorise/ita-corpus/main/emotion_transcript_utf8.txt
### amitaro
spk_name="amitaroITA_normal"
#### recitation
while read line
do
    file_name=${line%:*} # 「:」より左の部分
    content=${line#*:} # 「:」より右の部分
    text=${content%,*} # 「,」より左の部分
    data_dir="Data/${model_name}/audios/wavs"
    file_path=${data_dir}/${spk_name}_${file_name}.wav
    lang="JP"
    echo "${file_path}|${spk_name}|${lang}|${text}" >> Data/${model_name}/filelists/text.list
done < "recitation_transcript_utf8.txt"

#### emotion
while read line
do
    file_name=${line%:*} # 「:」より左の部分
    content=${line#*:} # 「:」より右の部分
    text=${content%,*} # 「,」より左の部分
    data_dir="Data/${model_name}/audios/wavs"
    file_path=${data_dir}/${spk_name}_${file_name}.wav
    lang="JP"
    echo "${file_path}|${spk_name}|${lang}|${text}" >> Data/${model_name}/filelists/text.list
done < "emotion_transcript_utf8.txt"


# prepare config file
python preprocess_text.py
base_config=$(cat config.yml)
new_config=$(echo "$base_config" | \
sed -e "s|dataset_path: \"[^\"]*\"|dataset_path: \"Data/${model_name}\"|" | \
sed -e "s|transcription_path: \"[^\"]*\"|transcription_path: \"filelists/text.list\"|" | \
sed -e "s|config_path: \"[^\"]*\"|config_path: \"config.json\"|")

echo "$new_config" > config.yml

base_conf_json=$(cat configs/config.json)
echo "$base_conf_json" | sed -e "s|\"batch_size\": [0-9]*|\"batch_size\": 4|" > Data/${model_name}/config.json

# execute preprocess python script
python resample.py
python preprocess_text.py

# download emotional model
curl -L -o emotional/wav2vec2-large-robust-12-ft-emotion-msp-dim/pytorch_model.bin https://huggingface.co/audeering/wav2vec2-large-robust-12-ft-emotion-msp-dim/resolve/main/pytorch_model.bin
curl -L -o emotional/clap-htsat-fused/pytorch_model.bin https://huggingface.co/laion/clap-htsat-fused/resolve/main/pytorch_model.bin

# prepare fiture files
python bert_gen.py
python clap_gen.py
```

作成したら、実行権限を付与して実行してください。
```bash
chmod +x preprocess.sh
./preprocess.sh
```

# 学習
以下のコマンドで学習を開始します。
```bash
python train_ms.py
```

# 推論
`config.yml`の100行目あたりにモデルのパスを指定する箇所があるので、`models/G_1000.pth`(**数字の部分は適宜変更してください**)と書きかえます。
```
webui:
  # 推理设备
  device: "cuda"
  # 模型路径
  model: "genshin/models/G_8000.pth"　-> "models/G_1000.pth"に変更
...
```
webuiを起動します
```bash
python webui.py
```

# 学習結果のサンプル
準備中

# 参考
https://zenn.dev/litagin/articles/b1ddc1da5ea2b3