vLLM OpenAI 兼容服务端完整指南:架构、六大 API 与协议扩展实践
vLLM 在推理与 serving 引擎的基础上,内置了一个高度兼容 OpenAI 生态的 HTTP 服务端。本文以仓库中 docs/serving/online_serving/openai_compatible_server.md 为骨架,系统讲解该服务端支持的 API 类型、vllm serve 的启动方式、认证边界、vLLM 私有的扩展参数与扩展 HTTP 头,并结合源码(vllm/entrypoints/openai 下的协议与 serving 实现)深入说明每个参数的底层语义。读完本文,你将能用官方 OpenAI Python 客户端(或任意 HTTP 客户端)在零改动的情况下把 vLLM 接入现有 LLM 应用链路,并正确使用其超出 OpenAI 规范的能力。
vLLM 的 HTTP 服务端是什么
vLLM 提供的 HTTP 服务端实现了 OpenAI 官方规范中的多个核心接口,包括 Completions API(/v1/completions)、Chat API(/v1/chat/completions)等,并进一步扩展了 Responses API、批处理接口以及语音、Embedding 等能力。这意味着训练过 LLM serving 的团队可以把 vLLM 当作一个"本地 OpenAI 网关"直接替换,客户端只需要修改 base_url 与 api_key 两个字段。
服务端入口位于 vllm/entrypoints/openai/api_server.py,每个 API 的路由与协议定义分散在同级目录:
- completion:
/v1/completions的路由(api_router.py)、协议(protocol.py)与处理逻辑(serving.py); - chat_completion:
/v1/chat/completions及批处理接口/v1/chat/completions/batch(batch_serving.py); - responses:Responses API 路由、上下文管理与流式事件定义;
run_batch.py、sse_keep_alive.py:批处理离线运行与 SSE 长连接保活。
从文档与源码结构看,vLLM 的 API 层采用"协议模型(Pydantic 校验请求)→ serving 层(编排引擎执行)→ 路由层(FastAPI 暴露端点)"的分层设计。协议文件中用 --8<-- [start:xxx] / --8<-- [end:xxx] 标记的代码片段会被文档系统直接嵌入到 API Reference 小节,保证文档与实现永不脱节。
支持的 API 一览
当前服务端支持的 OpenAI 兼容 API 及其适用模型类型如下表(模型类型说明分别见 文本生成模型 与 Embedding 模型):
| API | 路径 | 适用模型 | 备注 |
|---|---|---|---|
| Completions API | /v1/completions |
文本生成模型 | suffix 参数不受支持 |
| Chat Completions API | /v1/chat/completions |
具备 chat template 的文本生成模型 | user 参数会被忽略;parallel_tool_calls 语义见下文 |
| Chat Completions 批处理 | /v1/chat/completions/batch |
同上 | 单次请求内子请求并行调度 |
| Responses API | /v1/responses、/v1/responses/{response_id}、/v1/responses/{response_id}/cancel |
文本生成模型 | — |
| Embeddings API | /v1/embeddings |
Embedding(池化)模型 | 详细见 Embed 模型指南 |
| Transcriptions API | /v1/audio/transcriptions |
语音识别(ASR)模型 | 见 speech_to_text |
| Translation API | /v1/audio/translations |
语音识别(ASR)模型 | 同上 |
几个容易被忽略的语义细节
user参数被忽略:在 OpenAI 规范中user用于终端用户标识,而 vLLM 出于多租户上下文隔离的复杂度考量选择忽略它。查看 chat_completion/protocol.py 源码可以发现user: str | None = None字段上方明确注释NOTE this will be ignored by vLLM。parallel_tool_calls语义:该参数控制单次请求返回的 tool call 数量。设置为false时 vLLM 保证每请求最多返回 0 或 1 个 tool call;默认值true允许返回多个,但并不保证一定返回多个——最终行为取决于模型本身是否支持并行工具调用,并非所有模型都具备该设计。协议模型中该字段默认值为True(见 protocol.py 中parallel_tool_calls: bool | None = True)。- Chat API 的多模态参数:Chat API 同时支持 Vision 与 Audio 相关参数,多模态输入的完整说明见 Multimodal Inputs 指南。需要注意
image_url.detail参数不受支持。
快速启动并发送第一个请求
启动服务端
首先需要安装 vLLM(也可直接使用 Docker 镜像)。随后使用 vllm serve 命令拉起服务端:
vllm serve NousResearch/Meta-Llama-3-8B-Instruct \
--dtype auto \
--api-key token-abc123
默认监听地址为 http://localhost:8000,API 前缀为 /v1。--dtype auto 表示让引擎自动推断权重精度;--api-key token-abc123 会为请求开启基于 Bearer Token 的认证(注意其保护边界见下节)。全部启动参数可查阅 serve_args 文档 或直接运行 vllm serve --help。
使用官方 OpenAI Python 客户端调用
新建一个 Python 脚本,用官方 openai 客户端发起对话请求:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="token-abc123",
)
completion = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[
{"role": "user", "content": "Hello!"},
],
)
print(completion.choices[0].message)
仓库中还提供了可直接运行的最小客户端示例:openai_chat_completion_client.py(Chat)与 openai_completion_client.py(Completions)。后者示范了 client.models.list() 动态获取模型 ID、以及 n=2、logprobs=3、stream、echo 等参数的标准用法,支持 --stream 命令行开关观察流式输出。
两个关键行为须知
- OpenAI 不支持的参数如何传:vLLM 支持一些 OpenAI 规范之外的采样参数(例如
top_k)。由于客户端 SDK 会做入参校验,需要把这些参数放进extra_body中透传,即extra_body={"top_k": 50}。 generation_config.json的影响:默认情况下,若 Hugging Face 模型仓库中存在generation_config.json,服务端会套用模型作者推荐的采样默认值,从而可能覆盖你显式设置的采样参数默认语义。若希望完全以 vLLM 侧参数为准,启动时追加--generation-config vllm即可关闭该行为。
安全边界:--api-key 并不能保护所有端点
文档开篇即以醒目方式警告:--api-key(或环境变量 VLLM_API_KEY)只对路径前缀为 /v1、/v2、/inference 的端点生效,同一 HTTP 服务上的其他端点并不受保护。最典型的是 /invocations——它暴露了与 /v1 端点等价的推理能力,却绕过了认证。因此不能单独依赖 --api-key 来保护 vLLM 服务。
受保护与不受保护端点的完整清单、以及推荐的安全加固方案(例如部署在反向代理之后),见 安全文档中的 "API Key 认证限制" 一节。对于生产环境,还应当配合 多进程安全部署 相关章节里关于绑定网卡、TLS 终结的实践。
扩展参数(Extra Parameters):突破 OpenAI 规范天花板
vLLM 在 OpenAI 兼容层之外定义了多组"超集"参数,既可以在 OpenAI 客户端里通过 extra_body 传入,也可以在直接使用 HTTP JSON 调用时平铺进请求体。以文档示例的情感分类场景为例:
completion = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[
{"role": "user", "content": "Classify this sentiment: vLLM is wonderful!"},
],
extra_body={
"structured_outputs": {"choice": ["positive", "negative"]},
},
)
下面按 API 类型展开这些参数的完整清单与语义(字段定义直接取自协议源码,可点击对应文件位置核对)。
Completions API 的扩展参数
额外采样参数(定义于 completion/protocol.py 中 completion-sampling-params 标记区,约为 L73–L110):
| 参数 | 默认值 | 说明 |
|---|---|---|
use_beam_search |
False |
是否启用 beam search 解码 |
top_k |
None |
每步采样只保留概率最高的 K 个 token(OpenAI 无此参数) |
min_p |
None |
相对概率阈值过滤(保留概率不低于最高概率 × min_p 的 token) |
repetition_penalty |
None |
重复惩罚系数 |
length_penalty |
1.0 |
长度惩罚,配合 beam search 使用 |
stop_token_ids |
[] |
额外的停止 token ID 列表 |
include_stop_str_in_output |
False |
停止字符串是否包含在输出中 |
ignore_eos |
False |
忽略 EOS token 继续生成 |
min_tokens |
0 |
生成的最少 token 数 |
skip_special_tokens |
True |
输出是否剔除特殊 token |
spaces_between_special_tokens |
True |
特殊 token 之间是否插入空格 |
truncate_prompt_tokens |
None |
截断 prompt 至前/后 N 个 token(≥ -1) |
truncation_side |
None |
left 保留最后 N 个 token,right 保留最前 N 个 |
allowed_token_ids |
None |
只允许从指定词表 ID 集合中采样 |
prompt_logprobs |
None |
返回每个 prompt token 的 logprob 数 |
logprob_token_ids |
None |
除采样 token 外,额外返回指定词表 ID 的 logprob(比 top_logprobs=-1 更高效,常用于多标签打分场景,需与 logprobs=True 配合) |
bad_words |
[] |
禁止生成出现的词表(字符串或 ID) |
额外请求参数(completion-extra-params 标记区,L112 起):包括 prompt_embeds(直接以预计算向量而非文本作为 prompt)、add_special_tokens(默认 True,为文本 prompt 附加 BOS 等特殊 token)、documents(面向 RAG 的文档列表)、chat_template、chat_template_kwargs、mm_processor_kwargs、structured_outputs、request_id 等。
Chat Completions API 的扩展参数
额外采样参数(chat_completion/protocol.py 的 chat-completion-sampling-params 标记区,约 L265–L301):与上述 Completions 采样参数大体一致(use_beam_search、top_k、min_p、repetition_penalty、length_penalty、stop_token_ids、ignore_eos、min_tokens、skip_special_tokens、truncate_prompt_tokens、truncation_side、prompt_logprobs、logprob_token_ids、allowed_token_ids、bad_words),另含 include_stop_str_in_output、spaces_between_special_tokens 等。这些字段与 OpenAI 标准字段(frequency_penalty、logit_bias、max_completion_tokens、reasoning_effort 等)共存于同一个请求模型里。
Chat 专属扩展参数(chat-completion-extra-params 标记区,L303 起)更值得关注:
echo:若为真,模型输出会以最后一条同 role 消息续写;add_generation_prompt(默认True):渲染 chat template 时追加生成 prompt,取值来自模型的 tokenizer 配置;continue_final_message:让最后一条消息保持开放(不加 EOS),模型继续补全它,可用来"预填"回复前半段;与add_generation_prompt互斥;add_special_tokens(默认False):在 chat template 之外额外附加特殊 token。大多数模型的 chat template 已自行处理特殊 token,故默认关闭;documents:形如[{"title": ..., "text": ...}]的文档列表,供支持 RAG 的 chat template 取用(模板不支持 RAG 时该参数无效果);chat_template/chat_template_kwargs:按请求覆盖默认 Jinja 对话模板并注入模板变量。自 transformers v4.44 起不再允许"无默认模板",因此当 tokenizer 未定义模板时必须在服务端或请求中提供;media_io_kwargs:按模态(keyed by modality)向媒体 I/O connector 传递额外参数,与引擎级配置合并;mm_processor_kwargs:透传给 HF processor 的额外参数;structured_outputs:结构化输出约束(JSON Schema / 枚举 choices 等);request_id:调用方自定义的稳定请求 ID。
Responses API 的扩展参数
Responses API 的请求对象与响应对象各有一组扩展字段,分别定义于 responses/protocol.py 的 responses-extra-params 与 responses-response-extra-params 标记区。客户端示例见 openai_responses_client_with_tools.py,流式场景可参考 examples/reasoning/openai_responses_client.py。
扩展 HTTP 头:请求 ID 与优先级调度
除请求体字段外,vLLM 还支持两类扩展 HTTP 头。
X-Request-Id 与 --enable-request-id-headers
该功能默认关闭,需在启动时加 --enable-request-id-headers 开启。开启后,调用方可通过 extra_headers 传入 x-request-id,响应对象上会回显该 ID,便于分布式追踪与日志关联:
# Chat 场景
completion = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role": "user", "content": "Classify this sentiment: vLLM is wonderful!"}],
extra_headers={"x-request-id": "sentiment-classification-00001"},
)
print(completion._request_id)
# 原生 Completions 场景
completion = client.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
prompt="A robot may not injure a human being",
extra_headers={"x-request-id": "completion-test"},
)
print(completion._request_id)
从源码看,请求 ID 会贯穿 serving 层的每个子请求:Chat 场景按 chatcmpl-{base_request_id} 生成(见 chat_completion/serving.py),Completions 场景按 cmpl-{base_request_id} 生成(见 completion/serving.py),且支持在协议层传入自定义 request_id 保持幂等追踪。
X-Vllm-Priority:请求优先级覆盖
Completions、Chat Completions 与 Responses 三个 API 均支持 X-Vllm-Priority 请求头,其值必须是整数,用于覆盖 JSON 请求体中的 priority 字段。注意:非零优先级要求服务端启用了优先级调度(priority scheduling),否则该头部不会生效:
completion = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role": "user", "content": "Hello!"}],
extra_headers={"X-Vllm-Priority": "-10"},
)
快速索引:官方示例与实现对照
| 主题 | 仓库位置 | 用途 |
|---|---|---|
| Chat 客户端示例 | examples/basic/online_serving/openai_chat_completion_client.py | 多轮对话 + 流式演示 |
| Completions 客户端示例 | examples/basic/online_serving/openai_completion_client.py | n、logprobs、echo 演示 |
| Responses + 工具调用示例 | examples/tool_calling/openai_responses_client_with_tools.py | Responses API + tools |
| Responses 客户端(reasoning) | examples/reasoning/openai_responses_client.py | Responses 基础调用 |
| 推理参数总索引 | docs/api/README.md | sampling 等公共参数定义 |
| Chat template 说明 | docs/serving/online_serving/README.md | 对话模板要求 |
| 多模态输入 | docs/features/multimodal_inputs.md | Vision/Audio 入参 |
| 语音 API | docs/serving/online_serving/speech_to_text.md | Transcriptions/Translations |
| Embedding API | docs/models/pooling_models/embed.md | /v1/embeddings 兼容说明 |
| 安全加固 | docs/usage/security.md | 认证边界与反向代理 |
| 服务启动参数 | docs/configuration/serve_args.md | vllm serve 全部 CLI 参数 |
小结
vLLM 的 OpenAI 兼容服务端是一个"协议层与引擎解耦"的成熟实现:对外,Completions / Chat / Responses / Embeddings / 语音六大接口与 OpenAI 规范对齐,让存量客户端几乎零成本切换;对内,通过 extra_body、extra_headers、structured_outputs 等扩展机制把 beam search、优先级调度、结构化输出、RAG 文档注入、多模态等 vLLM 原生能力完整暴露给 HTTP 层。
实践中的三条关键建议:其一,生产部署切勿依赖 --api-key 保护整个服务,务必按 security 文档 在反向代理层补齐认证与传输加密;其二,采样行为同时受 generation_config.json(模型仓库)影响,需要可复现的结果时用 --generation-config vllm 关闭外部默认值;其三,官方客户端是"所见即所得"的最佳参考,遇到协议不确定的参数直接对照上述协议文件中的字段注释即可获得权威解释。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00