fish-speechのFine-tuningを独自データで行う

初めに

fish-speech v1.4がリリースされたので、改めて触ってみます。

前回 CLIで推論を行う記事を書いたので、今回は つくよみちゃん会話AI育成計画(会話テキストデータセット配布) を使って学習を進めていきます

ayousanz.hatenadiary.jp

環境

docker環境の作成

まずは fish-speechをcloneします。

https://github.com/fishaudio/fish-speech.git

docker環境が準備されているので、docker環境をビルドして立ち上げます。

docker-compose -f docker-compose.dev.yml up -d

ビルドしたdocker環境には以下のコマンドで入ることができます

docker exec -it fish-speech /bin/bash

音声データセットの準備

今回は つくよみちゃんデータセットを使うので、データセットをダウンロードしてきます。

次に 以下のようなフォルダ構成を作成します

/exp/
├── data-raw/
│   ├── tsukuyomi-chan/

この中に音声ファイルを入れます。

ノーマライゼーション処理

はじめに 音声のノーマライゼーションを行います

fap loudness-norm data-raw data --clean

fapコマンドがない場合は、以下でインストールをします

pip install fish-audio-preprocess

(docker環境内でほかのライブラリと依存関係が一致しない場合は、docker外で別環境を作成してそちらでインストールを行うとうまく動きました。)

この処理が終わると /data に処理後の音声が保存されます。

ファイルによってはうまく処理がされない場合があるので、以下の修正を行ったverを作成しました。

  • ファイルのI/O処理のチャンク対応
  • 音声のクリッピングの際に音声の長さの考慮

github.com

必要に応じてこちらをcloseして以下でインストールを行い処理をします。

pip install -e .

文字お越しファイルの作成

/data の音声から それぞれの音声ファイルに対する .lab ファイルを作成します。

以下のコードで つくよみちゃんの文字起こしのテキストファイルと音声ファイルを使って labファイルを作成します。

import re
import os
import argparse

def process_text_file(input_file, output_dir):
    # 出力ディレクトリが存在しない場合は作成
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    with open(input_file, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    for line in lines:
        # 空行をスキップ
        if line.strip() == "":
            continue

        match = re.match(r'(VOICEACTRESS100_\d+):(.+)', line.strip())
        if match:
            file_name = match.group(1) + '.lab'
            content = match.group(2).strip()
        else:
            # マッチしない行の場合、ファイル名を生成
            file_name = f'line_{lines.index(line) + 1}.lab'
            content = line.strip()
        
        # .lab ファイルを作成し、内容を書き込む
        with open(os.path.join(output_dir, file_name), 'w', encoding='utf-8') as out_file:
            out_file.write(content)

def main():
    parser = argparse.ArgumentParser(description='Generate .lab files from input text file.')
    parser.add_argument('input_file', help='Path to the input text file')
    parser.add_argument('--output_dir', default='output', help='Path to the output directory (default: output)')

    args = parser.parse_args()

    process_text_file(args.input_file, args.output_dir)

if __name__ == "__main__":
    main()

実行は以下のコマンドで実行することができます。

python generate_lab_files.py input_text.txt --output_dir custom_output

セマンティックトークンのバッチ抽出

VQGANの重みをダウンロードをダウンロードします。

huggingface-cli download fishaudio/fish-speech-1.4 --local-dir checkpoints/fish-speech-1.4

セマンティックトークンを抽出します。

python tools/vqgan/extract_vq.py data \
    --num-workers 1 --batch-size 16 \
    --config-name "firefly_gan_vq" \
    --checkpoint-path "checkpoints/fish-speech-1.4/firefly-gan-vq-fsq-8x1024-21hz-generator.pth"

データセットをprotobufにパック

以下でデータセットからprotobufを生成します。

python tools/llama/build_dataset.py \
    --input "data" \
    --output "data/protos" \
    --text-extension .lab \
    --num-workers 16

LoRAの学習

LLAMAの重みをダウンロードします。

huggingface-cli download fishaudio/fish-speech-1.4 --local-dir checkpoints/fish-speech-1.4

docker環境で学習をする場合、shm_sizeが小さいとエラーになるため docker_compose.dev.yml に以下を追加します。

shm_size: 30gb

追加後は以下にようになります

services:
  fish-speech:
    build: .
    container_name: fish-speech
    shm_size: 30gb

batchサイズやデータの並列処理部分のパラメータは text2semantic_finetune.yaml の 以下で変更することができます。

  num_workers: 2
  batch_size: 4

学習時のステップ数や保存するタイミングは以下のパラメータになります。

  max_steps: 5000
  limit_val_batches: 1000
  val_check_interval: 1000

以下でLoRAの学習を開始することができます。 my_voice_project は任意のプロジェクト名を指定してください。

python fish_speech/train.py --config-name text2semantic_finetune \
    project=my_voice_project \
    +lora@model.model.lora_config=r_8_alpha_16

学習後のLoRAの重みを変換

学習が終わった後に生成されるファイルは .ckpt というファイルになっているため、こちらを .pth に変換する必要があります。

以下のコマンドで重みの変換を行います。

python tools/llama/merge_lora.py \
    --lora-config r_8_alpha_16 \
    --base-weight checkpoints/fish-speech-1.4 \
    --lora-weight results/$project/checkpoints/step_000000010.ckpt \
    --output checkpoints/fish-speech-1.4-yth-lora/

学習後のモデルを使って推論

音声推論をする場合は、CLIとWeb版などいくつか選ぶことができます。

CLIは以下を参考にしてください。

ayousanz.hatenadiary.jp

今回は視覚的にわかりやすいWeb版を立ち上げていきます。

まずは必要なモデルをダウンロードします。

huggingface-cli download fishaudio/fish-speech-1.4 --local-dir checkpoints/fish-speech-1.4

以下でWebUIを立ち上げることができます

python -m tools.webui \
    --llama-checkpoint-path "変換したLoRAの重みを保存したパス" \
    --decoder-checkpoint-path "checkpoints/fish-speech-1.4/firefly-gan-vq-fsq-8x1024-21hz-generator.pth" \
    --decoder-config-name firefly_gan_vq

備考

変更差分は以下にpushしています。

github.com