十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Qwen3-Omni 离线推理实战:基于 vLLM-Omni 的多阶段流水线、模态控制与异步 Chunk 并发

Qwen3-Omni 离线推理实战:基于 vLLM-Omni 的多阶段流水线、模态控制与异步 Chunk 并发 Qwen3-Omni 离线推理实战基于 vLLM-Omni 的多阶段流水线、模态控制与异步 Chunk 并发【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni本文以 vLLM-Omni 仓库中的 Qwen3-Omni 离线推理示例为核心骨架完整讲解如何用Omni/AsyncOmni入口类在离线场景下运行 Qwen3-OmniThinker/Talker/Code2Wav 三阶段流水线覆盖部署配置--deploy-config、批量/单条提示词、输出模态控制、本地媒体文件输入以及基于async_chunk的阶段级并发原理与用法。读完本文你将能够直接复现示例命令、按需调整部署 YAML并理解 chunk 数据在阶段间流动的底层机制。1. 示例概览先了解目录里有什么示例目录 examples/offline_inference/qwen3_omni 下包含文件作用end2end.py同步入口使用Omni类适合非 async-chunk 流程官方推荐入口end2end_async_chunk.py异步入口使用AsyncOmni类启用阶段级并发run_single_prompt.sh单条音频输入提示词run_single_prompt_tp.sh单条提示词 Thinker 张量并行低显存场景run_multiple_prompts.sh批量文本提示词py_generator模式run_single_prompt_async_chunk.sh单条请求的 async_chunk 版run_multiple_prompts_async_chunk.sh批量请求 并发控制的 async_chunk 版text_prompts_10.txt10 条文本提示词每行一条默认模型为Qwen/Qwen3-Omni-30B-A3B-Instruct见 end2end.py 中的--model参数你可以通过--model换成其他 Qwen3-Omni 变体或本地 checkpoint 路径。2. Setup用--deploy-config覆盖部署配置Qwen3-Omni 是三阶段流水线stage 0 Thinker、stage 1 Talker、stage 2 Code2Wav默认的显存分配、设备布局、采样参数都来自部署配置文件。运行前需要先进入示例目录cd examples/offline_inference/qwen3_omni通过--deploy-config传入部署 YAML可覆盖诸如stage 显存分配gpu_memory_utilization、设备映射devices、默认采样参数default_sampling_params等选项python end2end.py --deploy-config /path/to/your_deploy.yaml部署配置的完整字段说明见仓库文档 docs/configuration/stage_configs.md字段缺省时会回退到StageDeployConfig默认值对应实现见 vllm_omni/config/stage_config.py。仓库为 Qwen3-Omni 提供了三个现成配置vllm_omni/deploy/qwen3_omni_moe.yaml默认2x H100 验证vllm_omni/deploy/qwen3_omni_moe_mori_intranode.yamlvllm_omni/deploy/qwen3_omni_moe_thinking.yaml3. 运行示例3.1 单条提示词bash run_single_prompt.sh对应脚本内容见 run_single_prompt.shpython end2end.py --output-wav output_audio \ --query-type use_audio--query-type use_audio表示输入是一条音频未指定本地音频路径时会使用内置默认音频资产mary_had_lamb。输出音频以 24 kHz 采样率保存为 WAV见 end2end.py。3.2 显存不足时Thinker 张量并行TPbash run_single_prompt_tp.sh脚本在单条提示词基础上增加了--stage-init-timeout 300见 run_single_prompt_tp.sh。脚本注释说明了该参数的含义stage-init-timeout设置单阶段初始化的最大等待时间避免两个 vLLM 阶段在同一张卡上同时初始化。当 Thinker 显存吃紧时可配合部署 YAML 中 stage 0 的tensor_parallel_size例如 NPU 平台下为 2、XPU 平台下为 4见 qwen3_omni_moe.yaml 的platforms段来横向切分 Thinker。3.3 批量提示词py_generator 模式bash run_multiple_prompts.sh对应脚本见 run_multiple_prompts.shpython end2end.py --output-wav output_audio \ --query-type text \ --txt-prompts text_prompts_10.txt \ --py-generator要点--query-type text纯文本输入--txt-prompts仅支持 text 类型代码中对此有断言见 end2end.py。--txt-prompts text_prompts_10.txt从文件按行加载提示词文件见 text_prompts_10.txt。--py-generator处理大量数据时启用Omni.generate()的返回值变为 Python Generator 对象逐条产出结果而非一次性返回便于流式落盘、控制内存。批量模式下每条请求都会保存{request_id}.txt含 Prompt 与文本输出或output_{request_id}.wav音频输出。4. 输出模态控制Qwen3-Omni 默认可能同时产出文本与音频若只想得到某一种模态例如只输出文本可通过--modalities指定python end2end.py --output-wav output_audio \ --query-type use_audio \ --modalities text--modalities支持逗号分隔的模态列表如text、audio、text,audio。实现上--modalities会被按逗号切分并写入每个 prompt 的modalities字段见 end2end.py编排器据此计算请求的最终输出阶段final_stage_id见 omni.py 中基于prompt.get(modalities)的计算逻辑从而跳过不必要的下游阶段。5. 使用本地媒体文件end2end.py支持通过命令行参数直接传入本地媒体文件音频、视频、图片未提供路径时回退到内置默认资产# 使用本地视频文件 python end2end.py --query-type use_video --video-path /path/to/video.mp4 # 使用本地图片文件 python end2end.py --query-type use_image --image-path /path/to/image.jpg # 使用本地音频文件 python end2end.py --query-type use_audio --audio-path /path/to/audio.wav # 组合多个本地媒体文件音视频图混合 python end2end.py --query-type mixed_modalities \ --video-path /path/to/video.mp4 \ --image-path /path/to/image.jpg \ --audio-path /path/to/audio.wav支持的--query-type及对应行为如下与源码 end2end.py 中的query_map一致query-type说明相关参数use_video视频输入默认抽取 16 帧--video-path、--num-frames默认 16use_image图片输入统一转 RGB--image-pathuse_audio音频输入默认 16 kHz 采样率加载--audio-path、--sampling-rate默认 16000text纯文本查询--txt-prompts、--num-promptsmulti_audios多段音频输入源码中为use_multi_audios可对比两段音频内置资产mixed_modalities视频 图片 音频组合输入三个--*-path可同时给出use_audio_in_video视频中嵌入音频轨mm_processor_kwargs.use_audio_in_videoTrue内置资产媒体加载的底层实现值得留意视频经video_to_ndarrays抽取帧序列numpy 数组图片经convert_image_mode(..., RGB)统一通道音频经load_audio(path, srsampling_rate)得到(float32 信号, 采样率)元组后放入multi_modal_data每个查询函数还返回limit_mm_per_prompt如{audio: 1, image: 1, video: 1}用于约束每个 prompt 中各模态的输入数量见 end2end.py。6. Async-chunk真正的阶段级并发6.1 为什么需要 async_chunk同步流程Omni下下游阶段要等上游阶段整体结束后才开始。而async_chunk 模式下下游阶段Talker、Code2Wav可以在上游阶段Thinker尚未结束时提前启动——上游把中间输出切分成 chunk边生成边向下游推送实现真正的阶段级流水线并发。启用条件部署 YAML 顶层需设置async_chunk: true。默认的 qwen3_omni_moe.yaml 已开启见其第 15 行async_chunk: true可直接作为 overlay 基础。硬件需与配置匹配默认三阶段配置在 2x H100 上验证stage 0 独占cuda:0stage 12 共享cuda:1。从源码看async_chunk是部署配置的顶层字段定义见 vllm_omni/config/model.py 的DeployConfig.async_chunk且存在校验逻辑当async_chunkTrue但流水线各阶段都没有提供async_chunk_process_next_stage_input_func时配置校验会直接报错见 vllm_omni/config/omni_config.py确保该开关只作用于真正支持 chunk 语义的流水线。6.2 数据通路不经编排器的 chunk 直传async_chunk 示例使用AsyncOmni见 vllm_omni/entrypoints/async_omni.py替代同步的Omni类异步编排器接收 stage 0 的中间输出并提前触发下游阶段。关键点在于Chunk 数据在阶段 worker 之间通过 in-worker 的OmniChunkTransferAdapter/ connector 直接流转不经过编排器OmniChunkTransferAdapter的实现位于 vllm_omni/distributed/omni_connectors/transfer_adapter/chunk_transfer_adapter.py它负责相邻阶段之间按请求维度的 chunk 收发通过后台线程实现异步 get/put跟踪每个请求的 chunk 索引并跨 chunk 累积 payloadAR 模式下拼接张量/列表同时缓存 prompt token ids 供调度器使用调度器侧通过WAITING_FOR_CHUNK状态转换配合请求在轮询 chunk 期间进入 waiting-for-chunk 队列chunk 到达后恢复到 waiting/running 队列直到检测到 payload 的finished标志结束加载。6.3 单条请求cd examples/offline_inference/qwen3_omni bash run_single_prompt_async_chunk.sh脚本见 run_single_prompt_async_chunk.sh会自动定位仓库根目录并传入默认部署配置python end2end_async_chunk.py \ --query-type use_audio \ --deploy-config ${REPO_ROOT}/vllm_omni/deploy/qwen3_omni_moe.yaml \ --output-dir output_audio_async_chunk6.4 批量请求 并发控制bash run_multiple_prompts_async_chunk.sh --max-in-flight 4--max-in-flight控制请求级并发度默认 1每个请求内部依然具备 async_chunk 的阶段级并发而多个请求之间由asyncio.Semaphore限流实现见 end2end_async_chunk.py。注意并发请求共享同一份 prompt 模板时脚本会先做浅拷贝clone_prompt_for_request见同文件 L170-L179确保每个请求持有独立的multi_modal_data等容器避免并发写冲突。批量脚本默认加载text_prompts_10.txt的 10 条文本提示词并在运行结束时输出汇总统计成功数、墙钟时间、音频总时长、实时率 RTF。6.5 只输出文本跳过音频生成python end2end_async_chunk.py --query-type text --modalities text与同步版一致--modalities控制输出模态。在 async 版中不显式指定采样参数时generate()会自动把输出类型设为 delta增量语义这对大多数多模态用例是更合理的选择见 end2end_async_chunk.py 注释。6.6 自定义部署配置python end2end_async_chunk.py \ --query-type use_audio \ --deploy-config /path/to/your_async_chunk.yaml如需关闭 async_chunk可复制默认 YAML 并把顶层async_chunk改为false再通过--deploy-config传入。AsyncOmni.from_cli_args只转发显式传入的 CLI 参数argparse 默认值不会静默覆盖部署 YAML 中的值见 end2end_async_chunk.py。6.7 其余实用参数end2end_async_chunk.py还提供以下参数见 end2end_async_chunk.py参数默认值说明--max-in-flight1最大并发请求数--request-timeout-sNone单请求超时秒超时请求被取消并记为错误--batch-timeout-sNone整个批次的全局超时秒--stream-audio-to-diskFalse音频 chunk 边到达边写入 WAV而非在内存中累积适合超长音频或高--max-in-flight场景--output-diroutput_audio_async_chunk输出目录同步版为--output-wav已标记 deprecated--num-prompts/--txt-prompts1 / None单条复制或从文件加载提示词异步输出处理还统计了stage-0 first output时间、首音频时间TTFA、音频 chunk 数、端到端延迟等指标便于评估流水线并发带来的收益见 end2end_async_chunk.py。注意同步的end2end.py使用Omni仍然是非 async-chunk 流程的推荐入口。仅当你确实需要 README 中描述的阶段级并发语义对应 PR #962 / #1151时才使用 async_chunk 示例。7. 部署 YAML 详解三阶段配置如何落地以默认的 vllm_omni/deploy/qwen3_omni_moe.yaml 为例其结构分为四块7.1 顶层与连接器async_chunk: true connectors: connector_of_shared_memory: name: SharedMemoryConnector extra: initial_codec_chunk_frames: 4 codec_chunk_frames: 25 codec_left_context_frames: 25async_chunk: true开启阶段级并发SharedMemoryConnector定义阶段间共享内存传输codec_chunk_frames等参数控制编解码 chunk 的帧粒度——chunk 越小流水线重叠度越高但传输/调度开销也越大。7.2 三个 stage字段stage 0Thinkerstage 1Talkerstage 2Code2Wavmax_num_batched_tokens327683276865536max_num_seqs646464gpu_memory_utilization0.90.60.1devices011输入连接—from_stage_0: connector_of_shared_memoryfrom_stage_1: connector_of_shared_memorydefault_sampling_paramstemp 0.0, max_tokens 2048temp 0.9, top_k 50, max_tokens 4096, rep 1.05temp 0.0, top_p 1.0, top_k -1, max_tokens 65536, rep 1.1其他moe_backend: triton、enable_prefix_caching: false同左enable_chunked_prefill: false、async_scheduling: false、enforce_eager: false对照示例脚本中的采样参数见 end2end.pyThinker 使用temperature0.9, top_p0.9, top_k-1, max_tokens1200, repetition_penalty1.05Talker 使用top_k50, max_tokens4096, detokenizeFalse, stop_token_ids[2150]2150即TALKER_CODEC_EOS_TOKEN_ID用于终止 codec 输出Code2Wav 使用贪心采样temperature0.0, max_tokens4096*16, detokenizeTrue。脚本会把三个采样参数列表按实际配置的 stage 数截取all_sampling_params[:num_stages]见 end2end.py因此增减 stage 后采样参数会自动对齐。7.3 平台差异化覆盖YAML 的platforms段按硬件平台覆盖各 stage 参数体现了工程化的兼容处理cudastage 0 指定custom_ops: [rotary_embedding]让 MRoPE 走 CUDA 原生路径——因为 vLLM 0.27 编译后的原生 MRoPE 路径会把 Q/K RMSNorm 归约垂直融合进 rotary 运算从而实质改变 Qwen3-Omni 的音频输出musa对 stage 1/2 清除 checkpoint 级量化元数据hf_overrides.quantization_config: null因为受支持的 Qwen3-Omni ModelOpt checkpoint 只量化 ThinkernpuThinker 改 2 卡 TPtensor_parallel_size: 2、显存降至 0.6、cudagraph_mode: PIECEWISEQwen3-Omni 在 NPU 上不完全支持 FULL cudagraphrocmstage 2 强制enforce_eager: true——Code2Wav 的 UpSample1d 调用F.conv_transpose1d在 ROCm 上走 MIOpen 且不可在 vLLM 外层 graph capture 期间安全捕获xpuThinker 用 4 卡 TP、全部阶段enforce_eager: true且max_cudagraph_capture_size: 0。由此可见同一份 deploy YAML 可以跨平台复用--deploy-config不只是显存开关更是多硬件适配的载体。8. 与仓库其他资源的衔接配置语义stage 缺省字段的回退规则与校验见 vllm_omni/config/stage_config.py 与 vllm_omni/config/omni_config.py完整文档见 docs/configuration/stage_configs.md。入口类同步Omni位于 vllm_omni/entrypoints/omni.py异步AsyncOmni位于 vllm_omni/entrypoints/async_omni.py二者均支持按阶段传入sampling_params_list。在线服务对照离线示例使用Omni/AsyncOmni直接编程需要 HTTP 服务时可参考 examples/online_serving/qwen3_omni 下的在线部署脚本模型注册与部署配置保持一致。端到端测试仓库的 e2e 测试目录 tests/e2e/offline_inference 中包含对 Qwen3-Omni 离线推理路径的覆盖可作为回归验证参考。9. 小结如何选择同步与异步入口场景推荐入口原因常规离线推理、兼容性优先end2end.pyOmniREADME 明确推荐语义简单、验证充分需要阶段级流水线并发、追求更低端到端延迟end2end_async_chunk.pyAsyncOmni下游阶段提前启动chunk 直传不过编排器显存不足run_single_prompt_tp.sh 部署 YAML 的 TP 配置Thinker 张量并行分摊显存大批量数据处理run_multiple_prompts.sh--py-generator逐条产出控制内存占用围绕上述流程最核心的三件事是正确传入--deploy-config与硬件匹配的 YAML、按需用--modalities裁剪输出模态、在需要并发时切换到 async_chunk 系列脚本。三者结合即可在 vLLM-Omni 上稳定跑通 Qwen3-Omni 的离线推理。【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表