Irodori-TTS:GPU 非常駐 Flask サーバ

この構成では Flask + Waitress だけを常駐させます。音声合成の要求を受けるたびに infer.py を別プロセスで起動し、終了時に CUDA コンテキストを破棄します。したがって、待機中の Irodori-TTS は GPU メモリを占有しません。

Windows CLI ──HTTP──> Flask + Waitress (常駐・GPU非使用)
                                └─> infer.py (要求ごとにGPUロード→合成→終了)

配置

サーバ側では、Irodori-TTS の公式リポジトリを /opt/irodori-tts に置き、その直下に server/ 内の 3 ファイルをコピーします。

サーバ上のパス

内容

/opt/irodori-tts/irodori_tts_flask.py

常駐する OpenAI 風 API。torch を import しない。

/opt/irodori-tts/irodori_tts_once.py

1 回だけ CLI を実行して終了する runner。

/opt/irodori-tts/infer.py

公式 Irodori-TTS CLI。

/opt/irodori-tts/voices/

登録済み参照音声。ファイル名が voice ID になる。

/opt/irodori-tts/hf-cache/

モデル・codec のディスクキャッシュ。

/etc/systemd/system/irodori-tts.service

systemd 定義。

クライアント用の irodori_tts_api.py は Windows 側の任意のフォルダへ置きます。

サーバへの導入

以下は usrv18 での手順です。Irodori 専用環境にし、Qwen ASR の環境とは混ぜません。

sudo mkdir -p /opt/irodori-tts
sudo chown tkamiya:tkamiya /opt/irodori-tts
git clone https://github.com/Aratako/Irodori-TTS.git /opt/irodori-tts
cd /opt/irodori-tts
uv sync --extra cu128
uv pip install --python .venv/bin/python Flask waitress
mkdir -p voices hf-cache

この配布物の server/irodori_tts_flask.py と server/irodori_tts_once.py を /opt/irodori-tts/ にコピーし、サービス定義も配置します。

cp server/irodori_tts_flask.py server/irodori_tts_once.py /opt/irodori-tts/
sudo cp server/irodori-tts-flask.service /etc/systemd/system/irodori-tts.service

まず、サービス化の前に CLI 単体で GPU 動作を確認します。

cd /opt/irodori-tts
HF_HOME=/opt/irodori-tts/hf-cache \
IRODORI_ATTENTION_BACKEND=sdpa \
.venv/bin/python infer.py \
  --hf-checkpoint Aratako/Irodori-TTS-v4.1-Small \
  --text 'これは Irodori-TTS の GPU テストです。' \
  --no-ref \
  --model-device cuda --codec-device cuda \
  --model-precision bf16 --codec-precision bf16 \
  --output-wav test.wav

初回はモデルと codec をディスクへ取得します。2 回目以降は hf-cache が使われ、ネットワーク接続は不要です。

systemd の起動

sudo systemctl daemon-reload
sudo systemctl enable --now irodori-tts
sudo systemctl status irodori-tts
curl http://127.0.0.1:8002/health
curl http://127.0.0.1:8002/v1/models

LAN 上の Windows から呼ぶには、既存の公開方針と同じようにポート 8002 を許可します。

sudo firewall-cmd --permanent --add-port=8002/tcp
sudo firewall-cmd --reload

待機中に VRAM を使わないことの確認

nvidia-smi
watch -n 1 nvidia-smi

合成中だけ infer.py のプロセスが GPU メモリを使用します。応答が返った後にはそのプロセスが終了するため、待機状態にモデルは残りません。

参照音声の登録

参照音声はサーバ側に置きます。teacher.wav を置けば、API/CLI では voice: "teacher" または --voice teacher と指定します。

cp /path/to/teacher.wav /opt/irodori-tts/voices/teacher.wav
curl http://127.0.0.1:8002/v1/audio/voices

--voice none は参照音声なしです。Voice Design を使う場合は caption を指定します。

Windows クライアント

python irodori_tts_api.py --health
python irodori_tts_api.py --list-voices

python irodori_tts_api.py ^
  --text "統計力学の講義を始めます。" ^
  --voice teacher ^
  --caption "落ち着いた、明瞭な講義調の日本語。" ^
  --output lecture.wav

参照音声なしの場合:

python irodori_tts_api.py ^
  --text "これは音声合成の確認です。" ^
  --voice none ^
  --caption "明るく自然な日本語の女性話者。" ^
  --output sample.wav

長い本文は --text-file narration.txt で渡せます。通常の RF モデルは品質確認後に既定ステップ数を使うのが安全です。低頻度利用で速度を優先する場合は、--sway --num-steps 6 などを試せます。

API 形式

POST /v1/audio/speech に次の JSON を送ると WAV バイト列が返ります。

{
  "model": "irodori-tts",
  "input": "こんにちは。",
  "voice": "teacher",
  "response_format": "wav",
  "irodori": {
    "caption": "落ち着いた講義調。",
    "num_steps": 40
  }
}

この初期版では、GPU 非常駐を優先して、WAV 出力とサーバ側に登録済みの単一参照音声に絞っています。Flask は threads=1、さらに推論ロックを持つため、複数要求が来ても GPU に複数モデルを同時ロードしません。

障害時

sudo systemctl status irodori-tts
journalctl -u irodori-tts -n 100 --no-pager
curl -sS http://127.0.0.1:8002/v1/audio/voices

Blackwell で optional な FlashAttention カーネルに起因する問題が出ないよう、サービスでは IRODORI_ATTENTION_BACKEND=sdpa を指定しています。安定動作の確認後、より高速な attention backend を試す場合だけこの行を外してください。