ZipVoiceのボコーダーをFlow2GANに置き換えて高速化できるか検証する

はじめに

ZipVoiceは、Flow Matchingを使った高速・高品質なゼロショットText-to-Speech(TTS)システムです。
今回、ボコーダー部分を最近公開されたFlow2GANに置き換えることで推論速度を向上できないか検証しました。

結論から言うと、Flow2GANに置き換えるメリットはありませんでした。 むしろVocosの方が6〜22倍高速という結果になりました。

今回統合した実装は以下のリポジトリ/ブランチに残しています。

github.com

検証環境

項目 内容
OS Windows
GPU NVIDIA CUDA対応
Python 3.11
パッケージ管理 uv

ボコーダーとは

TTSシステムは以下のパイプラインで動作します:

テキスト → モデル推論 → メルスペクトログラム → ボコーダー → 波形

ボコーダーはメルスペクトログラムを音声波形に変換するコンポーネントです。 ZipVoiceはデフォルトでVocosを使用しています。

Flow2GANとは

Flow2GANはFlow MatchingとGANファインチューニングを組み合わせたボコーダーで、1〜4ステップでの推論が可能です。

主な特徴: - 1〜4ステップ推論(設定可能) - Flow Matching + GANファインチューニング - マルチブランチConvNeXtアーキテクチャ

ZipVoiceとFlow2GANは同じMel-Spectrogram仕様(24kHz、100 bins、FFT 1024、hop 256)を使用しているため、理論上は置き換え可能です。

Flow2GANの統合

以下の手順でインストール、統合、推論まで行いました。

uv addでの依存関係追加

Flow2GANをローカルから追加:

uv add flow2gan --editable "C:\path\to\Flow2GAN"

ボコーダーパッケージの作成

VocosとFlow2GANを切り替えられるように、統一インターフェースを作成しました:

from abc import ABC, abstractmethod
import torch

class BaseVocoder(ABC):
    @abstractmethod
    def decode(self, mel: torch.Tensor) -> torch.Tensor:
        """(B, 100, T) -> (B, 1, samples)"""
        pass

def get_vocoder(vocoder_type: str = "vocos", **kwargs) -> BaseVocoder:
    if vocoder_type == "vocos":
        return VocosVocoder(**kwargs)
    elif vocoder_type == "flow2gan":
        return Flow2GANVocoder(**kwargs)

推論スクリプトへの引数追加

parser.add_argument("--vocoder-type", type=str, default="vocos",
                    choices=["vocos", "flow2gan"])
parser.add_argument("--vocoder-n-steps", type=int, default=2)

ボコーダーの処理時間の比較

まずは Vocosでの推論の時間の内訳を計測します

処理ステップ 処理時間 割合
プロンプト読込 10.73 ms 0.5%
プロンプト前処理 20.18 ms 1.0%
特徴量抽出 2.66 ms 0.1%
トークン化 1.22 ms 0.1%
モデル推論 (ZipVoice) 1929.54 ms 97.8%
ボコーダー 4.29 ms 0.2%
後処理 4.15 ms 0.2%
合計 1972.77 ms 100%

ここでボコーダーの部分だけを置き換えて比較をすると以下のようになりました。

ボコーダー速度比較

ボコーダー 処理時間 全体に占める割合
Vocos 4.29 ms 0.2%
Flow2GAN 1-step 25.76 ms 1.3%
Flow2GAN 2-step 48.24 ms 2.4%
Flow2GAN 4-step 94.89 ms 4.7%

またVocosでもFlow2GAN(各ステップ)の生成された音声は音質など大きくは分からない状態でした