初めに
今回は、Meituan が公開した拡散ベースのゼロショット TTS モデル LongCat-AudioDiT を使って、テキストから音声を生成する方法を紹介します。
LongCat-AudioDiT は、メルスペクトログラムを介さず波形の潜在空間で直接動作する Diffusion TTS モデルです。Seed ベンチマークで SOTA を達成しており、1B と 3.5B の 2 つのチェックポイントが HuggingFace で公開されています。
今回は 3.5B モデルを RTX 4070 Ti SUPER (16 GB VRAM) で動かします。そのままでは VRAM が足りないため、bf16 で読み込む工夫が必要になります。
開発環境
- OS: Windows 11 Education (10.0.22631)
- GPU: NVIDIA GeForce RTX 4070 Ti SUPER (16 GB VRAM)
- NVIDIA ドライバ: 591.86 (CUDA 13.1 対応)
- パッケージマネージャ: uv 0.9.2
- Python: 3.12.7 (uv 自動管理)
- torch: 2.11.0+cu126
- transformers: 5.5.3
環境構築
リポジトリのクローン
git clone https://github.com/meituan-longcat/LongCat-AudioDiT.git
cd LongCat-AudioDiT
Python バージョンの固定
uv を使って Python 3.12 に固定します。
uv python pin 3.12
Python 3.14 は torch の wheel が未提供、3.13 は numba/llvmlite が不安定なため、3.12 を推奨します。
pyproject.toml の作成
requirements.txt はリポジトリに同梱されていますが、uv で PyTorch の CUDA wheel を正しく取得するには pyproject.toml が必要です。以下の内容で作成します。
[project] name = "longcat-audiodit" version = "0.1.0" description = "HuggingFace-compatible inference for LongCat-AudioDiT." requires-python = ">=3.12,<3.13" dependencies = [ "transformers>=5.3.0", "torch>=2.5.0", "torchaudio>=2.5.0", "safetensors>=0.4.0", "librosa>=0.10.0", "soundfile>=0.12.0", "numpy>=1.24.0", "einops>=0.8.0", ] [tool.uv] package = false [[tool.uv.index]] name = "pytorch-cu126" url = "https://download.pytorch.org/whl/cu126" explicit = true [tool.uv.sources] torch = [{ index = "pytorch-cu126" }] torchaudio = [{ index = "pytorch-cu126" }]
ポイントは [[tool.uv.index]] と [tool.uv.sources] の設定です。PyTorch の CUDA 対応 wheel は PyPI にないため、https://download.pytorch.org/whl/cu126 から取得するよう指定します。explicit = true により、torch と torchaudio 以外のパッケージは通常の PyPI から取得されます。
依存関係のインストール
uv sync
初回実行時は torch CUDA wheel (約 2.4 GB) を含む約 3 GB のダウンロードが発生します。
Resolved 77 packages in 1.32s Prepared 3 packages in 1m 12s Installed 57 packages in 24.19s + torch==2.11.0+cu126 + torchaudio==2.11.0+cu126 + transformers==5.5.3 ...
3.5B モデルを動かすための工夫
VRAM の問題
3.5B モデルをデフォルト (fp32) で読み込むと、DiT transformer だけで約 14 GB の VRAM を消費します。text encoder と VAE を合わせると約 17 GB となり、16 GB GPU では OOM (Out of Memory) になります。
| モデル | dtype | VRAM 概算 | 16 GB GPU |
|---|---|---|---|
| 1B | fp32 | 約 7 GB | OK |
| 1B | bf16 | 約 4 GB | OK |
| 3.5B | fp32 | 約 17 GB | NG (OOM) |
| 3.5B | bf16 | 約 9 GB | OK |
inference.py の修正
inference.py に --dtype フラグを追加し、from_pretrained に dtype を渡せるようにしました。
parser.add_argument("--dtype", type=str, default="fp32", choices=["fp32", "bf16", "fp16"], help="Dtype for loading DiT transformer / text encoder. VAE always runs in fp16.")
dtype_map = {"fp32": torch.float32, "bf16": torch.bfloat16, "fp16": torch.float16}
model = AudioDiTModel.from_pretrained(args.model_dir, dtype=dtype_map[args.dtype]).to(device)
model.vae.to_half() # VAE は常に fp16 (元チェックポイントとの数値一致のため)
VAE は to_half() で常に fp16 に変換されます。これは元の実装 (AutoencoderPretransform(model_half=True)) と数値を一致させるための仕様です。
Windows の cp932 エンコーディング問題
Windows 日本語版では標準出力が cp932 (Shift-JIS) のため、中国語テキストを print すると UnicodeEncodeError が発生します。
UnicodeEncodeError: 'cp932' codec can't encode character '\u8f6c' in position 10
inference.py の冒頭に以下を追加して解決しました。
import sys try: sys.stdout.reconfigure(encoding="utf-8", errors="replace") sys.stderr.reconfigure(encoding="utf-8", errors="replace") except (AttributeError, OSError): pass
推論の実行
中国語テキストの生成
3.5B モデルを --dtype bf16 で読み込み、APG ガイダンスで推論します。
uv run python inference.py \ --text "今天晴暖转阴雨,空气质量优至良,空气相对湿度较低。" \ --output_audio output_zh_3.5b.wav \ --model_dir meituan-longcat/LongCat-AudioDiT-3.5B \ --dtype bf16 \ --guidance_method apg
Loading weights: 100%|██████████| 1351/1351 [00:10<00:00, 131.02it/s] Text: 今天晴暖转阴雨,空气质量优至良,空气相对湿度较低。 Approx duration: 5.250s Saved: output_zh_3.5b.wav (5.21s)
初回はモデルウェイト (数 GB) が HuggingFace から自動ダウンロードされるため数分かかります。2 回目以降はキャッシュから読み込まれ、ロード時間は約 10 秒です。
英語テキストの生成
uv run python inference.py \ --text "The weather today is warm and sunny, perfect for a walk in the park." \ --output_audio output_en_3.5b.wav \ --model_dir meituan-longcat/LongCat-AudioDiT-3.5B \ --dtype bf16 \ --guidance_method apg
Text: the weather today is warm and sunny, perfect for a walk in the park. Approx duration: 4.510s Saved: output_en_3.5b.wav (4.44s)
ボイスクローン
リポジトリに同梱されている assets/prompt.wav を参照音声として使い、別のテキストを同じ声で生成できます。
uv run python inference.py \ --text "合成したい任意のテキスト" \ --prompt_text "小偷却一点也不气馁,继续在抽屉里翻找。" \ --prompt_audio assets/prompt.wav \ --output_audio output_clone_3.5b.wav \ --model_dir meituan-longcat/LongCat-AudioDiT-3.5B \ --dtype bf16 \ --guidance_method apg
--prompt_text には --prompt_audio の音声で実際に話されている内容を渡す必要があります。
実行結果
生成された音声ファイルの仕様は以下の通りです。
| 項目 | 中国語 | 英語 |
|---|---|---|
| ファイル | output_zh_3.5b.wav |
output_en_3.5b.wav |
| サンプリングレート | 24000 Hz | 24000 Hz |
| 長さ | 5.21 秒 | 4.44 秒 |
| ピーク振幅 | 0.52 | 0.56 |
| ファイルサイズ | 約 250 KB | 約 214 KB |
モデルのロード時間は約 10 秒、推論時間は 5 秒程度の音声で数秒〜十数秒でした。ODE ステップ数 (--nfe) はデフォルトの 16 を使用しています。