ライブ翻訳の遅れのほとんどは待ち時間です。ストリームを待ち、次の語を待ち、文の区切りを待ちます。利用者が操作できるのは遅延モードだけで、遅延を減らすか、修正を減らすかを選べます。
翻訳付きのライブ字幕を読む視聴者は、話者が話してから数秒遅れて各行を目にします。この遅れは一つではなく、いくつもの段階が連なって積み重なったものです。その大半は何らかの待ち時間です。どの待ちがどれにあたるかを知っておくと、遅延モードを選ぶのが簡単になり、読み手として何をいつ表示すべきかが開発者にも分かります。
まず目安を示しておきます。人間の同時通訳者は、通常、話者の2〜4秒後を話します。通訳者はこの間隔を「ear-voice span」と呼びます。動詞が文末に来る言語では、動詞を待つのではなく予測したり、文を単独で成り立つ節に区切ったりして対応します。1〜2秒の遅れはソフトウェアの欠陥ではなく、非常に優れた人間がしていることとほぼ同じです。
VocalStack では、すべてのリアルタイム文字起こしが同じ段階を同じ順序で通ります。各段階は、その前の段階を待ちます。
原文のテキストは、話されるのとほぼ同時に読み手に届きます。翻訳は1〜2秒遅れて続き、読み上げられる文は翻訳のあとに来るため、音声クリップは必ず最後に届きます。ただし、最初に目に見える効果は音声よりずっと前に現れます。テキストそのものが動くのです。
ライブ文字起こしで最初に気づくのは、直近の語が動くことです。フレーズが現れ、変わり、やがて落ち着きます。これは下書きの段階が働いているためで、どの音声認識にも当てはまる理由があります。
認識器は、ある語を、その後に続く語を見て確定させます。「I scream」と「ice cream」は、次の語が届くまで同じ音に聞こえます。末尾の「s」が、この語に属するのか次の語に属するのかも分かりません。語の右側に音声がないうちは、その綴りは推測にすぎません。ですからライブ文字起こしの直近の語は、常に最も不確かな語です。下書きとは、この推測を隠さずに早めに見せたものにすぎません。
各下書きは、ライブ部分、つまり最後の確定以降に聞こえた、まだ変わりうる語を丸ごと置き換えます。確定は最終的なものです。変わることはなく、語ごとの時間情報を持ち、番号は欠番なく振られるので、読み手は取りこぼしに気づけます。
開発者にとって、リアルタイム API が求める規則はこれ一つです。確定したセグメントをすべて描画し、その後ろに最新の下書きを描画します。確定が届いたら下書きを消します。下書きを追記していくと、重複したテキストやちらつきが生じます。確定によって末尾が消費されるのです。WebSocket チュートリアルは、まさにこの仕組みに基づいて読み手を作ります。
ホスト側では、語が動くのが低遅延の代償です。フレーズが終わる前に語を見せるからこそ、文字起こしがライブらしく感じられます。ただし翻訳はこの手が使えません。語は半分の文から推測できても、翻訳は推測では成り立たないからです。
語順こそが、翻訳が下書きに追いつけない理由です。ドイツ語では動詞が節の末尾に来ることがあり、日本語も動詞を最後に置きます。どの翻訳者も、忠実に訳すには節全体が必要です。語ごとに訳すと、節が閉じるまで読めない断片を読み手に渡すことになります。ドイツ語は、ソフトウェアが試みるずっと前から、通訳者に動詞を待たせてきました。
そのため VocalStack は、セグメントではなく文を翻訳します。文はデフォルトでオンになっており、オンの間は、サーバーが確定した行を一つの文にまとめ、その文全体を翻訳します。文が開いている間、その翻訳は暫定です。文が閉じると、翻訳は確定します。読み手は文ごとに一つの項目を持ち、更新が届くたびにそれを置き換えます。
読み上げはさらに待ちます。閉じた文だけが読み上げられます。まだ変わっている文は、修正のたびに音声を作り直すことになるからです。長い文は小分けにして読み上げるので、残りの部分を作っている間に最初の部分を再生できます。
文のモードをオフにすると、代わりに確定ごとに独自の翻訳フレームが付きます。この経路は何も待ちませんが、文単位のほうがはるかに読みやすくなります。
ここで挙げた待ち時間はすべて、音声が VocalStack に届いた瞬間から計測されます。多くの配信では、音声はすでに届いた時点で遅れていたのです。
音声源がマイクではなくストリームの場合、文字起こしの前から音声はすでに遅れています。ストリームが公開している最新の時点、つまりライブの最先端から後ろにずれているのです。
一般的な HTTP 音声ストリーム、つまりほとんどのインターネットラジオ局が公開している形式は、通常1〜3秒遅れて流れます。サーバーはバーストバッファを持ちます。直近の音声を数秒分まとめて一度に送り、新しく接続したリスナーのプレーヤーが止まらずに再生を始められるようにするのです。すべてのリスナーは、VocalStack を含め、その分だけ後ろから参加します。HLS はさらに遅れます。そのプレイリストは、クライアントをライブの最先端から3セグメント後ろに置くため、セグメントの長さによっては数秒から30秒ほどの遅れになります。標準の DASH は通常、HLS と同じ程度になり、低遅延版だけがそれより大幅に短くなります。局の「ライブ」ストリームは、いわば「最新」の手紙のように、ライブと呼ばれているにすぎないことがあります。
これらの数字はおおよそのものであり、遅れはストリームに属し、文字起こしには属しません。VocalStack 側のどの設定でも、その秒数を取り戻すことはできません。イベントにとってその数秒が重要なら、公開ストリームではなく、マイクやエンコーダーから音声を入れてください。ストリームの遅れは、VocalStack が一語も聞く前に確定しています。実際に動かせるのは、遅延モードだけです。
遅延モードが行うことは一つだけです。遅れと精度のバランスを決めます。この設定は、ライブ文字起こしを作成するときは「Advanced」の下にあり、実行中は「Speed」タブにあります。そこではチップが AUTO、SPEED、ACCURACY と表示されます(Fast は SPEED と表示されます)。API では、session.update でストリーム中にモードを変更できます。
トレードオフは名前が示すとおりです。Fast は文字起こしを早く出しますが、より多くを修正します。Accuracy は少しだけ時間をかけ、修正を少なくします。翻訳字幕を読む着席した観客は、一秒の追加遅れにはめったに気づきませんが、変わり続ける語には気づきます。ですから、遅れのグラフが平らなままであれば、Accuracy のほうが親切な設定であることが多いのです。Auto は、何をしているかを隠しません。ギャップを埋めるために速めた行には、ホストの文字起こしに FAST MODE のバッジが付き、その箇所では精度が下がる可能性があるという注記が出ます。
どのモードでも、最初の一語の前に文字起こしの準備ができている必要があります。そして、その準備にかかる遅れは、この流れの中で一度だけ支払う遅れです。
プランによっては、ライブ文字起こしの開始に数秒かかります。かかる時間はプランによって異なり、料金ページの Start-up speed の行には、従量課金でのコールドスタート最大15秒から、Enterprise での常時ウォームまでが記載されています。
API では、この待ち時間は、セッションの開始中に届く session.loading フレームとして現れ、その後 session.ready が届きます。クライアントは session.ready の後にだけ音声を送ります。その間にリンクを開いた視聴者には、「Live. The first line appears in a moment.」と表示されます。文字起こしが動き出せば、この遅れは過ぎたものです。残る問題は、残っている遅れをどれだけ抱えるかだけです。
ライブ文字起こしの実行中、ホストの「Speed」タブには、これらすべてを足し合わせた結果が表示されます。話者と文字起こしテキストの間の現在のギャップが、モードのチップとともに示され、録音全体にわたるそのギャップのグラフが、平均値と最大値とともに表示されます。文字起こしそのものでは、視聴者に届くのが遅れた行に、話された時点から届くまでの秒数を示すバッジが付きます。
グラフが低く平らなままなら、そのモードは音声に合っています。グラフが上がり続けるなら、パイプラインが遅れ始めています。Accuracy で上がり続けるなら、Auto に切り替えるタイミングかもしれません。Auto は、ギャップが縮まるまで、精度を少し犠牲にして速さを優先します。
開発者は、代わりに一つの数値を得られます。リアルタイムセッションが終わると、session.done が stats.realtimeFactor を返します。これは、文字起こしした音声の長さを、その文字起こしに費やした時間で割った値です。注意が一つあります。音声認識の文献では、リアルタイムファクターは通常その逆数を指し、処理時間を音声時間で割った値で、小さいほど良いとされます。VocalStack は逆の向きで報告するため、ここでは大きいほど良くなります。ライブセッションは1付近にあり、1未満は、音声がパイプラインの文字起こし速度より速く届いたことを意味します。
これらの秒数は、どれも不可解なものではありません。一部はストリームに属し、一部は次の語を待つ語に属し、一部は翻訳に必要な文に属し、残りは選んだ遅延モードに属します。APIリファレンスにはフレーム単位の詳細があり、トップページのデモでは、この流れ全体が動いている様子を見られます。