OpenAI 低延迟语音 AI 基础设施
OpenAI 实现了一个分离的中继加收发器(relay‑plus‑transceiver)架构,以解决实时语音 AI 的规模化难题。通过将数据包路由与协议终止解耦,OpenAI 能在标准的 Kubernetes 环境中保持自然对话所需的低延迟。
在 Kubernetes 上扩展 WebRTC 的挑战
标准的 WebRTC 实现通常采用“一端口对应一次会话”的模型,在 OpenAI 规模(每周活跃用户 9 亿+)下部署时会产生显著的运营障碍。该模型带来三大主要限制:
- 端口耗尽: 每个服务需要管理数万条公共 UDP 端口,导致负载均衡器配置、防火墙策略以及发布安全性都变得更加复杂。
- 安全风险: 大范围的 UDP 端口暴露了更多可被外部访问的表面,使网络策略更难审计。
- 自动伸缩摩擦: Kubernetes Pod 经常被重新调度;如果每个 Pod 必须保留并广播一大段稳定的端口范围,弹性伸缩就会变得脆弱。
虽然单端口每服务器的设计可以降低端口数量,但它们在“状态粘性”方面表现不佳。由于 ICE(Interactive Connectivity Establishment)和 DTLS(Datagram Transport Layer Security)是有状态的,特定会话的数据包必须始终到达拥有该会话的进程,否则连接会失败。
中继 + 收发器 架构
为了解决上述冲突,OpenAI 放弃了通常用于多方通话的选择性转发单元(SFU)模型,转而采用 收发器模型。在该架构中,WebRTC 边缘服务(即收发器)负责终止客户端连接,并将媒体转换为内部协议供推理和编排使用。
分离路由与终止
此设计的核心是将 Relay(路由)与 Transceiver(终止)分离:
- 中继: 轻量级的 UDP 转发层,公共占用极小。它不解密媒体、不运行 ICE 状态机,也不协商编解码器。它仅读取数据包元数据以确定目的地并转发数据包。
- 收发器: 有状态的 WebRTC 端点。它拥有完整的会话状态,包括 ICE 连接检查、DTLS 握手、SRTP 加密密钥以及会话生命周期管理。
通过 ICE ufrag 的首包路由
为避免在首个数据包上进行外部查询导致的停顿,OpenAI 使用 ICE username fragment(ufrag)。在会话建立期间,收发器生成包含路由元数据的服务器端 ufrag。
当客户端发送首个 STUN(Session Traversal Utilities for NAT)绑定请求时,中继解析 ufrag,解码路由提示,并将数据包转发给对应的收发器。路由建立后,后续的 DTLS、RTP 与 RTCP 数据包均依据内存中的会话映射表进行转发,若中继重启则通过 Redis 缓存恢复映射关系。
全球覆盖与延迟优化
OpenAI 使用一支 “Global Relay” 车队,部署在全球分布的入口点,以缩短客户端到 OpenAI 的首跳距离。这降低了往返时延(RTT)、抖动以及在流量进入 OpenAI 主干网前的丢包率。
- Geo-Steered Signaling(地理引导信令): Cloudflare 的地理与邻近性调度确保首次 HTTP 或 WebSocket 请求落在附近的收发器集群。
- Integrated Routing(集成路由): SDP(Session Description Protocol)应答中提供 Global Relay 地址,而 ufrag 则保证中继能够将媒体路由到正确的集群和收发器。
技术实现与性能
中继服务使用 Go 编写,并在不依赖内核绕过框架的前提下实现高吞吐量。关键性能优化包括:
SO_REUSEPORT: 该 Linux 套接字选项允许多个中继工作进程绑定同一 UDP 端口,内核会在工作进程之间分配入站数据包,从而避免读取循环瓶颈。runtime.LockOSThread: 将 UDP 读取 goroutine 锁定到特定的 OS 线程,提升缓存局部性并通过让同一流的包始终在同一 CPU 核心上处理来减少上下文切换。- Memory Management(内存管理): 使用预分配缓冲区并尽量减少拷贝,降低分配开销和垃圾回收暂停时间。
架构收益概述
通过将复杂度迁移到轻量的路由层,而不是后端服务或客户端本身,OpenAI 实现了可扩展的 WebRTC 部署,保持了标准协议语义。这确保浏览器和移动应用保持互操作性,同时让推理后端能够像普通服务一样弹性伸缩,而不必充当 WebRTC 对等方。