リアルタイム通信 — WebSocket・gRPC ストリーミング・WebRTC
リアルタイムチャネルを測り、音声フレームを送る
一言でいうと
リアルタイムチャネルは、平均ではなくレイテンシ分布のテールと再接続率で見ます。音声フレームは20msの拍を守って送り、再生バッファーで途切れと遅延を引き換えにします。
なぜ必要なのか
リアルタイムチャネルの障害は、ほとんどが「たまに」起こります。1%のフレームが300ms遅れても、平均レイテンシはほとんど変わらないのに、会話は途切れます。接続数の指標は正常なのに、再接続が1分に数千回起こっているかもしれません。音声AIサービスでは、ここに拍が加わります。マイクは20msごとにフレームを作り、認識エンジンと再生器は、その拍を期待します。拍を破ると、受け取る側のバッファーがあふれたり空になったりして、音が飛んだり途切れたりします。
どう動くのか
フレームの計算: 音声認識がよく受け取る形式は、16kHz、16ビット、モノラルです。1秒で32,000バイト(256kbps)で、20msのフレーム1つは、320サンプル、640バイトです。Opusでエンコードすると、音声は数十kbpsに減ります。フレームを送るときは、締め切りの時刻を絶対時刻(開始 + i × 20ms)で決める必要があります。送るたびに20ms眠る方式は、エンコードに使った時間が毎回足されて、1秒に数百msずつずれていきます。
レイテンシの分布: 往復のレイテンシは、送った瞬間の単調時計をフレームヘッダーに書き、エコーが戻ってきた瞬間との差で測ります。片方向のレイテンシは、2台の機械の時計が合っている必要があり、はるかに難しくなります。集めたサンプルは、p50・p95・p99で要約します。最近傍順位方式は、並べ替えた値のceil(p/100 × n)番目を選ぶので、実際に観測された値だけを報告します。複数のサーバーのp99を平均すると意味のない数字になるので、サーバーごとにヒストグラムを集めて合算してから、パーセンタイルを計算する必要があります。
ジッター: RFC 3550の6.4.1節は、到着間隔のジッターを、連続した2つのパケットの転送時間の差Dの絶対値で、J = J + (|D| − J)/16を繰り返して推定します。1/16は、ノイズを減らすゲインです。ブラウザーのWebRTC統計(getStats)は、受け取るRTPストリームごとに、jitter、packetsLost、jitterBufferDelay、concealedSamplesのような値を出し、相手が報告したroundTripTimeも出します。
再生バッファー: 受け取る側は、最初のフレームが届いたあとで、バッファーの時間だけ待ってから、20msごとに1つずつ再生します。i番目のフレームが、その再生時刻より遅く来ると、ないのと同じです。バッファーを増やすと、遅いフレームは減りますが、すべての音がその分遅れます。TCPの上のWebSocketは、失ったものがないのに、一度止まるとそのあいだのフレームが一度に遅れて届くので、同じ途切れの割合を守るには、止まった時間の分のバッファーが必要です。順序と再送を要求しないWebRTCのデータチャネルやRTPは、失ったものだけを失います。
チャネルの観測: リアルタイムチャネルで見る数字は、5つです。
| 指標 | 理由 |
|---|---|
| 接続準備時間(ハンドシェイク・ICE・DTLS) | ユーザーが最初に待つ時間 |
| メッセージのレイテンシp50・p99 | 平均の陰に隠れるテール |
| 再接続率とクローズコードの分布 | 切断がどこで、なぜ起こるのか |
| 購読者ごとのキューの長さ・捨てた数 | 遅いコンシューマー |
| pingの往復時間 | ネットワークの状態と、死んだ相手 |
測り方の落とし穴: 負荷生成器が、応答を待ってから次のリクエストを送ると、サーバーが止まっているあいだに送るはずだったリクエストが、まるごと測定から抜けます(coordinated omission)。拍を守る送信器、つまり前の累積誤差のない送信で測ってはじめて、停止がテールにきちんと捉えられます。また、レイテンシは、同じ機械の単調時計で測る必要があります。壁時計は、NTPが途中で直すと逆戻りすることもあり、負のレイテンシが出ます。
観測する数字には、タグを付けます。どの伝送路(WebSocket・WebRTC)か、どの地域とネットワークの種類(Wi-Fi・LTE)かを一緒に残してはじめて、全体のp99が悪化したときに、どのグループのテールなのかを切り分けられます。
再接続率も、同じように見ます。接続数が一定に見えても、1分あたりの再接続数とクローズコードの分布を別に数えなければ、1%のユーザーが30秒ごとに切れてはつながる状況が、指標の陰に隠れます。
現場での姿
音声AIの体感レイテンシは、チェーンの合計です。20msのフレームをためる時間、ネットワーク、発話の終わりの検出、認識の途中結果、言語モデルの最初のトークン、合成の最初の断片、再生バッファーです。ITU-T G.114の言う片方向150msは、人どうしの通話の基準で、音声AIは、その上に処理時間が載ります。そのため、伝送路で節約できる数十msが重要で、その数十msを測るツールが先に必要です。このラボの数字は、音声AIコースで、認識・合成をこの伝送路の上に載せるときの基準線になります。
次のラボですること
16kHzのWAVを20msのフレームに切り、累積誤差なしに拍を守って送り、パーセンタイルとRFC 3550のジッターを計算します。WebSocketとWebRTCデータチャネルで、同じフレームの往復レイテンシを測り、Opusメディアトラックで音を送って48kHzで受け取ることを確認したあと、到着の記録から、再生バッファーのサイズを計算します。