学習元音声の文字起こしが不要で、特定話者の音声さえあれば、誰でもどんな声でも学習でき、歌やセリフをその声に変換できるso-vits-svcをWindows環境にインストールし動かす方法を画像付きでどこよりも丁寧に解説します。
自宅で声質学習や事前学習済みモデルを用いた音声の変換を行う方法などを解説していきます。
自宅で学習させたモデルを使用して、約0.2秒で下のような変換ができるようになります。
変換前(声:音読さん):
変換後:
1. 環境構築
適当な名前のフォルダを作成してください。
その中にこれから色々ダウンロード・インストールしていきます。
まずは作成したフォルダ内で右クリック→「ターミナルで開く」を選択します。
前提条件
ここでは以下のものの導入(インストールしてパスを通してある)が済んでいるものとして進めます。
- Python 3.10 (バージョン厳守!!)(インストールとパスの通し方)
- Git
- CUDA
- cuDNN
- C++ BuildTools
so-vits-svcリポジトリをダウンロード
以下のコマンドを実行してリポジトリをダウンロードします。
git clone https://github.com/innnky/so-vits-svc -b 4.0
旧リポジトリは404 Not Found化しました。
移行先はこちらのため、コマンドは以下のものを使用してください。
git clone https://github.com/svc-develop-team/so-vits-svc -b 4.0
なお、上記URLのも消えていたら「https://github.com/ThePioneerJP/so-vits-svc」に差し替えてください。
python関係で諸々インストール
仮想環境を作成し、必要なものをインストールしていきます。
まず以下のコマンドで仮想環境を作成します。
python -m venv venv
そして仮想環境を有効化します。
venv\Scripts\Activate.ps1
仮想環境なら失敗した際もvenvフォルダを消すだけでイチからやり直せて、既存のPython環境を汚すこともないため積極的に使用していきましょう!
あとは色々とインストールしていきます。
まずは時間のかかるPytorchをインストールします。
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117
それ以外は一気にインストールします。
pip install SoundFile
pip install sounddevice
pip install requests==2.28.1
pip install onnx onnxsim onnxoptimizer
pip install scipy==1.9.3
pip install Flask==2.1.2 Flask_Cors==3.0.10
pip install playsound==1.3.0 PyAudio==0.2.12
pip install pydub==0.25.1
pip install pyworld
pip install tqdm==4.63.0
pip install scikit-maad
pip install praat-parselmouth
pip install gradio==3.9
pip install starlette==0.20.4
pip install tensorboard
pip install librosa
pip install fairseq==0.12.2
上記をまるごとコピペしてエンターを押します。
「警告:複数行のテキストが云々」と表示されますが、「強制的に貼り付け」してください。
なお最終行のpip install fairseq==0.12.2
はエンターを押さないとインストールされないことがあるのでご注意ください。
インストールすべきモジュールはhttps://rentry.co/a8zt2を参考にしました。
ありがとうございます。
学習元モデルなどをダウンロードしフォルダに設置する
まず、checkpoint_best_legacy_500.ptをダウンロードし、so-vits-svc\hubert
フォルダに入れます。
そして、G_0.pthとD_0.pthもダウンロードし、so-vits-svc\logs\44k
フォルダに入れます。
これで環境構築などは終了です。
2. 学習元データセットを用意する
データセット音声の配置方法
dataset_raw
├───speaker0
│ ├───xxx1-xxx1.wav
│ ├───...
│ └───Lxx-0xx8.wav
└───speaker1
├───xx2-0xxx2.wav
├───...
└───xxx7-xxx007.wav
複数話者の声を同時学習できるため、上記のようなファイル構成にします。
データ音声の品質・フォーマット・数量などの推奨値
データセットの推奨設定は次のとおりです。
なお、サンプリングレートは一括変換するスクリプトを使用するためバラバラでOK.
なお、ステレオ・モノラルどちらが推奨かは分かりませんでしたが、今回はモノラルでできました。
- 1つのファイルは2~15秒程度
- wavファイルであること
- ファイル数は1000個以上が望ましい
- ただし100個程度でもそこそこの品質が出るらしい
- 環境音やノイズなどが無い方が良い
- 単一の話者の音声
- 歌声でも良いし、歌声でなくても良い
データセットを整形する
今回は「つくよみちゃんコーパス」を使用させていただきます。
「声質の学習」には、フリー素材キャラクター「つくよみちゃん」が無料公開している音声データを使用しています。
■つくよみちゃんコーパス(CV.夢前黎)
https://tyc.rei-yumesaki.net/material/corpus/#terms2
https://tyc.rei-yumesaki.net/material/corpus/
今回は「02 WAV(+12dB増幅)」フォルダ内の音声100件を全て長さそのままで使用します。
大体どれも5~15秒のため助かります。
- モノラル
- サンプルレート:96.0 KHz
- ビット深度 : 32 ビット
音声の形式はそのようになっていますが、後でまとめて44.1KHzに変換します。
音声ファイルをso-vits-svc\dataset_raw\tsukuyomi
にコピーします。
先程開いたターミナル内で、次のようにコマンドを実行します。
cd so-vits-svc
python resample.py
./dataset_raw\tsukuyomi
100it [00:16, 6.07it/s]
これでサンプリングレート44.1KHzに一括変換されました。
なお変換された後の音声はso-vits-svc\dataset\44k
にあります。
続いて以下のコマンドを実行します。
python preprocess_flist_config.py
python preprocess_hubert_f0.py
これでデータセットの用意が終了しました。
いろんな拡張子がありますが、1つの音声ファイルごと追加で3つ作成されます。
- 音声ファイル名.wav
- 音声ファイル名.spec.pt
- 音声ファイル名.wav.f0.npy
- 音声ファイル名.wav.soft.pt
3. 訓練・学習を開始する
学習時の設定を確認&変更(epoch,batch sizeなど)
メモ帳などでso-vits-svc\configs\config.json
を開きます。
{
"train": {
"log_interval": 200,
"eval_interval": 800,
"seed": 1234,
"epochs": 10000,
"learning_rate": 0.0001,
"betas": [
0.8,
0.99
],
"eps": 1e-09,
"batch_size": 6,
"fp16_run": false,
"lr_decay": 0.999875,
"segment_size": 10240,
"init_lr_ratio": 1,
"warmup_epochs": 0,
"c_mel": 45,
"c_kl": 1.0,
以下略
変更すべきは赤字部分の2箇所だけ。
batch_size
はVRAM容量に応じて変更します。- バッチサイズ1につきVRAM 0.7~1.1GBくらいの感覚で何度か増減されてやってみてください
- VRAM 24GB:バッチサイズ32(これでVRAM 23.5GB程度)
- VRAM 16GB:バッチサイズ19 (20でVRAM16GB丁度のため)
- VRAM 12GB:バッチサイズ11 (12でVRAM12GB丁度のため)
- VRAM 8GB:バッチサイズ6か7くらい?
- ※ギリギリのサイズだと途中でVRAM不足により失敗することもあるので、上記バッチサイズの8割くらいにしましょう。
epochs
は学習データ1000個で400- 1000個で120エポックでも十分らしいです
- 今回は100個ですが1000エポックでいきました
音声ファイル100個200epoch時に学習済みモデルファイル「G_800.pth」ってのが始めて作成されたので、それ以下のepoch数では音声モデルファイルが作成されないようです。
きっと設定のどこかを弄れば変えられるのでしょうが、私にはわからないので常に200epoch以上にしています。
学習を開始するコマンド
python train.py -c configs/config.json -m 44k
上のコマンドを入力してエンターを押せば、学習が開始されます。
学習中のハードウェア負荷
バッチサイズ12だと?
バッチサイズ12は無料枠のGoogle Colabでも動作する設定ため、VRAMは16GB以下なのはわかっていましたが、どうやらVRAM 12GB+アルファ程度を消費するようです。
1epochごとにCUDAコア使用率が上がり、また次のEpochに切り替わるタイミングで下がっているのがわかります。
バッチサイズ20だと?
どうやらバッチサイズ20だとVRAM16GBのようです。
VRAM24GBならもっと盛れましたね。
バッチサイズ32
多分この辺が限度ですね。
学習データの数によっても違うかもしれませんが、音声ファイル100個・VRAM 24GBならバッチサイズは32くらいでヨシ!
でもギリギリは怖いのでいつも28くらいでやります。
学習中の「黒い画面」の様子
$32return_value.15 = cast(value=$30binary_and.14) ['$30binary_and.14', '$32return_value.15']
return $32return_value.15 ['$32return_value.15']
INFO:44k:====> Epoch: 8, cost 7.00 s
めちゃめちゃ表示が多いので省略しました。
とりあえず、エポックごとの所要時間と進捗状況などが表示されます。
出力されたモデルファイルの保存場所
so-vits-svc\logs\44k
にモデルファイルがあります。
通常「G_数字.pth」のもっとも数字が大きいものを使用します。
4. 推論・音声変換を行う
変換準備
変換元ファイルの配置場所
変換元のwav形式の音声をso-vits-svc\raw
フォルダ内に配置します。
一例はこのように。
なお、mp3ファイルの場合自動でwav化されるので、神経質にならなくて大丈夫です。
変換コマンドを作成する
必須引数(必ず指定するもの)
- -m, –model_path:モデルファイル(G_数字.pth)のファイルパス
- -c, –config_path:設定ファイルのパス
- -n, –clean_names:変換したい音声ファイル( rawフォルダに配置)
- -t, –trans:ピッチ調整。上下半音ずつ数値で指定
- -s, –spk_list:複数話者を合成(多分一度に複数人学習された時にリスト形式で指定する?!)
オプション設定(指定をしなくてもよい)
- -a, –auto_predict_f0:音声変換時にピッチを自動で予測する。歌声を変換する際にこれを付けないと音程が狂ってしまう
- -cm, –cluster_model_path:クラスタリングモデルのパス。トレーニングクラスタ(ナニソレ?)がないため今回未指定。
- -cr, –cluster_infer_ratio:クラスタリングスキーム(ナニソレその2)の割合を数値0 ~ 1で指定。クラスタリングモデルをトレーニングしていない時は0。つまり今回未指定。
実際にコマンドを作成してみた(例示)
python inference_main.py -m "logs/44k/G_3200.pth" -c "configs/config.json" -n "test.wav" -t 0 -s "tsukuyomi" -a
ぶっちゃけ赤文字部分だけ各自のものに置き換えたらOKだと思います。
音声変換を実行する
変換を行う 所要時間・出力フォルダなど
so-vits-svcフォルダ内でターミナルを開き、先程のコマンドをコピペしてエンター。
python inference_main.py -m "logs/44k/G_3200.pth" -c "configs/config.json" -n "test.wav" -t 0 -s "tsukuyomi"
load model(s) from hubert/checkpoint_best_legacy_500.pt
INFO:fairseq.tasks.text_to_speech:Please install tensorboardX: pip install tensorboardX
INFO:fairseq.tasks.hubert_pretraining:current directory is C:\Users\loveanime\Desktop\test\so-vits-svc
INFO:fairseq.tasks.hubert_pretraining:HubertPretrainingTask Config {'_name': 'hubert_pretraining', 'data': 'metadata', 'fine_tuning': False, 'labels': ['km'], 'label_dir': 'label', 'label_rate': 50.0, 'sample_rate': 16000, 'normalize': False, 'enable_padding': False, 'max_keep_size': None, 'max_sample_size': 250000, 'min_sample_size': 32000, 'single_target': False, 'random_crop': True, 'pad_audio': False}
INFO:fairseq.models.hubert.hubert:HubertModel Config: {'_name': 'hubert', 'label_rate': 50.0, 'extractor_mode': default, 'encoder_layers': 12, 'encoder_embed_dim': 768, 'encoder_ffn_embed_dim': 3072, 'encoder_attention_heads': 12, 'activation_fn': gelu, 'layer_type': transformer, 'dropout': 0.1, 'attention_dropout': 0.1, 'activation_dropout': 0.0, 'encoder_layerdrop': 0.05, 'dropout_input': 0.1, 'dropout_features': 0.1, 'final_dim': 256, 'untie_final_proj': True, 'layer_norm_first': False, 'conv_feature_layers': '[(512,10,5)] + [(512,3,2)] * 4 + [(512,2,2)] * 2', 'conv_bias': False, 'logit_temp': 0.1, 'target_glu': False, 'feature_grad_mult': 0.1, 'mask_length': 10, 'mask_prob': 0.8, 'mask_selection': static, 'mask_other': 0.0, 'no_mask_overlap': False, 'mask_min_space': 1, 'mask_channel_length': 10, 'mask_channel_prob': 0.0, 'mask_channel_selection': static, 'mask_channel_other': 0.0, 'no_mask_channel_overlap': False, 'mask_channel_min_space': 1, 'conv_pos': 128, 'conv_pos_groups': 16, 'latent_temp': [2.0, 0.5, 0.999995], 'skip_masked': False, 'skip_nomask': False, 'checkpoint_activations': False, 'required_seq_len_multiple': 2, 'depthwise_conv_kernel_size': 31, 'attn_type': '', 'pos_enc_type': 'abs', 'fp16': False}
load
INFO:root:Loaded checkpoint 'logs/44k/G_3200.pth' (iteration 801)
#=====segment start, 89.02s======
vits use time:0.5869977474212646
#=====segment start, 0.964s======
jump empty segment
上のようなログが流れ、約1秒で90秒の音声を変換し終えました。
生成された音声ファイルは、FLAC形式でso-vits-svc\
results
フォルダに出力されます。
このように。
変換のハードウェア負荷 VRAMの使用量
その際にVRAM9.4GBを使用。
4分以上の歌だとVRAMの不足で失敗したので、あまり長い音声ファイルは変換元にしないように!!
出力された音声を聞いてみる!!
-aオプション(音声変換時にピッチを自動で予測)の有無を比べてみました。
python inference_main.py -m "logs/44k/G_3200.pth" -c "configs/config.json" -n "test.wav" -t 0 -s "tsukuyomi" -a
-a有りの方が流暢ですね。変換時は基本的には-aを付けておけば良さそうです。
ちなみに学習元音声はこの動画の冒頭みたいなものなので、かなり再現出来ていますね!!
上記動画冒頭の「フリー素材キャラクターのつくよみちゃんと申します。」を入力してみました。
変換前(声:音読さん):
変換後:
そこそこ似てますね。
これが学習100分くらいでできるなんて素晴らしい☆
すでに学習済みのMoeGoeをWindowsでGUIで使用したり、AI TuberのAPIなし構成を考えたり、GPTをローカルファインチューニングしたりしてます。
合わせてご覧ください。