Intent-First Translation — 500msで意図を伝えるリアルタイム音声翻訳
課題
音声翻訳アプリは正確な翻訳を出力するが、毎回3〜5秒の沈黙が発生し会話のテンポが崩れる。この問題は翻訳品質を向上させても構造的に解消されない。
解決策
リアルタイム音声認識・LLMストリーミング出力のJSON順序最適化・WebSocket即時配信を組み合わせた3レイヤー構造により、500msで意図を表示するアーキテクチャを設計。
成果
意図表示 約500ms、翻訳表示 約800msを達成し、ほぼリアルタイムの二言語会話を実現。6つのLLMモデルのベンチマーク比較、ローカルGPUでの動作検証も実施。
課題:翻訳が正確でも会話は成立しない
Microsoft Translator、Google翻訳、AppleのAirPodsライブ通訳——主要な音声翻訳サービスはすべて同じアーキテクチャを採用しています。話し終わるのを待ち、テキストを確定し、翻訳する。
翻訳は正確です。しかし毎回3〜5秒の沈黙が生まれます。相手は「聞こえていないのかな」と不安になり、こちらは翻訳が出るまで反応できない。翻訳品質がどれほど向上しても、この会話テンポの崩壊は逐次翻訳の構造的な問題であり、精度向上では解消されません。
着想:同時通訳者はなぜ待たないのか
プロの同時通訳者は文の完結を待ちません。「We should probably reschedule the meeting to…」と聞いた時点で、**「会議の日程変更について話しています」**と伝え始めている。詳細が来る前に、まず意図を先に伝えています。
この原則をソフトウェアで再現しました。意図を先に見せ、翻訳は後から届ける。
アーキテクチャ:3レイヤーの段階的配信
Layer 1: キーワード予測 → 約0ms (辞書ベース、LLM不要)
Layer 2: 意図ラベル → 約500ms (LLMストリーミング)
Layer 3: 完全翻訳 → 約500〜800ms(LLMストリーミング続き)
Layer 1 — キーワード即時表示(遅延ゼロ)
音声認識の断片テキストに対し、辞書ベースでトピックを即座にマッピング。“meeting” → 会議、“budget” → 予算。LLMを待たずに聞き手がトピックを把握できます。
Layer 2 & 3 — JSON フィールド順序を最適化したLLMストリーミング
本プロジェクトの核心となる技術的知見です。LLMのストリーミング出力はJSONを上から順に生成します。意図ラベルと翻訳をJSONスキーマの先頭に配置することで、これらのフィールドが最初にユーザーに届きます。
{
"dialogue_act": "PROPOSAL",
"intent_label": "日程調整の提案",
"full_translation": "火曜に会議を移動しませんか...",
"confidence": 0.85,
"is_meaning_stable": true
}
翻訳フィールドを最後に配置した場合、実測で約2倍の遅延が発生しました。JSONフィールドの並び順を入れ替えるだけで、体感の翻訳表示速度が2倍に向上しています。
Partial/Finalに応じたプロンプト切替
音声認識には2種類の結果があります。
| 状態 | 目的 | 戦略 |
|---|---|---|
| Partial(発話中) | 素早く意図を表示 | 速度重視:意図 → 翻訳を先に生成 |
| Final(発話完了) | 正確な翻訳を提供 | 品質重視:文脈分析を先に実行 |
話している最中はスピード優先で大まかな意図を表示し、話し終わった時点で品質優先の正確な翻訳に差し替えます。人間の同時通訳者と同じ構造です。
システム全体のデータフロー
[ブラウザ] [バックエンド (FastAPI)] [外部API]
| | |
|-- 音声バイナリ --------->| |
| |-- 音声ストリーム -------->| Deepgram
| |<-- Partial/Final text ----|
| | |
| |-- テキスト -------------->| LLM (Gemini/Groq)
| |<-- ストリーミングJSON ----|
| | |
|<-- intent_partial -------| (WebSocketで即時配信)
|<-- translation_partial --| (WebSocketで即時配信)
|<-- intent (complete) ----| (確定結果)
JSONの各フィールドが生成された瞬間に、個別のWebSocketメッセージとしてフロントエンドへ即座に送信しています。全体の応答完了を待ちません。
LLM呼び出しの最適化
Deepgramは非常に高速にPartial結果を返すため、対策なしではLLMリクエストが毎秒数十回に達します。
- デバウンス(300ms) — テキスト更新後300ms待機してからLLMを呼び出し
- 短文スキップ — 5単語未満のPartialは処理をスキップ
- 重複チェック — 同一テキストの二重処理を防止
- 非同期パイプライン — LLM応答待ちの間も音声認識データを受信し続ける
6モデルのベンチマーク比較
| モデル | 翻訳表示速度 | 品質 | 5時間あたりのコスト |
|---|---|---|---|
| Groq / Llama 4 Maverick | 413ms | ◎ | $3.43(約515円) |
| Groq / Llama 3.3 70B | 480ms | ◎ | — |
| Groq / Llama 3.1 8B | 377ms | ○ | — |
| Groq / GPT-OSS 120B | 662ms | ◎ | — |
| Gemini 2.5 Flash Lite | 954ms | ◎ | $1.17(約175円) |
| OpenAI GPT-4o-mini | 1,976ms | ◎ | $1.74(約261円) |
Groq + Llama 4 Maverickは800+ tokens/secの推論速度で、リアルタイム用途に最適でした。フロントエンドからワンクリックでモデルを切り替えられるUIを実装しています。
ローカルGPU検証
クラウドAPIに頼らず、自宅のGPU(RTX 3060、VRAM 6GB)でGemma 3 4Bを動作させる検証を実施しました。
| 環境 | 結果 |
|---|---|
| Ollama | 単発リクエストは動作、並列リクエストでVRAM枯渇 → Windows強制シャットダウン |
| LM Studio(ヘッドレス) | 翻訳に3〜4秒の遅延、サマリー生成はロック競合でほぼ実行不可 |
結論:VRAM 6GBではリアルタイム翻訳の要件を満たせない。 12GB以上(RTX 4070クラス)であれば可能性はありますが、現時点ではクラウドAPIが現実的な選択肢です。ただし、ローカルGPUへの切替を容易にするアーキテクチャ設計としています。
デモ
技術スタック
| レイヤー | 技術 |
|---|---|
| 音声認識 | Deepgram Streaming API |
| 意図推定・翻訳 | Gemini Flash, Groq / Llama 4 Maverick |
| バックエンド | Python / FastAPI |
| フロントエンド | React + TypeScript |
| リアルタイム通信 | WebSocket |
| ストリーミングJSONパーサー | 独自のインクリメンタルパーサー |
今後の展望
- TTS連携 — 翻訳をBluetoothイヤホンで音声読み上げし、ハンズフリー翻訳を実現
- 双方向翻訳 — 日本語 ↔ 英語のリアルタイム双方向会話を通訳者なしで実現
- スマートグラス連携 — オープンソースのスマートグラス(OpenGlass, Team Open Smart Glasses)に翻訳字幕を表示
本プロジェクトの核心
この開発を通じて最も実感したこと:LLMの出力を「結果」ではなく「ストリーム」として扱うことの重要性です。JSONフィールド順序の最適化、生成途中のJSONの部分的パース、音声状態に応じたプロンプトの動的切替——いずれもLLMが「上から順にトークンを生成する」という基本的性質を活かした設計であり、この原則は翻訳に限らず広く応用可能です。
技術詳細はブログシリーズで解説しています: