全模态模型:Qwen2.5-Omni 与 Thinker-Talker 分离 本节摘要:GPT-4o 在 2024 年 5 月的产品演示之所以颠覆,不在于底层模型,而在于产品形态——一个语音界面,你说话、模型看到摄像头所见、它在 250ms 内说回去。开源生态花了 2024 余下时间与 2025 全年追赶这个产品面。Qwen2.5-Omni(2025 年 3 月)是开源参考设计:一个 Thinker(生成文本的大型 Transformer)加一个 Talker(并行的语音生成 Transformer),由流式语音 token 连接。Mini-Omni 简化了它,Moshi 匹配了它的延迟,GLM-4-Voice 把它扩到中文。
本节摘要:GPT-4o 在 2024 年 5 月的产品演示之所以颠覆,不在于底层模型,而在于产品形态——一个语音界面,你说话、模型看到摄像头所见、它在 250ms 内说回去。开源生态花了 2024 余下时间与 2025 全年追赶这个产品面。Qwen2.5-Omni(2025 年 3 月)是开源参考设计:一个 Thinker(生成文本的大型 Transformer)加一个 Talker(并行的语音生成 Transformer),由流式语音 token 连接。Mini-Omni 简化了它,Moshi 匹配了它的延迟,GLM-4-Voice 把它扩到中文。本节读 Thinker-Talker 架构与让流式实时对话成立的延迟预算。
阅读完本节,你应当能够:
实时语音助手要做很多事,还要快:
每步都加延迟。对话体感要求总往返 < 500ms——低于这个,用户就不察觉滞后。GPT-4o 称约 250ms,Moshi 约 160ms,Qwen2.5-Omni 约 350~500ms。
每个组件都必须流式,不能「先攒齐再解码」。
Qwen2.5-Omni 的分解:
分离很重要。Thinker 必须大才能推理好;Talker 可以小,因为它的活是局部的——把文本转成语音 token。更大的 Talker 不会更有表现力,只会更慢。
并行运行:
Thinker 要整合图像帧(比如 4 FPS 到达)、音频帧(每秒 50 帧)、对话历史的文本。朴素的序列顺序(所有图、再所有音频、再文本)会丢时间对齐。
TMRoPE 给每个 token 分配绝对时间戳。视觉 token 在 t=2.3s,音频 token 在 t=2.32s,用户文本「停」在 t=2.35s。RoPE 按时间戳旋转注意力,模型把它们看作时间上并发。
这是「他挥手的同时说你好」得以成立的基础设施——模型在同一概念时刻看到视频帧与音频。
语音 token 必须流式。Mini-Omni(Xie & Wu,2024)提出「语言模型能边想边听边说」:Thinker 输出 token 与 Talker 输出 token 在同一条序列里交错。Talker 一旦 Thinker 提交下一文本 token 就触发,无 batch 边界。
Moshi(Défossez 等人,2024 年 10 月)是最快的开源实现,单 A100 上 160ms TTFAB。架构:单一 7B Transformer 在交替位置发文本与语音 token,用「内心独白」把思考流与说话流分开。这实质是把 Thinker + Talker 融进一个模型,配以精心训练。
输入侧跑语音活动检测。两种模式:
Qwen2.5-Omni 默认半双工,经静音阈值轮流;全双工需应用层处理。
继任者。Qwen3-80B Thinker、更大 Talker、改进 TMRoPE-v2,延迟逼近 GPT-4o 的 250ms,开源权重,在 OmniBench 上与 Gemini 2.0 Live 竞争。
典型流式交互:
总 TTFAB:7B 320510ms,70B 600900ms。前沿质量通常意味着 70B+,这就是前沿延迟差距的由来。
16kHz 语音、50Hz 基础语音 token,每秒输出需要 50 个语音 token。Talker 必须 ≥50 tok/s 才跟得上。H100 上典型 LLM 吞吐 3080 tok/s,小型(23 亿)Talker 够快;7B Talker 会落后。
这就是为什么有专门的小 Talker 模型,而不是「直接用主模型」。
code/main.py:
def thinker_talker_stream(audio_in, video_in, history): # Thinker 边想边发文本 token for text_tok in thinker.generate(audio_in, video_in, history, stream=True): # Talker 边收文本 token 边发语音 token (并行, 不等 Thinker 结束) for speech_tok in talker.generate(text_tok, stream=True): waveform_chunk = speech_decoder(speech_tok) # 流式波形 play(waveform_chunk) # 实时出声 history.append(text_tok)
def ttfab(thinker_size, talker_size): mic_to_token = 60 # ms prefill = 150 if thinker_size == "7B" else 700 first_text = 40 talker_proc = 20 speech_commit = 40 rvq_decode = 30 waveform = 65 return mic_to_token + prefill + first_text + talker_proc + speech_commit + rvq_decode + waveform # 7B ≈ 405ms, 70B ≈ 955ms
💡 为何要小 Talker:16kHz 语音每秒需 50 个基础语音 token,Talker 必须 ≥50 tok/s。H100 上 7B 模型 3080 tok/s 容易落后;23 亿的小 Talker 轻松过百,保证不卡顿。这就是 Thinker 大、Talker 小的根源。
def tmrope_align(events): # events = [(modality, content, t_absolute), ...] # 给每个 token 分配绝对时间戳, RoPE 按时间戳旋转 for modality, content, t in events: position = (t=t, h=0, w=0) # 视觉/音频/文本共享时间轴 rotate(q, position) # 模型看到它们时间并发 # 「他挥手(t=1.2s)的同时说你好(t=1.18s)」得以对齐
工程取舍:要开源前沿质量用 Qwen3-Omni;要最低延迟用 Moshi(160ms);要简化用 Mini-Omni;要中文用 GLM-4-Voice;全双工用 Moshi。
本节产出 outputs/skill-omni-streaming-budget.md。给定实时语音产品的目标 TTFAB 与功能集(视觉输入、双语、全双工),它在 Qwen2.5-Omni、Qwen3-Omni、Moshi、Mini-Omni 间选择,并给 Thinker/Talker 选型。
TTFAB 拆解:目标 TTFAB 300ms,7B Thinker + 300M Talker,写出每个组件的延迟。
TMRoPE 场景:Qwen2.5-Omni 用 TMRoPE。描述用户在 t=1s 开始说话、摄像头在 t=1.2s 捕获手势时,模型看到什么。
全双工训练:全双工要求模型边听边发音频。提出一个教这个的训练数据格式。
读 Moshi:读 Moshi 论文第 4 节,描述「内心独白」分离,以及它为何能避开 Thinker-Talker 拆分。
吞吐预算:16kHz 语音、50 基础层 token/秒下,Talker 必须多快发 token 才跟得上?
下一节,我们将进入具身 VLA——视觉-语言-动作模型,把多模态理解变成机器人动作(OpenVLA、PI0、GR00T),让模型不仅能「说」,还能「做」,是 AI 走向物理世界的桥梁。