OpenAI 低延遲語音 AI 基礎設施
OpenAI 採用了分離的中繼加收發器(relay‑plus‑transceiver)架構,以解決即時語音 AI 的擴展挑戰。透過將封包路由與協議終止分離,OpenAI 能在標準 Kubernetes 環境中,同時維持自然對話所需的低延遲。
在 Kubernetes 上擴展 WebRTC 的挑戰
傳統的 WebRTC 實作通常依賴「每個會話一個埠」的模型,當在 OpenAI 這樣的規模(每週活躍使用者超過 9 億)部署時,會產生重大運營障礙。此模型帶來三大限制:
- 埠耗盡: 每個服務需要管理數萬個公共 UDP 埠,增加了負載平衡器設定、防火牆策略以及部署安全性的複雜度。
- 安全風險: 大量 UDP 埠範圍擴大了可被外部存取的表面,使得網路政策更難審核。
- 自動擴縮摩擦: Kubernetes Pod 常被重新排程;若每個 Pod 必須保留並廣播一大段穩定埠範圍,彈性伸縮會變得脆弱。
雖然「每伺服器單埠」的設計可以減少埠數量,但會遭遇「狀態黏著」問題。因為 ICE(互動式連接建立)與 DTLS(資料報文傳輸層安全)是有狀態的,特定會話的封包必須始終抵達擁有該會話的處理程序,否則連線會失敗。
中繼 + 收發器 架構
為了解決上述衝突,OpenAI 放棄了通常用於多方通話的選擇性轉發單元(SFU)模型,改採 收發器模型。在此架構中,WebRTC 邊緣服務(即收發器)終止客戶端連線,並將媒體轉換為內部協議供推論與協調使用。
分離路由與終止
此設計的核心是將 中繼(路由)與 收發器(終止)分開:
- 中繼: 輕量級的 UDP 轉發層,公共足跡小。它不會解密媒體、執行 ICE 狀態機或協商編解碼器,只是讀取封包的中繼資料以判斷目的地,然後轉發。
- 收發器: 有狀態的 WebRTC 端點,負責完整的會話狀態,包括 ICE 連接檢查、DTLS 握手、SRTP 加密金鑰以及會話生命週期。
透過 ICE ufrag 的首封包路由
為避免在首個封包上進行外部查詢而產生延遲,OpenAI 使用 ICE 使用者名稱片段(ufrag)。在會話建立期間,收發器會產生包含路由中繼資料的伺服器端 ufrag。
當客戶端發送第一個 STUN(穿越 NAT 會話實用工具)綁定請求時,中繼會解析 ufrag、解碼路由提示,並將封包轉發給擁有該會話的收發器。路由確立後,後續的 DTLS、RTP 與 RTCP 封包皆依據記憶體中的會話映射傳遞,若中繼重新啟動,則會透過 Redis 快取恢復映射。
全球覆蓋與延遲最佳化
OpenAI 使用「全球中繼」艦隊,於地理上分散的入口點縮短客戶端到 OpenAI 的首跳距離,從而降低往返時間(RTT)、抖動與封包遺失,在流量進入 OpenAI 骨幹網路前即完成優化。
- 地理導向訊號: Cloudflare 的地理與接近度導向確保最初的 HTTP 或 WebSocket 請求抵達最近的收發器叢集。
- 整合路由: SDP(會議描述協議)回應中提供全球中繼地址,而 ufrag 確保中繼能將媒體正確路由至相應的叢集與收發器。
技術實作與效能
中繼服務以 Go 語言編寫,針對高吞吐量進行優化,且不需要 kernel‑bypass 框架。主要效能優化包括:
SO_REUSEPORT: 此 Linux socket 選項允許多個中繼工作者綁定同一 UDP 埠,讓核心將進入的封包分配給不同工作者,避免讀取迴圈瓶頸。runtime.LockOSThread: 將 UDP 讀取 goroutine 鎖定在特定 OS 執行緒上,提高快取局部性,並透過讓同一流的封包停留在同一 CPU 核心上,減少上下文切換。- 記憶體管理: 使用預先分配的緩衝區與最小拷貝,降低分配開銷與垃圾回收暫停時間。
架構收益總結
透過將複雜度移至薄薄的路由層,而非後端服務或客戶端,OpenAI 實現了可擴展的 WebRTC 部署,同時保留標準協議語意。這確保瀏覽器與行動應用保持相容,且推論後端可如同普通服務般水平擴展,而不必充當 WebRTC 對等節點。