21. 实时多模态(Realtime API / 实时语音对话)的核心技术挑战是什么?

整理实时语音/多模态流式系统的延迟、打断、流式生成关键设计。

简单回答

实时多模态系统(如 OpenAI Realtime API、GPT-4o 语音模式)的核心目标是把对话延迟压到接近人类对话节奏(200-500ms 端到端)。这要求整个链路从输入到输出都是流式且互相重叠的:语音持续输入边说边识别(streaming ASR)、文本/语义边接收边生成(streaming generation)、生成的内容边出边合成语音(streaming TTS)。最难的几件事是端到端延迟控制(每一段都要尽量重叠不能串行)、用户打断处理(用户开口后要立刻停止当前输出并切到新意图)、Voice Activity Detection 的准确度(决定何时算用户说完)、以及音频流和文本生成的协议设计。GPT-4o 这类原生多模态模型还要解决"边听边说"的并发对话能力。

详细解释

实时多模态对延迟的极端要求

人类对话的自然节奏是说话间隔 200-500ms。一旦超过 1 秒就明显感到"对方反应慢",超过 2 秒就尴尬。

传统的"录完音→转文字→送给 LLM→生成完→TTS 合成→播放"管线串行下来轻松 3-5 秒,根本不能用。实时系统的目标是把端到端 first-audio latency(用户说完到开始听到回复的时间)压到 500ms 以内。

要做到这点必须把整条链路 流水线化重叠 起来——不是等一段完成才做下一段,而是边做边出。

流式 ASR:边说边识

用户说话时,系统持续把音频发给 ASR,ASR 边收边出部分结果(partial transcript)。每说一个词左右就有一个增量的转写片段出来。

但这里有个矛盾:ASR 的 partial 结果不稳定——前面识别"我想买"可能在听到后面"贝壳"时改成"我想卖"。所以 partial 转写不能直接送给 LLM,否则 LLM 基于错误前提生成。

主流做法:

  • partial 用于检测意图、决定是否打断当前生成
  • 等到 ASR 输出 final(一段稳定的结果)才送进 LLM 做生成
  • final 的判断依赖 VAD(Voice Activity Detection)—— 用户停顿超过阈值(200-700ms)算说完

VAD 的阈值是个 trade-off。设短了——用户中间一停顿就被判说完,被打断很烦人。设长了——用户说完了系统还在等几百毫秒不响应,体感慢。OpenAI Realtime API 默认是 500ms,可以由开发者调节。

流式生成:LLM 边生成边输出

LLM 的 Decode 本身就是 token by token 的,天然支持流式。流式生成最早就是这层最早做起来的。

实时系统里有个特殊点:生成出来的 token 不是直接给用户看(文本应用那样 SSE 推到前端),而是要立刻送给 TTS 合成语音。所以生成节奏和 TTS 的需求要协调。

另一个约束是 LLM 生成内容必须 按句拆分 才能给 TTS——不能一个字一个字地合成(会卡顿且不自然),也不能等整段生成完才合成(延迟大)。常见做法是按句子或子句边界切分,"。""?""!"或者逗号处把已完成的部分送给 TTS,后续生成边走边送。

流式 TTS:边收文本边出音频

TTS 接收文本片段,边合成边输出音频流。现代神经 TTS(VITS、Tacotron 等的流式版本)支持 streaming inference——给一段文字先合成开头几百毫秒音频立刻输出,后续音频在播放过程中继续生成。

这里的关键技术点是 prosody continuity——句间的语调、语速要连贯,不能给一段合成完再给下一段时音色或语调突变。流式 TTS 需要内部维护跨段状态。

端到端延迟分解

把整个链路的延迟分解出来看:

用户说完 → VAD 判断说完 (200-500ms 等待停顿)
       → 把最后一段音频送 ASR 出 final transcript (50-100ms)
       → 送进 LLM Prefill (100-300ms 视上下文长度)
       → LLM 生成第一句 (100-300ms 取决于模型)
       → 送给 TTS 合成第一段音频 (100-200ms)
       → 通过网络播放给用户

最差情况加起来 1-1.5s。要压到 500ms 必须做几件事:

  • VAD 缩短到 300ms 甚至更短,但要避免误打断
  • ASR final 判断和 LLM Prefill 重叠——用户还没说完就用 partial 转写做 speculative prefill,押注用户说完是这个意思。如果 final 一致就省掉 Prefill 时间;如果不一致就回退。
  • LLM 第一句生成立刻流式给 TTS,不等整段
  • TTS 流式出第一段音频立刻播放,后续边播边合成

GPT-4o Realtime API 公开的 first-audio latency 中位数 320ms,已经很接近人类对话节奏。

打断处理(Barge-in)

用户在系统说话过程中开口,称为 barge-in。处理 barge-in 是实时系统区别于"说完听、听完说"的关键能力。

要做 barge-in:

  • 系统说话时麦克风必须保持开启,VAD 持续监测用户输入
  • 检测到用户开口后立刻执行三件事:停止当前 TTS 播放、停止 LLM 生成、把已生成但用户没听到的内容标记为"未传递"
  • 把用户新的输入接续到对话历史里——但要标注上一轮系统输出"实际播放到哪里",避免上下文里 LLM 以为它说完了实际只说了半句

最后这点很微妙。如果不处理,模型上下文里以为它说了"今天天气晴朗,气温 25 度",但用户实际只听到"今天天气晴朗"就打断了,问"你说什么气温",模型会说"我刚说气温 25 度"——但用户没听到。所以打断时要在上下文里精确标记"系统输出截断到这里"。

端到端神经多模态 vs Cascaded

GPT-4o 之前的语音对话基本都是 Cascaded(ASR → LLM → TTS 三段管线)。GPT-4o 是端到端原生多模态——一个模型直接处理音频输入和音频输出,跳过 ASR 和 TTS 中间层。

端到端的好处是:

  • 链路更短,理论延迟更低
  • 保留语音中的情感、语调、口音、笑声等 paralinguistic 信息(Cascaded 在 ASR 转文字时全丢了)
  • 输出语音可以表达情感和强调(不只是把字读出来)

代价是:

  • 训练数据要求高(语音 + 文本对齐数据规模大、标注难)
  • 模型推理对语音 token 的处理增加 token 数和成本
  • 泛化和可控性相对 Cascaded 更难(Cascaded 里每段独立优化)

本专题第 16 篇讲过 cascaded 和端到端的对比。从 2024 年下半年到 2025 年,端到端方案在头部产品里取代了 Cascaded,但开源生态还是 Cascaded 更成熟。

协议和 API 设计

实时多模态对 API 协议提出了新要求。HTTP request-response 不行,必须是双向流——常见选择是 WebSocket 或 WebRTC。

OpenAI Realtime API 用 WebSocket,事件驱动协议:客户端发送 input_audio_buffer.append 携带音频块,服务端推送 response.audio.deltaresponse.text.deltaresponse.audio_transcript.delta 等事件。VAD 触发由服务端做(也可由客户端做后通过 input_audio_buffer.commit 触发)。

WebRTC 在浏览器端体验更好(自带 echo cancellation、noise suppression),但服务端实现复杂得多。

工程上的难点和坑

回声消除和噪声抑制。如果不做,系统播放的语音会被麦克风录进去,触发 ASR 自己识别自己——形成无限循环。浏览器端 WebRTC 自带回声消除,APP 端要自己做。

网络抖动容忍。音频流对网络波动敏感,丢一段音频用户感知很明显。需要前端 buffer + 重传机制,或者用 jitter buffer。

多语言识别和切换。用户说着说着切到另一种语言(双语家庭、技术名词混英文),ASR 要能跟上。

情感和语调。Cascaded 系统里 LLM 拿到的是干文字,丢了情感信息。要让回复也有情感,要么端到端模型处理,要么在 prompt 里加情感标注("用平静的语气回答")让 LLM 显式输出 SSML 给 TTS 控制。

长对话上下文。语音对话比文本对话上下文积累快——一小时的对话上下文可能几万 token。要做主动摘要或滚动窗口。

面试时可以这样答

实时多模态系统的核心目标是把端到端对话延迟压到 500ms 以内接近人类对话节奏。要做到这点整个链路必须流水线化重叠,不能串行。

链路上四段都要流式:流式 ASR 边说边识但 partial 不稳定不能直接送 LLM,要等 final;流式 LLM 生成是天然 token by token;TTS 也要流式合成边收文本边出音频;中间还要 VAD 判断用户什么时候说完。每段单独看都是几十到几百毫秒,串行起来就一两秒。

关键的优化是用 partial transcript 做 speculative prefill——用户还没说完就押注开始 LLM Prefill,押对了省掉等待时间。还有 LLM 生成第一句立刻送 TTS、TTS 第一段音频立刻播放,全链路重叠。GPT-4o Realtime API 中位 first-audio latency 320ms 就是这么做出来的。

打断处理是实时系统的标志能力。系统说话时麦克风保持开启 VAD 监测,用户开口立刻停 TTS、停 LLM 生成,并在上下文里精确标注"实际播放到哪里",避免下一轮模型以为自己说完了实际半句没说。

端到端原生多模态(GPT-4o)相比 Cascaded(ASR + LLM + TTS)的好处是延迟更低、保留语音情感语调、输出能表达情感。代价是训练数据要求高、模型成本高、可控性低。开源生态还是 Cascaded 更成熟,头部商业产品逐步切到端到端。

协议上必须是双向流,OpenAI Realtime 用 WebSocket 事件驱动,浏览器端 WebRTC 体验更好但实现复杂。工程上的坑包括回声消除(不做会自己识别自己进入死循环)、网络抖动容忍、多语言切换、情感语调控制、长对话上下文滚动。

常见追问

  1. Speculative Prefill 押错了怎么处理?回退成本大吗?
  2. VAD 阈值怎么动态调整?根据用户语速、对话场景自适应?
  3. 端到端模型生成"嗯""啊"这种 filler 是优点还是缺点?怎么控制?