← ブログに戻る

音声AIの525ms壁を300ms未満にする3手法

音声AIのカスケード構成(STT→LLM→TTS)は、最速のパーツをそろえても合計525msから逃げられません。

STT 200ms、LLM 150ms、TTS 75ms、ネットワーク 50ms、VAD等 50ms。全部足すと525ms。F1マシンのパーツを最速で買いそろえても、組み立てたら軽自動車より遅い。

300msの崖を物理で越える。

この時点で無理です。

過去記事の「voice AI TTFBを100msに詰めた実測」ではTTFBという1指標に絞りました。今回はカスケード全体の525ms内訳を分解する。体感で300ms未満に落とすまでに私が回した3手法をまとめます。

そもそも525msの内訳を疑う

議論の起点は、この表です。

コンポーネント最速通常最悪
STT200ms350ms500ms
LLM150ms500ms1,000ms
TTS75ms200ms300ms
ネットワーク50ms150ms300ms
その他(VAD等)50ms100ms200ms
合計525ms1,300ms2,300ms

Deepgram Nova-3のsub-300ms STT、ElevenLabs Flash v2.5の75ms TTFB、東京リージョンのGPUホスティング。この最速セットを組んでもカスケードだと525msから動かない。私が最初にこの数字を見たとき、「じゃあ結論は統合モデル(OpenAI Realtime API)しかないな」で終わらせかけました。しかし現実の運用では、既存のSTT/LLM/TTSベンダーとの契約や、ドメイン特化のプロンプト資産をそのまま使いたい事情があります。統合モデルに一足飛びに移れないケースが多い。そこでカスケードのまま300ms未満に見せる3手法が要ります。

手法1: 部分ストリーミング(体感で500ms→200ms)

いちばん効いたのがこれでした。

逐次処理の発想を捨てる。20-30msのフレーム単位で全ステージを並行に走らせます。STTが認識した瞬間からLLMがトークン生成を始める。LLMの最初の1文が出た瞬間からTTSが合成を始める。実装はPipecat + LiveKitの組み合わせが現時点で最有力です。

# Pipecat文単位パイプラインの骨格
class VoiceLoop:
    async def on_stt_final(self, text):
        async for token in self.llm.stream(text):
            self.sentence_buffer.append(token)
            if self.sentence_ended(token):
                audio = await self.tts.synthesize(self.flush_buffer())
                await self.output.send(audio)

体感レイテンシの計算式が変わります。逐次だと STT + LLM_all + TTS_all + Network の全部和。文単位ストリーミングだと STT + LLM_1sentence + TTS_TTFB + Network に短縮されます。LLMが全文を出し終える前に1文目の音声が鳴り始める。ユーザーの体感は「最初の音が鳴るまでの時間」になる。私の環境(東京、Pipecat + LiveKit + Deepgram Nova-3 + Claude 3.5 Sonnet + ElevenLabs Flash v2.5)で計測したら、体感525ms → 210ms。LiveKitのSFU(Selective Forwarding Unit)は音声パケットを再エンコードせずに転送します。従来のMCU方式でかかっていた数十msのオーバーヘッドが消える。ネットワーク層の50msが実質そのまま活きます。

WebRTCの初期セットアップで3日溶かしたのは秘密です。

ICEネゴシエーション、STUN/TURN、DTLSハンドシェイク。IKEAの家具を説明書なしで組み立てる体験と同じ。完成すると最高だけど途中で何度か泣きたくなります。

手法2: 予測発話(初回ターン+300msを埋める)

DEV.to CloudXの30+スタックベンチマークで判明した現象があります。会話の初回ターンだけ、システムプロンプト処理でfirst-tokenまでに追加300msかかる。KVキャッシュがまだ効かないためです。2回目以降のターンは手法1で210msに収まる。でも初回ターンだけ510msに戻る。ユーザーが最初に喋りかけた瞬間だけ体験が崩れます。

ここで私が入れたのは「予測発話」です。ユーザーの発話終端をVADが検出した瞬間に、LLMを待たずに定型フィラーを再生します。

# 予測発話のトリガ
async def on_vad_end(self):
    if self.is_first_turn:
        await self.output.send(self.filler_cache["ええと"])
    await self.llm.start_generation(self.stt_result)

「ええと」「はい、それはですね」といった短いフィラーを事前にTTSで生成する。オンメモリキャッシュしておく。VAD終端検出から30-50msでフィラーが鳴ります。ユーザーは「返事が始まった」と感じる。裏でLLMが本命の応答を生成している。フィラーの再生が終わる頃に本文が始まる。これは知覚のトリックです。実際のfirst-tokenは510msでも、体感TTFAは50ms。人間の会話でも「ちょっと考えるときに『えー』と言う」のは同じ機能で、脳は「相手が反応した」と受け取ります。

フィラーを入れすぎるとうるさい。

私は初回ターンだけ、成功率85%(裏のLLM生成が予測発話完了より遅い場合のみ)で発火する設計にしています。

手法3: TTS早出し(合成待ちの75msを守る)

これは地味だけど効きます。

TTSのTTFB(Time-to-First-Byte)を75-100ms前後で固定できるベンダーを選ぶ、ただそれだけです。ElevenLabs Flash v2.5、Cartesia Sonic 3、Deepgram Aura-2。この3つが2026年時点で公称75-90msに収まります(いずれも公称値、実測は往復とリージョンが上に乗る)。

厳密には手法1で計測した210msもFlash v2.5を使っています。手法3の実務的な意味は、低TTFB TTSをプロジェクト要件として固定した上で、環境ごとのTTS側の実装最適化まで踏み込む余地を作ること。構成Cの50-180msはそこまで詰めた実測で、ベンダーを選び直しただけでは210msから動きません。

比較すると自明です。

TTS公称TTFB用途
ElevenLabs Flash v2.575ms汎用・多言語(32言語)
Cartesia Sonic 3sub-90ms感情表現・42言語
Deepgram Aura-290ms(p95<200ms)Deepgram STTと同ベンダーで完結
OpenAI TTS-1200-500ms品質重視・遅い
Google Cloud TTS(Standard)150-300msレガシー統合

音質と遅延のトレードオフはあります。ElevenLabs Flash v2.5は音質がやや平坦。プロダクションでキャラクター性を出したい場面ではElevenLabs Multilingual v2(TTFBはFlash比で明らかに遅い、実測で秒級に届くケースあり)を選ぶことになる。その場合は手法1と2でカバーする範囲が広がります。私の環境ではメインをFlash v2.5に固定する。キャラクターボイスが必要な特定発話だけMultilingual v2に切り替える2系統構成にしました。切り替え自体は動的にできます。

3構成の比較表

3手法をどう組み合わせるかで実装難易度が変わります。私が試した3構成の比較です。

カスケード音声AI 3構成 - 部分ストリーミング / 予測発話 / TTS早出しの組み合わせと体感TTFA

構成部分ストリーミング予測発話TTS早出し体感TTFA実装難易度
A: 最小構成210ms
B: 初回対策入り50-210ms
C: フル装備50-180ms最高

構成AだけでもTTFAは210ms。300msの崖はここで越えます。初回ターンの510ms問題を許容できるなら、これで十分です。構成Bは初回ターンの体験を優先したいケース。私が本番運用しているのはこれです。フィラーキャッシュの管理コードが400行くらい増えますが、初回体験が変わる。構成Cは技術デモや競合比較で「体感TTFA 50ms」を出す用途向け。実装は最高難易度で、TTSベンダー切り替えの動的制御まで入ります。

「1つずつやると効かないんだよね、これ」と検証中のノートに書きました。

3手法は独立で効くわけではない。Pipecatが並列処理の基盤を持っていることが前提条件です。Pipecat無しで予測発話だけ入れても、逐次処理のせいで結局裏のLLM完了を待つことになります。

Speech-to-Speech統合モデルとの比較

「OpenAI Realtime APIに乗り換えれば全部消える」という選択肢もあります。

2026年時点でWebRTC接続時のOpenAI Realtime APIは300-600msの応答レイテンシ。カスケード + 3手法の構成B(50-210ms)に対して、統合モデルの方が実は遅い場面があります。

アーキテクチャー体感TTFA中間モデル差し替えドメイン特化
カスケード + 3手法(構成B)50-210ms○ 各層を選べる○ プロンプト+RAG自由
OpenAI Realtime API300-600ms✗ OpenAI固定△ 制約あり
Gemini Live APISub-800ms✗ Google固定△ 制約あり

統合モデルの真の強みは音声プロソディ(韻律・感情)の維持と、STTの誤認識がLLMに伝わらないこと。純粋なレイテンシだけならカスケードでも勝負できます。

何が結論だったか

私の運用結論はこれです。

  • 汎用対話・ドメイン特化が要る → カスケード + 手法1(部分ストリーミング)を優先
  • 初回ターンの体験を落とせない → 手法2(予測発話)を足す
  • 音質を落としても速度優先 → 手法3(TTS早出し)まで足す
  • 感情表現や音声完結ドメイン → 統合モデル(OpenAI Realtime API)

「525msは物理」と諦めるより、体感TTFAで測り直す方が実務では効きます。

ユーザーは合計処理時間を見ていない。

最初の音がいつ鳴ったかを見ている。

本記事の背景となる設計論(カスケード分解、ストリーミング設計、知覚ハック、フィラー戦略、Pipecat + LiveKitの構成、TTSベンダー選定基準)は、voice-ai-300ms-ux 本に章単位で置いてあります。


ken imoto · WebRTC & Voice AI engineer · kenimoto.dev

音声AIの300ms 関連書籍 音声AIの300ms 音声AI レイテンシ 設計 | Pipecat・LiveKit・Deepgram で525msの壁を突破 書籍ページを見る →