vLLM-Omni Chat Completions API 实战:多模态对话、vLLM 扩展参数与批量请求
2026/9/17 5:22:03 网站建设 项目流程

vLLM-Omni Chat Completions API 实战:多模态对话、vLLM 扩展参数与批量请求

【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni

vLLM-Omni 通过 OpenAI 兼容的/v1/chat/completions端点统一承载对话式与多模态推理管线:请求可以携带文本、图像、音频或视频输入,响应则可能返回文本、音频、图像或其他模型特定输出。本文基于仓库文档 chat_completions_api.md 与对应服务端源码,讲解基础请求、vLLM 扩展参数的传递方式、扩散模型走 Chat Completions 的兼容约定,以及/v1/chat/completions/batch批量端点的实现细节,帮助你在接入 omni 模型服务时写对请求、避开 400 错误。

一、基础请求:一个端点覆盖多模态对话

vLLM-Omni 的 serve 进程会启动一个 OpenAI 兼容的 HTTP 服务。从 serve CLI 的说明可以看到,服务端会自动识别模型类型:LLM 模型通过/v1/chat/completions提供服务,纯扩散模型则主要走/v1/images/generations。对于支持对话语义的模型(如 Qwen3-Omni 这类 omni 模型),Chat Completions 是默认入口。

最基本的请求如下:

curl http://localhost:8091/v1/chat/completions \ -H "Content-Type: application/json" -d '{ "messages": [ {"role": "user", "content": "Describe vLLM-Omni briefly."} ], "modalities": ["text"] }'

几个要点:

  • modalities字段用于声明本次请求期望的输出模态。请求未显式指定时,服务端会回退到该模型支持的输出模态。
  • 传入stream: true即可获得 Server-Sent Events 流式响应;不传则为一次性 JSON 响应。
  • 输入媒体的消息语法、支持的输出模态以及响应 choice 的形态都依赖具体模型,完整示例见 Qwen3-Omni 在线服务示例。
  • 每个服务进程只承载一个模型。如果客户端要求model字段,可以查询GET /v1/models获取当前服务的模型名。

源码视角:路由与 modalities 校验

在 api_server.py 中,/v1/chat/completions路由被 omni 自定义的 handler 接管(上游 vLLM 的同名路由会被移除后重新注册)。处理逻辑:

  1. 构造Omnichathandler 并调用create_chat_completion
  2. 引擎级错误(EngineGenerateErrorEngineDeadError)会转换为 OpenAI 风格的错误 JSON 响应;
  3. 非流式响应直接以JSONResponse返回(序列化时抑制多模态字段带来的 Pydantic 警告);
  4. 流式请求返回media_type="text/event-stream"StreamingResponse

modalities的校验逻辑在 serving_chat.py:服务端先从引擎读取该模型声明的输出模态列表(engine_client.output_modalities,过滤掉None),请求未提供modalities时自动使用该默认值;若请求显式声明了模型不支持的模态,会返回形如Unsupported output modalities ... Supported modalities: ...的 400 错误。这意味着"能输出什么模态"是由加载的模型与阶段配置决定的,而不是端点本身。

响应协议本身也在标准 OpenAI 结构上做了 omni 扩展。protocol/chat_completion.py 中的OmniChatCompletionResponse/OmniChatCompletionStreamResponse在标准 response 之外增加了metrics字段(阶段级指标,可配合return_stage_metrics开关返回),choice 上则带有可选的audio_metadataAudioChunkMetadata),用于音频分片的元数据。

二、vLLM 扩展参数:标准参数之外怎么传

OpenAI 官方 schema 不包含top_k这类 vLLM 原生参数。vLLM-Omni 的约定是:把标准 Chat 参数和 vLLM 特定参数都作为顶层字段直接放在请求 JSON 里;使用 OpenAI Python SDK 时,则通过extra_body关键字传入——SDK 会把extra_body的内容合并进顶层 JSON。

直接 HTTP(curl):

curl http://localhost:8091/v1/chat/completions \ -H "Content-Type: application/json" -d '{ "messages": [{"role": "user", "content": "Write a short haiku."}], "top_k": 40 }'

OpenAI Python SDK:

from openai import OpenAI client = OpenAI(base_url="http://localhost:8091/v1", api_key="none") response = client.chat.completions.create( model="your-served-model", messages=[{"role": "user", "content": "Write a short haiku."}], extra_body={"top_k": 40}, )

两条路径最终在服务端看到的是同一种顶层 JSON,因此行为完全一致。这一约定也贯穿其他端点,例如 images 协议定义 中 LoRA 字段的注释就明确写道:镜像/v1/chat/completionsextra_body.lora约定。

三、扩散模型走 Chat Completions:兼容性约定与 400 冲突

部分扩散管线也支持通过 Chat Completions 做图像生成与编辑(modalities声明"image"时,serving_chat.py 会从 messages 中提取文本 prompt 与参考图,转成扩散引擎的采样参数)。此时请求可以接受num_inference_stepsseedheightwidth等扩散字段:

  • 直接 HTTP:放在请求顶层;
  • OpenAI SDK:放在extra_body中。

需要注意的兼容边界(文档明确说明):

  • 顶层嵌套一个字面"extra_body"JSON 对象会被接受(兼容既有客户端),但不建议新客户端这样做;
  • 同一个参数不要出现在多个位置。服务端对重复的扩散参数会返回400错误;
  • 如果任务与 Image Generation API 或 Image Edit API 匹配,应优先使用这两个专用端点——它们的请求字段与响应契约更直接。

源码视角:重复参数为什么报 400

上述"多处提供同一参数即报错"的行为由 diffusion_request_utils.py 中的normalize_diffusion_request_args实现。该函数会枚举参数的六个可能来源:

来源路径说明
request.<field>顶层公共/注册字段
request.extra_body.<field>嵌套 extra_body(兼容形式)
request.extra_args顶层模型特定扩展参数(推荐)
request.extra_params已废弃的旧命名(仅告警)
request.extra_body.extra_args/request.extra_body.extra_params嵌套形式

只要同一个 key 出现在两个不同来源(如同时给了顶层seed和嵌套extra_body.seed),函数会抛出ValueError: Diffusion request parameters were provided more than once: ...,最终由上层转成 400 响应。此外还有两个值得注意的规范化规则:

  • cfg_scale会被自动别名到true_cfg_scale(见 serving_chat.py 的_diffusion_root_field_aliases);
  • quality字段有取值校验,必须属于DIFFUSION_QUALITY_LEVELS,否则同样拒绝请求。

extra_params已弃用:如果请求里出现,服务端只会记录一次告警日志并建议使用extra_args

四、批量请求:POST /v1/chat/completions/batch

POST /v1/chat/completions/batch接受与单条请求相同的共享生成字段,区别在于messages是一个对话列表(list of conversations),响应按输入顺序为每个对话返回一个 choice:

curl http://localhost:8091/v1/chat/completions/batch \ -H "Content-Type: application/json" -d '{ "messages": [ [{"role": "user", "content": "Summarize vLLM in one sentence."}], [{"role": "user", "content": "Summarize vLLM-Omni in one sentence."}] ], "max_tokens": 64 }'

明确不支持的能力:流式(stream)、tools、beam search、n > 1

源码视角:批量端点如何复用单条管线

批量处理实现在 batch_serving.py 的OmniOpenAIServingChatBatch.create_batch_chat_completion,关键机制:

  1. 请求 ID 以chatcmpl-batch-<base_id>为前缀,每条子请求分配<base_id>-idx-<i>,避免与单条请求 ID 冲突;
  2. 逐条把messages[i]转换成标准ChatCompletionRequest强制stream = False——如果请求里带了stream: true,只会打一条 warning(Streaming is not supported for batched chat completions; ignoring stream=True.)而非报错;
  3. 所有子请求通过asyncio.gather并发提交给同一个create_chat_completion管线,任一条失败(返回ErrorResponse)则整个批量请求返回该错误;
  4. 对"文本与音频分属两个 choice"的模型,_maybe_collapse_choices会把 content choice 与 audio choice 合并为一个 choice,保证输入条数与响应 choice 严格 1:1;
  5. usage字段汇总所有子请求的 prompt/completion token 数。

从源码结构看,批量端点本质是"同进程内并发重放单条 Chat Completions 管线",因此单条端点支持的所有扩展参数(top_k、扩散字段等)在批量请求中同样可用,而批量特有的限制(禁流式等)是在这一层显式强制的。

五、模型特定示例索引

完整的、带模型特定输入输出(包括图像/音频输入语法)的示例,请参见仓库中的在线服务示例文档:

  • Qwen3-Omni
  • Qwen2.5-Omni
  • Text-to-Image (Qwen-Image)
  • Image-to-Image (Qwen-Image-Edit, Qwen-Image-Layered)
  • GLM-Image

与 Chat Completions 相邻的端点文档(音频、图像、视频等)也在 docs/serving/ 下,可按任务类型选择契约更直接的专用 API。

六、实践清单

结合文档与源码,调用/v1/chat/completions时的检查要点:

  1. GET /v1/models拿到model名,每个服务进程只服务一个模型;
  2. modalities显式声明输出模态;声明超出模型支持范围会得到 400 且错误信息中列出支持的模态;
  3. vLLM 扩展参数(top_k等)顶层直传或经 SDKextra_body传递,两种方式等价;
  4. 扩散任务字段(num_inference_stepsseedheightwidth等)只放一处;同参多处提供会触发 400,cfg_scale会归一为true_cfg_scale
  5. 批量场景用/v1/chat/completions/batchmessages为对话列表,响应 choice 与输入顺序一一对应;不要依赖流式、tools、beam search 或n > 1
  6. 需要阶段指标时通过extra_body中的return_stage_metrics开关控制响应中的metrics字段(见 serving_chat.py 的过滤逻辑)。

【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询