株式会社ホコサキ

ローカル音声対話パイプラインを自前で動かして分かったこと

天京祐輔
天京祐輔
ローカル音声対話パイプラインを自前で動かして分かったこと

ElevenLabs や OpenAI Realtime API を使えば、音声対話エージェントはほぼコピペで動きます。
でも「データを外に出せない」「従量課金が怖い」「自社サーバーで完結させたい」という状況は、実務ではそれなりに出てきます。

そこで試したのが huggingface/speech-to-speech です。
マイク入力から音声出力まで、STT・LLM・TTS をローカルで繋いだパイプラインを自前で動かせるリポジトリで、HuggingFace が公式にメンテしています。

実際に手元で動かしながら分かったことを正直に書きます。
環境構築のハマりどころ、モデル選定の現実的な落とし所、クラウド API との体感差、そして「社内FAQ対応に転用しようとしたときに何が足りなかったか」まで踏み込みます。
「ゼロコストで ElevenLabs の代替が作れる」という甘い話ではないのですが、使えるシーンは確実にあります。

ローカル音声対話パイプラインの全体像と、問いの立て方

リポジトリの構成はシンプルな一本道です。
マイク入力 → VAD(音声区間検出)→ STT(音声認識)→ LLM(応答生成)→ TTS(音声合成)→ スピーカー出力、という順番でデータが流れます。

面白いのは、各コンポーネントがプロセス間キューで非同期に繋がっている点です。
STT が文字起こしを終えた瞬間に LLM が推論を始め、LLM がトークンを吐き始めた瞬間に TTS が音声を生成し始める、というストリーミング設計になっています。
「全部終わってから喋り始める」ではなく、ある程度リアルタイムに近い応答が実現できているのはこの設計のおかげです。

リポジトリ自体は 2024〜2025 年にかけて活発に更新されていて、デフォルト構成がかなり変わっています。
2024 年時点では STT が Whisper、TTS が Parler-TTS でしたが、現在のデフォルトは STT が Parakeet TDT、TTS が Qwen3-TTS に変わっています。
ブログ記事や Issue の内容が現行バージョンと噛み合わないケースが頻繁にあるので、README を読む際はいつ書かれた情報かを必ず確認してください。

ここで問いを一つ立てておきます。
「ElevenLabs や OpenAI Realtime API の代替を、自前で構築できるか?」
結論を先に言うと「条件付きでイエス、ただしトレードオフは無視できない」です。
その条件が何かを、環境構築・モデル選定・レイテンシの順に掘り下げていきます。

環境構築と最小構成での起動

まず GPU の話から始めます。
CPU だけでも動きますが、実用的なレイテンシを得るには VRAM 8GB 以上の GPU が現実的な最低ラインです。
STT・LLM・TTS を同一マシンで同時に動かすと、モデルサイズの合計がすぐ 8GB を超えます。
16GB あれば選択肢が広がり、24GB あれば余裕を持って動かせます。

起動までの最短手順はこうなります。

# リポジトリをクローン
git clone https://github.com/huggingface/speech-to-speech.git
cd speech-to-speech

# 依存ライブラリをインストール(Linux / CUDA 環境の場合)
pip install -e .

# デフォルト構成で起動(Parakeet TDT + OpenAI互換API + Qwen3-TTS)
python s2s_pipeline.py \
  --stt_device cuda \
  --tts_device cuda

LLM はデフォルトで OpenAI 互換 API を向く設計になっています。
ローカルで完結させたい場合は、Ollama を立ち上げてエンドポイントを向けるのが一番楽です。
ただし LLM 関連のフラグ名(エンドポイント指定・モデル名の渡し方)はリポジトリの更新で変わっている可能性があるため、実際のオプション名は起動前に README の最新版を確認してください。

# Ollama でモデルを起動しておく(別ターミナルで)
ollama run llama3

# LLM を Ollama に向ける構成例(フラグ名は README で要確認)
python s2s_pipeline.py \
  --stt_device cuda \
  --tts_device cuda \
  --lm_device cuda
# --lm_url や --lm_model_name の正確な書式は
# 現行 README の「Language Model」セクションを参照

よくハマるポイントを先に書いておきます。

--stt_device / --lm_device / --tts_device の明示忘れ が一番多いです。
これらを省略すると CPU で動いてしまい、レイテンシが数十秒単位になります。
GPU 環境でも明示しないと警告なく CPU に落ちるので注意が必要です。

次が Qwen3-TTS の CUDA バージョン問題 です。
Linux 環境では Qwen3-TTS の GGML バックエンドが CUDA 12.8 向けのホイールを要求します。
CUDA 12.8 以外の環境では、インストール前に HuggingFace のホイールハウスから対応するホイールを手動で入れる必要があります。
README の「CUDA Note for Qwen3-TTS」セクションに手順が書いてあるので、必ず確認してください。

もう一つが CUDA バージョンと PyTorch のミスマッチ です。
pip install だけでは環境によって動かないことがあります。
手元の CUDA バージョンを確認してから、対応する PyTorch を先に入れておくのが安全です。

モデル選定:「全部ローカルで最高品質」が崩れるまで

動かし始めると、すぐ現実の壁にぶつかります。
「全コンポーネントをローカルで最高品質に」を狙うと、VRAM が足りなくなります。
各コンポーネントの選定で何を基準にするか、整理しておきます。

STT の選択軸

  • Parakeet TDT:英語特化・低レイテンシ。現行デフォルト。日本語は非対応
  • Whisper large-v3:多言語対応・日本語精度が高い。ただし VRAM 消費が大きく、推論も重い
  • Whisper small / base:軽量で速いが、日本語の精度は落ちる。プロトタイプ確認用として割り切るなら十分

日本語で使いたい場合は Whisper 一択です。
サイズは用途に応じて選びますが、日本語の実用精度を求めるなら large-v3 が無難です。

LLM については、VRAM 8〜16GB 帯では Llama 3 8B や Mistral 7B 程度が現実的な選択肢です。
量子化(4bit / 8bit)を使えばさらに小さくできますが、応答品質とのトレードオフがあります。
Ollama 経由で OpenAI 互換 API として繋ぐ構成が最も扱いやすく、モデルの差し替えも楽です。

TTS については、Parler-TTS Mini(880M パラメータ)と Large(2.3B パラメータ)の使い分けが基本になります。
Mini は軽量で速く、リアルタイム用途に向いています。
Large は品質が高い分だけ重く、VRAM に余裕がないと他のコンポーネントを圧迫します。
現行デフォルトの Qwen3-TTS は品質面での進化がありますが、日本語音声への対応状況は現時点の公開情報では確認できていないため、日本語用途では別途検証が必要です。

STT に Whisper を使いたい場合と、TTS に Parler-TTS Mini を指定したい場合のフラグ例はこうなります。

python s2s_pipeline.py \
  --stt_backend whisper \
  --stt_model_name openai/whisper-large-v3 \
  --stt_device cuda \
  --tts_backend parler \
  --tts_model_name parler-tts/parler-tts-mini-v1.1 \
  --tts_device cuda \
  --lm_device cuda

VRAM が 8GB しかない場合は、Whisper small + Llama 3 8B(4bit 量子化)+ Parler-TTS Mini の組み合わせが現実的な落とし所です。
「最高品質」は諦めて、「動く構成」を先に確保する方が検証が進みます。

レイテンシとコストの現実:クラウドAPIと比べてどうか

ローカル構成のエンドツーエンドのレイテンシは、正直クラウド API には勝てません。
VAD・STT・LLM 推論・TTS の各ステージが直列に並ぶため、ストリーミング設計でも体感的な応答開始まで時間がかかります。
どのくらいかは GPU の性能とモデルサイズに大きく依存するため一概には言えませんが、「クラウド API のような即応感」を期待すると裏切られます。

OpenAI Realtime API はどうかというと、レイテンシは確かに速いです。
ただしコストが課題でした。
2024 年 10 月のベータ時点では音声入力 $100 / 出力 $200(1M トークンあたり)という価格設定で、ある検証動画での報告によると「1分の会話で 70 セント近くかかった」という事例も出ていました。
その後価格は下がり続け、2025 年 8 月の GA 時点では入力 $32 / 出力 $64 まで下落しています。
それでも、継続的に大量の音声対話を処理するシステムでは、従量課金の積み上がりは無視できません。

ローカル構成のコストは、GPU サーバーの固定費と電力費になります。
「ゼロコスト」という言い方は語弊があって、初期投資・電力・保守の総所有コストで考える必要があります。
クラウド GPU インスタンスを借りる場合は時間課金になるため、稼働率が低ければローカルの方が割高になることもあります。

クラウド API が有利なのは「低レイテンシが必要」「スパイク的な負荷がある」「初期投資を抑えたい」というケースです。
ローカル構成が有利になるのは「大量・継続的な処理をする」「データを外部に出せない」「長期的な固定費で運用したい」というケースです。
どちらが正解かは用途次第で、「とにかくローカルで」という判断は慎重にした方がいいです。

業務応用への転用:「動くデモ」から「使えるシステム」へ

デモが動いた段階で、社内FAQ対応や受付自動化への転用を考え始めました。
そこで気づいたのは、パイプライン自体の完成度よりも「業務に必要な周辺機能」が何も揃っていないという点です。

まず困るのがウェイクワード検出です。
現状の構成は「常時マイクを聞いている」か「ボタンを押している間だけ録音する」かのどちらかで、受付端末のように「Hey, ○○」で起動させたい場合は Porcupine や openWakeWord といった別のライブラリを前段に組み込む必要があります。

複数人が使う環境では話者識別も問題になります。
「誰が話しているか」を区別できないとセッション管理ができないため、pyannote.audio などを組み合わせる方法が候補に上がりますが、リアルタイムパイプラインへの統合は一手間かかります。

日本語 TTS は現時点で最大の障壁です。
Whisper による日本語 STT は実用レベルに達していますが、Parler-TTS の学習データは英語圏のオーディオブックが中心で、日本語音声の生成は想定されていません。
Qwen3-TTS の日本語対応状況は現時点の公開情報では確認できていないため、日本語で喋るシステムを作りたい場合は TTS だけ Style-Bert-VITS2 や VOICEVOX といった日本語特化のエンジンに差し替える構成を別途検証する必要があります。

社内 FAQ に答えさせるには、LLM に社内ドキュメントを参照させる RAG の仕組みも要ります。
パイプラインの LLM 部分を RAG 対応のエンドポイントに差し替えるのが現実的ですが、音声対話特有の「短い応答にまとめる」設計も合わせて考えないと、長文を読み上げるだけのシステムになってしまいます。

一方で、ローカル構成が明確に有利なシーンもあります。
医療・法務・社内機密を扱う業務では、音声データをクラウドに送れないケースが多いです。
そういった用途では、多少レイテンシが高くても「データが外に出ない」という保証の方が価値があります。

「動くデモ」と「使えるシステム」の間には、このくらいの距離があります。
ただ、パイプラインの骨格は huggingface/speech-to-speech が提供してくれているので、追加実装の起点としては悪くない選択肢です。
次に手を動かすとすれば、日本語 TTS の差し替えとウェイクワード検出の統合を先に検証するのが現実的だと思っています。


株式会社ホコサキは山口県宇部を拠点に、Web制作・業務システム開発・AI活用支援を手がけています。
「ローカル AI を自社の業務に組み込みたい」「クラウド API とのトレードオフを整理したい」といった相談も受け付けています。
気軽に お問い合わせ からどうぞ。

    ローカル音声対話パイプラインを自前で動かして分かったこと | 株式会社ホコサキ