@vllm_project: @Alibaba_Qwen 的 Qwen3-Omni 能听、能推理、能回复。实时服务它是个管道问题,不是单一模型的问题……

X AI KOLs Timeline 工具

摘要

vLLM-Omni 引入分阶段流水线来实时服务阿里巴巴的 Qwen3-Omni,分别优化 Thinker、Talker 和 Code2Wav 三个阶段,在相同 GPU 上实现亚秒级首音频延迟和 5.4 倍吞吐量。

@Alibaba_Qwen 的 Qwen3-Omni 能听、能推理、能回复。实时服务它是个管道问题,而不是单一模型的问题:多模态 Thinker 后接 Talker → Code2Wav 用于语音生成。 每个阶段的瓶颈各不相同,因此优化需要逐层攻克。一个巧妙技巧:在负载下,只复制两个语音阶段,让重量级的多模态 Thinker 只运行一次。在高并发下,首音频延迟从约 6 秒降至约 0.6 秒,语音生成速度快于实时,且在相同 GPU 上实现约 5.4 倍的吞吐量。 由 @AntGroup 的超级计算技术(SCT)团队和 vLLM-Omni 团队共同构建。这篇博客逐一剖析了整个技术栈的瓶颈: http://vllm.ai/blog/2026-07-01-qwen3-omni-optimization…
查看原文
查看缓存全文

缓存时间: 2026/07/03 08:32

@Alibaba_Qwen 的 Qwen3-Omni 能听、能推理、能回话。要实现实时服务,这是一个管道问题,而不是单个模型的问题:一个多模态思考者,然后是说话者 → Code2Wav 生成语音。

每个阶段的瓶颈不同,因此收益来自于逐层优化。一个巧妙的方法:在负载下,只复制语音的两个阶段,而让重的多模态思考者只运行一次。在高并发下,首次音频大约在 0.6 秒内到达,而不是 6 秒,语音生成速度快于实时速度,并且在相同的 GPU 上吞吐量提升约 5.4 倍。

由 @蚂蚁集团 的超算技术(SCT)团队和 vLLM-Omni 团队共同构建。这篇博客逐一剖析了全栈优化过程,一次解决一个瓶颈。 http://vllm.ai/blog/2026-07-01-qwen3-omni-optimization…


在 vLLM-Omni 中服务多阶段 Qwen3-Omni 的经验与教训

来源:https://vllm.ai/blog/2026-07-01-qwen3-omni-optimization Qwen3-Omni 结合了多模态理解与语音生成。本文解释了 vLLM-Omni (https://github.com/vllm-project/vllm-omni) 如何将其作为分阶段管道进行服务,并针对在线工作负载优化每个阶段。

TL;DR

vLLM-Omni 的 Qwen3-Omni 服务栈包括:

  • 三阶段管道: 思考者负责多模态推理,说话者负责语音编解码生成,Code2Wav 负责波形重建。
  • 兼容 OpenAI 的服务: /v1/chat/completions 是 Qwen3-Omni 文本和音频生成的主要端点。
  • 批处理、CUDA 图、异步分块、异步输出、副本和关键路径清理: 对思考者、说话者和 Code2Wav 进行阶段级批处理和每个阶段的图捕获,以提高高并发吞吐量;异步分块交接和异步输出防止管道和解码工人因全载荷屏障和同步载荷构建而停滞;说话者/Code2Wav 副本可扩展语音生成阶段;关键路径清理会削减随话语长度增长的每步模型内部开销。
  • 性能验证: 受控基准扫描和 DFX 性能运行显示,随着每一层优化开启,音频首次分组到达时间(TTFP)降低,音频实时因子(RTF)降低,吞吐量提高。

快速开始

使用 --omni 参数服务模型时,默认的 Qwen3-Omni 部署配置会自动解析:

vllm serve Qwen/Qwen3-Omni-30B-A3B-Instruct \ --omni \ --port 8091

如需显式配置,可传入分阶段部署配置:

vllm serve Qwen/Qwen3-Omni-30B-A3B-Instruct \ --omni \ --port 8091 \ --deploy-config vllm_omni/deploy/qwen3_omni_moe.yaml

内置配置包含一个 platforms: 部分。vLLM-Omni 会自动检测运行时后端(CUDA、NPU、ROCm 或 XPU)并合并匹配的差异——无需额外的 CLI 参数。相同的启动命令可在不同硬件上运行。

请求应使用 /v1/chat/completions。在请求体中设置 modalities 来声明输出类型——例如 ["text"] 仅文本,或 ["text", "audio"] 文本加语音。

有关部署选项、异步分块设置和多副本布局,请参阅 Qwen3-Omni 在线服务指南 (https://github.com/vllm-project/vllm-omni/blob/main/examples/online_serving/qwen3_omni/README.md)。

Qwen3-Omni 服务模型

纯文本 LLM 服务是一个循环:预填充、解码、去分词。Qwen3-Omni 在多模态推理之后增加了两个语音阶段,每个阶段的计算特征不同:

思考者 -> 多模态理解 + 文本生成 说话者 -> 隐藏状态和嵌入到 RVQ 编解码代码 Code2Wav -> 编解码代码到波形音频

图 1:vLLM-Omni 中的 Qwen3-Omni 服务是一个分阶段数据流:思考者生成文本和隐藏状态,说话者生成编解码代码,Code2Wav 重建音频。图 1:vLLM-Omni 中的 Qwen3-Omni 服务是一个分阶段数据流:思考者生成文本和隐藏状态,说话者生成编解码代码,Code2Wav 重建音频。

优化概述

Qwen3-Omni 管道的不同部分会遇到不同的瓶颈。vLLM-Omni 不是应用一种固定的配方;每个优化都针对特定的阶段或交接点。接下来的讲解将逐一介绍每个优化——按照我们验证的顺序——并依次回答三个问题:为什么存在问题,为什么它有效(机制如何消除该问题),以及你能获得什么(测量的收益)。

技术目标阶段/路径解决的问题主要收益
阶段分解思考者 → 说话者 → Code2Wav三个计算特征差异巨大的阶段共享一个循环,因此单个批处理/图/设备策略会让最慢的子路径拖累其他路径——限制了吞吐量并阻碍了每个阶段的独立调优和扩展每个阶段独立的运行时策略
AR + Code2Wav 批处理说话者 MTP 路径,Code2Wav 异步分块高并发下,单请求的微工作让 SM 在启动之间空闲,限制了 GPU 占用率和 req/s更高的占用率和 req/s
CUDA 图思考者 / 说话者 / Code2Wav 解码路径每个解码步骤重复的 CPU 侧内核调度会膨胀 TPOT,并使音频 RTF 高于实时更低的 TPOT 和音频 RTF;扫描中吞吐量提升约 4 倍
异步分块思考者→说话者,说话者→Code2Wav全载荷阶段屏障迫使 Code2Wav 等待完整的说话者载荷,延迟了首次音频并膨胀了音频 TTFP流水线交接;最大的音频 TTFP 降低
异步输出思考者连接器载荷同步载荷构建阻塞了思考者解码工人之间的分块,浪费 GPU 时间用于分配并降低吞吐量恢复吞吐量且不增加音频 TTFP 回归
阶段副本说话者,Code2Wav说话者和 Code2Wav 饱和并排队,而思考者仍有余量,成为负载下的尾部瓶颈仅在瓶颈阶段水平扩展
关键路径清理说话者代码预测器,连接器载荷每步的 Python、分配和同步开销随着长话语而累积,膨胀 E2EL 和音频 TTFP更低的每步延迟;与上述所有层叠加

我们通过 Seed-TTS en 上的受控基准扫描验证了每一层(Qwen3-Omni-30B-A3B-Instruct10/160/320/640 提示词,并发度 1/16/32/645 次预热,三个可见 GPU 映射为 0/1/2)。每个配置会重启服务器,使用隔离的部署配置,并在前一行之上添加一个优化。BatchAsync output 将每个阶段固定在一个 GPU 上(思考者/说话者/Code2Wav 分别在 GPU 0/1/2,每阶段单副本);Phase replicas 行将思考者保留在 GPU 0,并在 GPU 1 和 2 上运行 2× 说话者 + 2× Code2Wav。下表总结了并发度 64 的结果;Validation Results (https://vllm.ai/blog/2026-07-01-qwen3-omni-optimization#validation-results) 图表显示了所有四个并发度级别。

步骤添加的配置说话者 / Code2Wav 副本req/s平均音频 TTFP平均音频 RTF
基线 Batch1 / 12.255884 ms1.15
+ CUDA 图在思考者、说话者、Code2Wav 上捕获图1 / 18.6 (+299%)2790 ms (−53%)0.59 (−49%)
+ 异步分块异步分块阶段交接1 / 19.3 (+8%)655 ms (−77%)0.63
+ 异步输出异步输出路径1 / 111.3 (+22%)631 ms (−4%)0.47 (−25%)
+ 阶段副本2× 说话者 + 2× Code2Wav2 / 211.7 (+4%)632 ms0.47

图 2:Qwen3-Omni 性能来自于同时优化阶段数据流、阶段运行时和解码关键路径。图 2:Qwen3-Omni 性能来自于同时优化阶段数据流、阶段运行时和解码关键路径。

逐阶段优化栈

每个优化都建立在前一个之上,因此在每个步骤中报告的数字都假设上面的所有层已经启用。

1. 阶段分解与批处理:基线

为什么。 Qwen3-Omni 不是单一的同质解码循环:思考者执行多模态 AR 文本生成,说话者运行编解码预测器 AR 路径,而 Code2Wav 运行并行声码器解码。将这三个非常不同的工作负载折叠到单个服务路径中,会强制它们使用相同的批处理策略、图策略和设备布局——并让最慢的子路径拖累其他路径。分离阶段消除了这种耦合,但暴露了第二个问题:语音路径仍然将大部分 GPU 时间花在单请求的微工作上。每个说话者解码步骤是一个短代码预测器前向,每个 Code2Wav 分块是一个小声码器前向,因此在并发度 64 下,一次一个请求地运行它们会使 SM 在启动之间保持空闲,并且永远不会摊薄固定的每步成本。

为什么它有效。 这依次解决了两个问题。首先,阶段分解打破了耦合:阶段边界成为第一类服务对象,连接器定义跨越每个边界的内容(隐藏状态、嵌入、编解码代码、分块元数据),调度器可以在每个阶段自己的关键路径上调度、批处理和绘制图表——因此没有单个策略被强加给所有三个阶段,最慢的子路径不再拖累其他路径。其次,每阶段批处理填补了空闲 SM 的缺口:将并发请求收集到一次说话者 MTP 调用和一次 Code2Wav 前向中,填满了单请求微工作留下的空闲 SM,并摊薄了固定每步成本。

你能获得什么。 显式的阶段让 vLLM-Omni 将每个组件视为独立的运行时——分别设置 max_num_seqs、采样参数、连接器、图形/eager 策略和可选副本——这是下面每个优化的先决条件。这个带批处理的阶段分解配置是 Batch 基线,后面的每一行都建立在此基础上。

2. CUDA 图:每阶段解码捕获

为什么。 批处理提高了占用率,但每个解码步骤仍然支付了重复的 CPU 侧内核调度。Qwen3-Omni 运行三个解码密集型阶段;仅说话者可能每句话执行数百个短步骤,而每个步骤以前都从 Python 重新启动相同的稳定算子序列。在并发度 64 下,这种启动开销主导了 TPOT,并使音频 RTF 在批处理后仍然高于实时。

为什么它有效。 CUDA 图消除了主导 TPOT 的每步内核调度:它捕获一次固定的算子序列,并以最小的 CPU 工作重放。每个阶段有不同的捕获点,但原理相同:解码形状桶化为稳定的 (batch, seq, frames) 配置文件,因此运行时在预热时记录图,并在关键路径上重用。

图 3:每个阶段在不同的点捕获图。思考者和说话者在 vLLM 的外层图下解码;说话者的内部代码预测器使用 torch.compile 而不是第二个图;Code2Wav 使用内部 CUDAGraphDecoderWrapper。图 3:每个阶段在不同的点捕获图。思考者和说话者在 vLLM 的外层图下解码;说话者的内部代码预测器使用 torch.compile 而不是第二个图;Code2Wav 使用内部 CUDAGraphDecoderWrapper。

阶段 0 — 思考者:vLLM 外层解码图

思考者是一个自回归多模态阶段(LLM_AR)。当 enforce_eager 为 false 时,它在解码路径上使用 vLLM 标准 CUDA 图捕获——与纯文本 LLM 服务相同的机制。这消除了长时间思考者生成期间重复的 CPU 侧内核调度。

阶段 1 — 说话者:外层解码图 + 编译代码预测器

说话者阶段在 enforce_eager: false 时也通过 vLLM 的外层 CUDA 图路径运行。每个说话者解码步骤额外调用代码预测器——一个短的重新预填充 Transformer,发射 RVQ 编解码代码。那个内部路径被单独优化:

  • torch.compile 融合了 5 层预测器前向(dynamic=Falseepilogue_fusion=False),使得 RMSNorm/RoPE 与参考路径在数值上保持一致,同时仍然减少每步的内核数量。
  • 在 CUDA 上,代码预测器默认启用第二个手动 CUDA 图层(use_cuda_graphs=False),因为这会与 vLLM 的说话者 CUDAGraphWrapper 冲突。外层说话者图和编译的内部前向是互补的:一个捕获 AR 阶段循环,另一个融合编解码预测微前向。

可选的前缀图桶(连接器配置中的 code_predictor_prefix_graphs)可以在显式启用时捕获额外的稳定预测器形状。

阶段 2 — Code2Wav:内部声码器图

Code2Wav 是一个生成阶段(LLM_GENERATION),而不是 AR 循环。它的图路径是一个内部 CUDAGraphDecoderWrapper,而不是 vLLM 的外层包装器:

``

在阶段 enforce_eager 为 false 时,在权重加载期间启用

self.code2wav.enable_cudagraph( codec_chunk_frames=chunk_frames, codec_left_context_frames=left_frames, ) ``

从连接器配置进行形状桶化。 在预热之前,包装器从阶段连接器配置读取 codec_chunk_framescodec_left_context_frames。捕获枚举了异步分块和全载荷解码在运行时将会遇到的 (batch, num_quantizers, frames) 桶——包括来自 initial_codec_chunk_frames 的较小第一个分块。

声码器预热。 precompute_snake_caches() 在图捕获之前运行,这样 SnakeBeta 激活就不会在捕获的解码循环内部重复付出设置开销。

分块调度。 在异步分块模式下,chunked_decode_streaming 将稳定分块委派给 _cudagraph_wrapper.chunked_decode_with_cudagraph;全载荷路径在形状匹配捕获桶时使用包装器的批处理解码入口点。

你能获得什么。 在基准扫描中为所有三个阶段开启 CUDA 图,将 req/s 从 2.2 提升到 8.6(+299%),将平均音频 TTFP 从 5884 ms 降低到 2790 ms,并将平均音频 RTF 从 1.15 降低到 0.59。大部分收益来自于同时消除思考者文本生成、说话者编解码解码和 Code2Wav 声码器前向的启动开销。

3. 异步分块:流水线阶段间交接

为什么。 CUDA 图使每个阶段更快,但管道仍然是屏障同步的:说话者必须等到思考者完成才能开始,Code2Wav 必须等到说话者积累完整载荷才能发出音频。因此,首次音频延迟跟踪了完整的思考者生成加上完整的说话者预填充——即使只需要几个编解码帧就能产生第一个可听分块。

为什么它有效。 异步分块用流水线部分交接取代了全载荷屏障。思考者增量地发射嵌入行;说话者积累编解码帧,并按 initial_codec_chunk_frames / codec_chunk_frames 边界进行切片;异步调度器将分块传输与阶段计算重叠,因此每个阶段在前一阶段仍在解码时就开始工作——首次音频在几个编解码帧之后就准备就绪,而不是等待完整的思考者生成加上说话者预填充。

图 4:没有异步分块时,每个阶段等待前一阶段的完整载荷,因此首次音频跟踪完整的思考者生成加上说话者预填充。异步分块重叠部分交接,因此 Code2Wav 在仅几个编解码帧后就开始发出音频。图 4:没有异步分块时,每个阶段等待前一阶段的完整载荷,因此首次音频跟踪完整的思考者生成加上说话者预填充。异步分块重叠部分交接,因此 Code2Wav 在仅几个编解码帧后就开始发出音频。

你能获得什么。 异步分块是扫描中最大的音频 TTFP 收益:平均音频 TTFP 从 2790 ms(CUDA 图)降低到 655 ms

4. 异步输出:非阻塞载荷构建

为什么。 异步分块流水线化了思考者→说话者→Code2Wav,但同步载荷构建仍然可能阻塞解码工人。如果思考者在每次分块边界处必须完全组装每个连接器载荷——复制嵌入和隐藏状态——然后下一个解码步骤才能开始,即使阶段交接已经是增量的,GPU 时间也会因 Python 调度而损失。

为什么它有效。 async_omni_output 将载荷构建与阶段交接解耦:思考者将解码状态交给一个非阻塞

相似文章

Qwen3.7预览版登陆Arena(1分钟阅读)

TLDR AI

阿里巴巴Qwen宣布两大重要模型发布:Qwen3-Omni,首个原生端到端全模态AI,统一处理文本、图像、音频和视频;以及Qwen3-Next-80B-A3B,一款超高效MoE模型,每个token激活30亿参数,实现了SOTA性能,推理速度比Qwen3-32B快10倍。

QWEN3.6 + ik_llama 快得离谱

Reddit r/LocalLLaMA

用户报告成功部署 Qwen 3.6 与 ik_llama 量化,在消费级硬件(16GB VRAM、32GB RAM)上实现 200k 上下文窗口下 50+ token/秒。

Qwen3.5-Omni 技术报告

Hugging Face Daily Papers

Qwen3.5-Omni 是一个千亿参数的多模态模型,具备先进的音视频理解与生成能力,引入了新颖的 Audio-Visual Vibe Coding,在215项基准测试中取得SOTA结果,同时与 Gemini-3.1 Pro 持平。