
vllm-omni 实战指南Qwen2.5-Omni 在线服务的部署、多模态请求、模态控制与 Web UI 演示【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omniQwen2.5-Omni 是支持文本、音频、图像与视频统一感知、并可生成文本与语音的全模态模型。本文以仓库文档 docs/user_guide/examples/online_serving/qwen2_5_omni.md 为骨架结合 examples/online_serving/qwen2_5_omni 目录下的客户端脚本、curl 脚本与 Gradio 演示以及 vllm_omni/deploy/qwen2_5_omni.yaml 部署配置和端到端测试完整讲解如何在 vllm-omni 上以 OpenAI 兼容 API 在线部署 Qwen2.5-Omni-7B并掌握多模态请求构造、输出模态控制仅文本 / 文本语音、流式输出与浏览器 Web UI 交互的完整实战能力。背景Qwen2.5-Omni 在 vllm-omni 中的在线服务形态vllm-omni 是面向 omni 模态模型的高效推理框架Qwen2.5-Omni 是其在在线服务场景下的代表模型之一。该模型的推理被拆分为三段式流水线见 vllm_omni/deploy/qwen2_5_omni.yaml 中的stages定义Stage职责关键采样默认值stage 0Thinker文本/感知主干处理音视频输入并生成文本与语音 tokentemperature0.0、top_p1.0、top_k-1、max_tokens2048stage 1Talker生成语音 codec token 流temperature0.9、top_p0.8、top_k40、stop_token_ids[8294]stage 2Code2Wav将 codec token 还原为波形音频temperature0.0、top_p1.0、max_tokens2048三个 stage 的模型实现分别位于 vllm_omni/model_executor/models/qwen2_5_omni 下的qwen2_5_omni_thinker.py、qwen2_5_omni_talker.py与qwen2_5_omni_token2wav.pystage 之间的数据传递thinker→talker、talker→code2wav由 vllm_omni/model_executor/stage_input_processors/qwen2_5_omni.py 实现。理解这一结构有助于后续把握输出模态控制与流式输出的行为差异。环境准备与安装在线服务以 OpenAI 兼容的 HTTP API 形式对外提供因此首先需要安装 vllm-omni 及运行vllm serve所需的环境。安装步骤以仓库根目录的 README.md 为准亦可在 docs/getting_started/quickstart.md 查看快速上手说明。特别地如果后续要运行本地 Gradio Web UI 演示需要额外安装demo扩展依赖pip install vllm-omni[demo]若从源码安装则使用pip install -e .[demo]demoextras 是可选依赖仅在需要浏览器交互界面时安装examples/online_serving/qwen2_5_omni/gradio_demo.py 的导入处也会在缺失时给出明确提示。启动 Qwen2.5-Omni 在线推理服务器在安装完成后用一条命令即可拉起服务vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091参数说明Qwen/Qwen2.5-Omni-7B模型名称/路径也可替换为本地权重目录--omni启用 vllm-omni 的 omni 多模态流水线必须携带否则不会走三段式部署--port 8091API 服务监听端口后续所有客户端请求都指向该端口。如需使用自定义部署配置例如调整各 stage 的显存分配、设备布局或采样参数通过--deploy-config指定 YAML 文件vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091 --deploy-config /path/to/deploy_config.yaml仓库内置的默认部署配置即为 vllm_omni/deploy/qwen2_5_omni.yaml其中每个 stage 都显式设置了max_num_batched_tokens32768、max_num_seqs1、gpu_memory_utilization、enforce_eagertrue、enable_prefix_cachingfalse等字段未写明的字段会回落到StageDeployConfig的默认值见 vllm_omni/config/stage_config.py。例如 stage 2code2wav之所以关闭enable_flashinfer_autotune是因为其 DiT 块并不调用 flashinfer自动调优的 dummy run 会在共享的cuda:0上引发 OOM——这属于源码注释中明确记录的部署经验。发送多模态请求服务启动后进入示例目录以使用配套脚本cd examples/online_serving/qwen2_5_omni该目录下包含四个文件README.md、gradio_demo.py、run_curl_multimodal_generation.sh、run_gradio_demo.sh以及位于上级目录、可复用的通用多模态客户端 examples/online_serving/openai_chat_completion_client_for_multimodal_generation.py。通过 Python 客户端发送请求python openai_chat_completion_client_for_multimodal_generation.py --query-type mixed_modalities --port 8091 --host localhost客户端支持以下命令行参数参数简写说明--query-type-q查询类型默认mixed_modalities。选项mixed_modalities、use_audio_in_video、multi_audios、text--video-path-v本地视频文件路径或 URL。未提供且查询类型需要视频时使用默认视频 URL。本地文件会被自动编码为 base64也支持 HTTP/HTTPS URL。示例--video-path /path/to/video.mp4或--video-path https://example.com/video.mp4--image-path-i本地图片文件路径或 URL。未提供且查询类型需要图片时使用默认图片 URL。支持本地文件自动 base64与 URL以及 JPEG、PNG、GIF、WebP 等常见格式。示例--image-path /path/to/image.jpg--audio-path-a本地音频文件路径或 URL。未提供且查询类型需要音频时使用默认音频 URL。支持 MP3、WAV、OGG、FLAC、M4A 等常见格式。示例--audio-path /path/to/audio.wav--prompt-p自定义文本提示/问题。未提供时使用所选查询类型的默认 prompt。示例--prompt What are the main activities shown in this video?一个音视频图像全部使用本地文件的混合模态示例python openai_chat_completion_client_for_multimodal_generation.py \ --query-type mixed_modalities \ --video-path /path/to/your/video.mp4 \ --image-path /path/to/your/image.jpg \ --audio-path /path/to/your/audio.wav \ --prompt Analyze all the media content and provide a comprehensive summary.从 客户端源码 可以补充几个重要实现细节本地文件自动 base64 化get_video_url_from_path/get_image_url_from_path/get_audio_url_from_path会依据扩展名推断 MIME 类型视频mp4/webm/mov/avi/mkv图片jpg/png/gif/webp音频mp3/wav/ogg/flac/m4a将本地文件编码为data:mime;base64,...形式URL 则原样透传默认素材未提供路径时使用内置默认资源例如视频为sample_demo_1.mp4、图片为cherry_blossom.jpg、音频为mary_had_lamb通过vllm.assets.audio.AudioAsset获取模型参数需显式指定虽然文档示例未写--model但客户端源码中--model的默认值是Qwen/Qwen3-Omni-30B-A3B-Instruct与本文的 Qwen2.5-Omni 服务不一致因此建议始终显式追加--model Qwen/Qwen2.5-Omni-7B示例目录内的 README.md 即采用该写法更多进阶参数客户端还支持--modalities输出模态、--stream流式、--num-concurrent-requests并发请求数配合--prompts、--speakers按请求覆盖 prompt 与 TTS 音色--speaker通过extra_body传给 talker stage客户端同时注册了use_image、use_video、use_audio、use_mixed_modalities、use_multi_audios等别名查询类型见源码中的query_map文档主表中的四种类型均可直接使用。通过 curl 发送请求仓库提供了封装好的 curl 脚本一条命令即可发送多模态请求bash run_curl_multimodal_generation.sh mixed_modalitiesrun_curl_multimodal_generation.sh 的用法为./run_curl_multimodal_generation.sh [query_type] [modalities]query_type支持mixed_modalities、use_audio_in_video、multi_audios、text四类第二个参数modalities默认为null。脚本内部做了几件值得关注的事按查询类型构建 user contentmixed_modalities会同时携带audio_url、image_url、video_url与文本问题use_audio_in_video仅发送视频与文本并通过mm_processor_kwargs: {use_audio_in_video: true}让服务端自动抽取视频音轨multi_audios发送两段音频让模型判断是否相同可选的三段采样参数thinker_sampling_params、talker_sampling_params、code2wav_sampling_params会以sampling_params_list数组随请求体下发。脚本注释明确说明该块是可选的——若省略各 stage 采样参数取解析后 pipeline 与 deploy config 中的默认值请求体结构包含model、sampling_params_list、mm_processor_kwargs、modalities、messagessystem 角色声明Qwen由 Qwen 团队开发、可感知视听输入并生成文本与语音的虚拟人等字段输出仅展示第一个 choice 的文本内容音频为二进制不直接打印并通过jq提取choices[0].message.content。输出模态控制vllm-omni 允许通过请求中的modalities字段控制模型生成哪些输出模态。当你只需要文本、希望跳过音频生成阶段以提升性能时这一能力尤其有用。支持的模态组合modalities输出[text]仅文本[audio]文本 音频[text, audio]文本 音频不指定文本 音频默认使用 curl仅文本curl http://localhost:8091/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen2.5-Omni-7B, messages: [{role: user, content: Describe vLLM in brief.}], modalities: [text] }文本 音频curl http://localhost:8091/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen2.5-Omni-7B, messages: [{role: user, content: Describe vLLM in brief.}], modalities: [audio] }使用 Python 客户端python openai_chat_completion_client_for_multimodal_generation.py \ --query-type mixed_modalities \ --modalities text客户端会将--modalities按逗号切分后透传给client.chat.completions.create(..., modalitiesoutput_modalities)。值得注意的是即使只指定[audio]服务端依然会返回文本作为音频的中间产物因此表格中[audio]与[text, audio]的输出均为文本 音频。使用 OpenAI Python SDK仅文本from openai import OpenAI client OpenAI(base_urlhttp://localhost:8091/v1, api_keyEMPTY) response client.chat.completions.create( modelQwen/Qwen2.5-Omni-7B, messages[{role: user, content: Describe vLLM in brief.}], modalities[text] ) print(response.choices[0].message.content)文本 音频from openai import OpenAI client OpenAI(base_urlhttp://localhost:8091/v1, api_keyEMPTY) response client.chat.completions.create( modelQwen/Qwen2.5-Omni-7B, messages[{role: user, content: Describe vLLM in brief.}], modalities[audio] ) # Response contains two choices: one with text, one with audio print(response.choices[0].message.content) # Text response print(response.choices[1].message.audio) # Audio response从 gradio_demo.py 的响应处理逻辑可以看到音频以 base64 编码内嵌于choice.message.audio.data客户端解码后用soundfile读回波形并转为(sample_rate, np.ndarray)供播放或保存通用客户端 则直接以audio_request_id_index.wav落盘。流式输出流式模式下输出按对应 stage 的生成进度实时返回最终结果在相应 stage 生成完毕后即可获取。目前仅支持文本流式输出其他模态音频仍按常规方式输出。python openai_chat_completion_client_for_multimodal_generation.py \ --query-type mixed_modalities \ --stream在客户端源码中流式响应的每个chunk携带modality字段当chunk.modality audio时对 base64 音频增量解码并保存为 wav当chunk.modality text时逐段打印文本。这也解释了为什么最终输出会在对应 stage 生成完毕后获得——文本由 thinker/talker 阶段产出可即时流式返回而音频需等待 code2wav 完成整个 codec token 到波形的转换。本地 Web UI 演示Gradiovllm-omni 为 Qwen2.5-Omni 提供了浏览器交互界面用户可以通过网页上传图片、音频、视频并输入文本实时查看文本与音频输出。该演示连接 vLLM API 服务器提供两种启动方式。方式一一键启动脚本推荐./run_gradio_demo.sh --model Qwen/Qwen2.5-Omni-7B --server-port 8091 --gradio-port 7861run_gradio_demo.sh 会自动完成四件事后台启动 vLLM 服务器等待服务器就绪通过tail -f监听日志中的Application startup complete关键字超时上限 300 秒启动 Gradio 演示按CtrlC时通过trap信号处理器统一清理两个进程。脚本支持的参数如下参数默认值说明--modelQwen/Qwen2.5-Omni-7B模型名称/路径--server-port8091vLLM 服务器端口--gradio-port7861Gradio 演示端口--deploy-config无自定义部署配置 YAML 路径可选--server-host0.0.0.0vLLM 服务器监听地址--gradio-ip127.0.0.1Gradio 演示 IP--sharefalse是否公开分享 Gradio生成公网链接方式二手动两步启动Step 1启动 vLLM API 服务器vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091使用自定义部署配置时vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091 --deploy-config /path/to/deploy_config.yamlStep 2在另一个终端运行 Gradio 演示python gradio_demo.py --model Qwen/Qwen2.5-Omni-7B --api-base http://localhost:8091/v1 --port 7861随后在浏览器打开http://localhost:7861/即可交互。gradio_demo.py 支持的参数参数默认值说明--modelQwen/Qwen2.5-Omni-7B模型名称/路径应与服务端一致--api-basehttp://localhost:8091/v1vLLM API 服务器地址--ip127.0.0.1Gradio 服务 IP--port7861Gradio 服务端口--sharefalse公开分享 Gradio 演示从演示源码可以看到界面与实现细节页面提供文本输入框、图片上传gr.Image、视频上传gr.Video附从视频提取音轨复选框勾选后自动设置mm_processor_kwargs[use_audio_in_video]True并将num_frames设为 32、音频上传支持上传与麦克风录音输出区为文本框与音频播放器。请求通过 OpenAI SDK 发出extra_body携带sampling_params_listthinker/talker/code2wav 三段参数其中 talker 含stop_token_ids: [8294]与可选的mm_processor_kwargs。SUPPORTED_MODELS目前登记了 3B 与 7B 两个尺寸并使用固定 seed42做确定性采样。源码级验证部署配置与端到端测试除了文档中的操作步骤仓库还提供了两层可验证的事实依据。默认部署配置的硬件适配vllm_omni/deploy/qwen2_5_omni.yaml 的注释明确指出该配置在 2×H100 上验证通过并给出了跨平台覆盖策略CUDA 默认stage 0thinker与 stage 1talker使用enforce_eager: truethinker 依赖无法被 cudagraph 干净追踪的自定义算子stage 2code2wav与 stage 0 共享cuda:0gpu_memory_utilization: 0.15NPU 覆盖NPU 上 thinker 支持 cudagraph故enforce_eager: falsestage 2 被挪到独立卡devices: 23-NPU 布局XPU 覆盖PyTorch 2.13 XPU Dynamo 编译两个 AR stage 时会触发重复 handler 断言故保持 eager并分别调整了三个 stage 的gpu_memory_utilization0.9 / 0.5 / 0.3stage 2 与 stage 1 共享devices: 1。阶段间数据流转的关键 tokenvllm_omni/model_executor/stage_input_processors/qwen2_5_omni.py 定义了TALKER_CODEC_PAD_TOKEN_ID 8292、TALKER_CODEC_START_TOKEN_ID 8293、TALKER_CODEC_END_TOKEN_ID 8294talker→code2wav 时通过_strip_codec_boundaries剥离 START/END/PAD 等控制 token只把真实 codec id 交给 code2wav 还原波形——这正是前面 curl 脚本中 talker 采样参数stop_token_ids: [8294]的由来模型在输出 8294 时结束 codec 流。端到端测试tests/examples/online_serving/test_qwen2_5_omni.py 针对 Qwen2.5-Omni-7B 覆盖了本文涉及的全部场景可视为文档命令的正确用法最权威的验证test_send_multimodal_request_001/002/003分别用 Python 客户端默认 prompt、自定义 prompt与 curl 脚本发送mixed_modalities请求断言文本与音频输出一致音频转写后与文本的余弦相似度 0.9并包含视频baby、book与音频lamb相关关键词test_modality_control_001/002/003分别验证--modalities text、--modalities audio、--modalities audio,text三种组合test_stream_001验证--stream流式输出下文本与音频的一致性测试还通过VLLM_WORKER_MULTIPROC_METHODspawn环境变量与 CI 专用 deploy 配置rocm/xpu 差异由platforms:段自动选择说明多卡部署与平台适配的工程化实践。总结围绕 docs/user_guide/examples/online_serving/qwen2_5_omni.md本文完整还原了 Qwen2.5-Omni 在线服务的端到端链路一条命令启动三段式流水线服务器vllm_omni/deploy/qwen2_5_omni.yaml通过 Python 客户端、curl 脚本或 OpenAI SDK 发送混合模态请求借助modalities字段按需裁剪输出仅文本可显著减少音频阶段开销使用--stream获取实时文本输出并用 Gradio 在浏览器中完成可视化交互。所有命令与参数均可直接在 examples/online_serving/qwen2_5_omni 目录下运行验证相关行为亦被 tests/examples/online_serving/test_qwen2_5_omni.py 的端到端测试覆盖可作为进一步二次开发与性能调优的起点。【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考