OpenAI 于 8 月 3 日发布技术文章,详细说明了驱动 ChatGPT Voice 的语音系统 GPT-Live 是如何构建的。文章记录了长达 6 个月的重构:把猜测说话间隙的轮次检测器从音频通路中移除,并把建立连接时的网络往返从 6 次压缩到 1 次。这不是一次模型发布,而是关于支撑该模型每天运转的底层系统的说明。
让模型自己决定何时开口
以往的语音 AI 依靠一个称为轮次检测器(turn detector)的小模型来判断用户是否说完,只有等它给出结论,体量大得多的 LLM 才能开始工作[1]。判断得太早会打断用户,判断得太晚则回应迟钝。无论偏向哪一边,对话都会失去自然感,这对一个小模型来说是个吃力不讨好的角色。
GPT-Live 是 7 月 8 日发布的第三代语音模型,采用可以同时收听和说话的全双工架构[2]。说话、继续聆听、保持安静、插话还是调用工具,这些判断由模型本身每秒做出多次[2]。轮次检测器这个中间裁判从音频通路中消失后,对话节奏不再依赖外部的推测[1]。
把音频通路和其他处理分开
设计早期就确定的一点,是把媒体流与应用逻辑明确分离[1]。音频走客户端与语音模型之间的专用快速通路,而向前沿模型的委派、工具调用等工作则在异步 RPC 边界之后进行。缓慢的工具调用只会拖延自身的结果,无法阻断媒体流。
这种分离也让系统更容易扩展。应用可以修改工具、策略和后端行为,而不影响负责让音频持续流动的媒体前端。实时通路保持小巧、可预测,只承担必须实时完成的工作[1]。
在实现层面,媒体前端和推理逻辑从原先的 Python asyncio 改写为 Go。帧传输的平滑度明显改善,新系统的 p95 达到了旧系统 p50 的水平[1]。传输层使用 WebRTC,能够在丢包、时钟漂移和客户端连接变化的情况下继续工作。数据包延迟到达时,WebRTC 会轻微拉伸音频以避免出现空隙,随后短暂加速播放追回实时进度[1]。
对话变长也能无中断地更换模型实例
有状态推理有其运维上的代价。语音会话可能长时间保持开启,上下文却在持续增长,而模型实例会随需求启停。
OpenAI 的做法是构建一套无缝交接机制。需要切换时,系统会预热一个替换实例,用当前会话上下文进行预填充,让两者并行推理,等新实例完全就绪后再切换过去[1]。
同一机制也用于上下文的动态压缩(compaction)。对话持续下去,累积的上下文最终会超出模型上限。压缩可以把它缩回限制之内,但由于改写了过去的上下文,会使保存已处理 token 注意力键值的 KV 缓存失效,重建这些状态需要重新预填充,从而带来额外延迟。把压缩当作又一次受管理的切换来处理,原实例继续对话,系统在后台准备好带有压缩后上下文的新实例,就绪后无中断切换。繁重的工作留在实时通路之外,对话不会漏掉一拍[1]。
更深的思考交给后台的 GPT-5.5
当请求需要搜索或更深入的推理时,GPT-Live 会委派给 GPT-5.5 这样的前沿模型[1][2]。问题在于结果能否及时回到对话中。语音模型可以短暂地维持交流,却无法掩盖任意缓慢的响应,因此整条委派链路,包括路由、提示处理、推理和工具调用,都被纳入了响应性预算[1]。
具体做法是,语音会话一开始,应用服务器就为前沿模型创建推理会话并预填充初始对话上下文,确保在第一次委派请求到来之前提示已经处理完毕。之后这个推理会话在整通对话期间保持可用,配合稳定的会话亲和性与提示缓存进一步降低延迟[1]。
另一项不太显眼但同样关键的工作,是把连续的语音切分成离散的消息。ChatGPT 的对话界面以及部分分析与安全基础设施,仍然按用户和助手的轮次来运作。应用服务器利用部分转写结果和时间信号推断由谁掌握发言权,构建消息队列,并把最新的一条视为暂定状态,其文本、时间和说话人归属都可能随后续语音而变化。助手简短的应和不必单独成为一条消息,而实质性的插话通常应该[1]。
任何切分策略都是在新鲜度与确定性之间取舍:提交得太早会让历史变得零碎,等得太久则转写滞后。系统为此维护两种视图,一种是当前状态的推测视图,一种是已说内容的权威记录。能够处理更新的界面使用推测视图,分析管线则接收最终转写[1]。
WARP 与 Instant Connect:把 6 次往返压到 1 次
从用户按下按钮的那一刻起,响应速度就开始被计量。WebRTC 面向低延迟媒体设计,但启动一次会话需要出人意料的多次握手和网络往返。它的诞生早于 QUIC 等后来协议对减少往返的重视,因此各个子协议之间存在重复工作,例如各自都带有自己的抗 DoS 机制[1]。
OpenAI 分析了整个协议栈,开发出 WARP(WebRTC Abridged Roundtrip Protocol),把媒体与数据的启动从 6 次往返减少到 1 次。它由一组向后兼容的改进组成:通过 SPED 把 DTLS 握手搭载在 ICE 上、使用更快的 DTLS 1.3 握手、通过 SNAP 预先协商 SCTP 握手,以及预先协商数据通道而不使用 DCEP[1]。
值得注意的是,这项成果并未自我封闭。WARP 被设计为一组开放规范,由 WebRTC 社区的合作者共同参与,并正在 IETF 的 TSVWG 工作组推进标准化。其中的 SPED 已在 IETF 数据追踪器登记为草案,被描述为让 ICE 与 DTLS 并行推进的向后兼容扩展[3]。libwebrtc 与 Pion 已加入对 WARP 的支持,其他实现的工作也在进行中[1]。
与之配套的 Instant Connect 则把 SDP 信令交换从关键路径上移除。它与标准信令流程并行运行,若预先协商的参数有效,服务器会在第一个媒体包到达时直接实例化会话;若参数已失效,常规信令流程本就在进行,客户端可以在不增加延迟的情况下回退。与 WARP 结合后,客户端只需一个 UDP 包即可开启会话[1]。
用生产流量做的静默测试暴露了什么
一个系统在纸面上很快,遇到真实语音流量仍可能卡住。在让用户接触 GPT-Live 之前,OpenAI 进行了静默测试,把生产环境中一小部分并逐步增加的 ChatGPT Voice 会话同时导向现有的 Advanced Voice Mode 和新系统。Advanced Voice Mode 照常服务用户,新系统只在只读模式下运行推理,用户听到的内容没有任何变化[1]。
第一个教训是,容量无法简化为 GPU 吞吐量。语音会话保持开启并持续发送帧,因此 CPU 侧的流处理器、队列和网络通路必须与推理一同扩展。在真实负载下,一个配套组件比负载测试的估计更早饱和,导致推理请求堆积、延迟层层累加。于是容量问题从一块 GPU 能处理多少请求,改为在保证每一帧准点送达的前提下系统能同时维持多少会话[1]。
地理分布同样成为一等考量。把会话调度到较远的容量,会在启动和流传输的多个环节增加延迟。长时间会话暴露出内存与持久化压力,重连考验压缩与状态恢复,而普通的客户端断开则暴露了关闭握手中的竞态。这些问题依赖时间与累积状态,短时负载测试很少能发现[1]。
可观测性与发布控制也做了改造。团队发现有些指标把不同来源的延迟混为一谈,有些仪表盘的聚合值掩盖了个别不健康的引擎,测试环境与部署环境之间还存在配置漂移。为此他们增加了更细粒度的遥测、与已知良好配置的比对校验、分阶段放量,以及快速隔离或停用单条通路的能力[1]。
总结
贯穿整篇文章的原则只有一条:语音必须持续流动。流式推理、专用媒体通路、异步委派和传输层优化,全都是为它服务的。这套底层架构还将成为即将推出的 GPT-Live API 的基础,因此对于构建语音交互的开发者来说,包括 WARP 的标准化进展在内,都值得持续关注。
[1] 来源: https://openai.com/index/continuous-voice-interaction-with-gpt-live
[2] 来源: https://openai.com/index/introducing-gpt-live/
[3] 来源: https://datatracker.ietf.org/doc/draft-hancke-webrtc-sped/
