ポッドキャスト風音声に最適化されたTTS「Muyan-TTS」を試す
ここで知った
GitHubレポジトリ
Muyan-TTS
referred from https://github.com/MYZY-AI/Muyan-TTSMuyan-TTSは、5万ドルの予算でポッドキャスト用途に最適化された学習可能なTTSモデルです。10万時間を超えるポッドキャスト音声データで事前学習されているため、ゼロショットでも高品質な音声生成が可能です。さらに、対象話者の音声を数十分用意するだけで話者適応が行えるため、個人の声への高いカスタマイズ性を備えています。
🔥🔥🔥 ニュース!!
- 2025年4月29日: 👋 ゼロショットTTSモデル Muyan-TTS の重みを公開しました。
- 2025年4月29日: 👋 単一話者の音声を数十分追加学習させた少ショットTTSモデル Muyan-TTS-SFT の重みを公開しました。
- 2025年4月29日: 👋 ベースモデルからSFTモデル(話者適応)までのトレーニングコードを公開しました。
- 2025年4月29日: 👋 Muyan-TTS の 技術報告書 を公開しました。
概要
フレームワーク
referred from https://github.com/MYZY-AI/Muyan-TTSMuyan-TTS のフレームワーク。左側はテキスト(青)と音声トークン(緑)の並列コーパスをモデル化する LLM、右側は生成された音声トークンと音素・話者埋め込みを音声波形へデコードする SoVITS モデルを示しています。
データ
referred from https://github.com/MYZY-AI/Muyan-TTSデータ処理パイプライン。最終的なデータセットは10万時間を超える高品質な音声と対応する転写から構成され、ポッドキャストのような長尺音声シナリオに適した堅牢な並列コーパスを形成しています。
トレーニングコスト
指標 データ処理 LLM事前学習 デコーダ学習 合計 GPU時間換算 60K (A10) 19.2K (A100) 1.34K (A100) — USD換算 $30K $19.2K $1.34K $50.54K ※A10 と A100 のGPU時間単価をそれぞれ $0.5、$1 と仮定して算出。
合成速度
ここでは、1秒の音声を生成する推論時間を r とし、複数のオープンソースTTSモデルと比較しました。
Model CosyVoice2 Step-Audio Spark-TTS FireRedTTS GPT-SoVITS v3 Muyan-TTS r ↓ 2.19 0.90 1.31 0.61 0.48 0.33 すべての推論は NVIDIA A100 (40 GB, PCIe) 1枚で実施し、ベースラインモデルは公式の推論実装を用いて評価しました。
注: Muyan-TTS は学習データの大半が英語であるため、現状では英語入力のみをサポートします。
デモ
https://github.com/user-attachments/assets/a20d407c-15f8-40da-92b7-65e92e4f0c06
「Base model」列の3つの音声と「SFT model」列の最初の音声は、それぞれ公開済みの Muyan-TTS と Muyan-TTS-SFT で合成したものです。「SFT model」列の残り2つの音声は、ベースモデル上で別途学習したSFTモデルによる生成で、一般公開はされていません。
論文についてはalphaXivのまとめを参照。
なお、対応言語は英語のみ
モデル
Colaboratory T4で試す。
レポジトリクローン
!git clone https://github.com/MYZY-AI/Muyan-TTS.git
%cd Muyan-TTS
Makefileが用意されているのでmake。中身は
- requirements.txtの依存パッケージをインストール
- LLaMA-Factoryをクローン
- LLaMA-Factoryの依存パッケージをインストール
という感じ。
!make build
次にモデルをダウンロードする。Muyan-TTS・Muyan-TTS-SFTと、chinese-hubert-base を以下のようなディレクトリ構成になるようにダウンロードする。
!mkdir -p pretrained_models
!git lfs install
!git clone https://huggingface.co/TencentGameMate/chinese-hubert-base pretrained_models/chinese-hubert-base
!git clone https://huggingface.co/MYZY-AI/Muyan-TTS pretrained_models/Muyan-TTS
!git clone https://huggingface.co/MYZY-AI/Muyan-TTS-SFT pretrained_models/Muyan-TTS-SFT
次に推論コードを実行するが、インストールしたパッケージがランタイムに反映されずエラーになってしまうので、ここで一旦ランタイムを再起動しておく。
ランタイム再起動後はカレントディレクトリがもとに戻ってしまうので再度移動。
%cd Muyan-TTS
では推論コードを実行。以下はtts.py
のコードをそのままnotebookで実行している。
from inference.inference import Inference
import asyncio
import os
# notebook環境では必要
import nest_asyncio
nest_asyncio.apply()
async def main(model_type, model_path):
tts = Inference(model_type, model_path, enable_vllm_acc=False)
wavs = await tts.generate(
ref_wav_path="assets/Claire.wav",
prompt_text="Although the campaign was not a complete success, it did provide Napoleon with valuable experience and prestige.",
text="Welcome to the captivating world of podcasts, let's embark on this exciting journey together."
)
output_path = "logs/tts.wav"
os.makedirs("logs", exist_ok=True)
with open(output_path, "wb") as f:
f.write(next(wavs))
print(f"Speech generated in {output_path}")
if __name__ == "__main__":
model_type = "base"
cnhubert_model_path = "pretrained_models/chinese-hubert-base"
try:
if model_type == "base":
model_path = "pretrained_models/Muyan-TTS"
elif model_type == "sft":
model_path = "pretrained_models/Muyan-TTS-SFT"
else:
print(f"Invalid model type: '{model_type}'. Please specify either 'base' or 'sft'.")
print(f"Model downloaded successfully to {model_path}")
except Exception as e:
print(f"Error downloading model: {str(e)}")
asyncio.run(main(model_type, model_path))
ポイントはこの部分
async def main(model_type, model_path):
tts = Inference(model_type, model_path, enable_vllm_acc=False)
wavs = await tts.generate(
ref_wav_path="assets/Claire.wav",
prompt_text="Although the campaign was not a complete success, it did provide Napoleon with valuable experience and prestige.",
text="Welcome to the captivating world of podcasts, let's embark on this exciting journey together."
)
output_path = "logs/tts.wav"
ref_wav_path
音声ファイル、prompt_text
がその音声ファイルのテキストになっている。これを「リファレンス」音声として、text
で指定されたテキストを生成する。
リファレンス用のオーディオはここにある
生成後に聴き比べてみると良い。リファレンスの声で生成されているのがわかる。
from IPython.display import Audio
display(Audio("assets/Claire.wav"))
display(Audio("logs/tts.wav"))
実際に生成された音声はこちら
APIサーバを起動するコードも用意されている
トレーニング用のコードも用意されているけど、これは話者の声だけを学習するってことかな?
まとめ
特定用途に特化して学習するってのはいろいろなユースケースに展開できそう。