VLLM 详细学习笔记 第 3 章 快速上手:离线推理 + OpenAI 兼容服务
第 3 章 快速上手:离线推理 + OpenAI 兼容服务(实践强化版)
目标:用最短时间打通 离线推理脚本 与 OpenAI 兼容在线服务 的最小闭环;理解
SamplingParams的关键项;掌握vllm serve常用启动参数;基于官方 OpenAI Python SDK 完成聊天与流式连通性测试;综合给出健康检查与限流(节流)建议与 Runbook。
3.1 两条最短路径
3.1.1 离线推理(Python 脚本)
vLLM 的离线推理入口是 LLM 类;采样与解码行为由 SamplingParams 控制。官方文档明确这两者的角色分工与最小示例(不同版本文档表述略有差异,但核心一致):LLM 提供批量离线推理接口,SamplingParams 提供温度、top-p、max_tokens 等参数;示例脚本通常以 facebook/opt-125m 为演示模型开箱可跑。(nm-vllm.readthedocs.io)
最小脚本(可直接粘贴运行):
# offline_minimal.py
from vllm import LLM, SamplingParams
prompts = [
"用 2 句话解释什么是 vLLM:",
"给出一个 Python 读取文件并统计行数的示例:",
]
sampling = SamplingParams(
temperature=0.7,
top_p=0.95,
max_tokens=128,
stop=None, # 可选,字符串或列表
presence_penalty=0.0, # vLLM 兼容 OpenAI 同名语义
frequency_penalty=0.0,
)
llm = LLM(model="facebook/opt-125m") # 可替换任意 HF 模型仓库名或本地路径
outputs = llm.generate(prompts, sampling_params=sampling)
for i, out in enumerate(outputs):
print(f"--- Prompt {i} ---")
print(out.outputs[0].text.strip())
上面的示例对应文档里的最小离线推理用法;LLM.generate() 返回与输入 prompt 顺序对齐的输出列表,每个元素里还可取 outputs[k].logprobs/token_ids 等细节用于调试。(nm-vllm.readthedocs.io)
进一步:
LLM也支持多 GPU 的张量并行(tensor_parallel_size),以及更多引擎参数(KV Cache 精度、最大序列长度、显存利用率等),详见 “Engine/Serve 参数总览”。(nm-vllm.readthedocs.io)
3.1.2 在线服务(OpenAI 兼容)
vLLM 自带一个 OpenAI 兼容 HTTP 服务器,实现了 Chat / Completions API 的主要参数与接口;可直接用官方 openai Python 客户端连接。文档明确:支持绝大多数 OpenAI 参数,例外包括 Chat 的 tools/tool_choice 与 Completions 的 suffix;并提供了 vLLM 特有扩展参数(如 guided_* 系列用于结构化输出)。(nm-vllm.readthedocs.io)
一条命令启动:
python -m vllm.entrypoints.openai.api_server \
--model NousResearch/Meta-Llama-3-8B-Instruct \
--dtype auto \
--api-key token-abc123
# 默认监听 0.0.0.0:8000,base_url 将是 http://<host>:8000/v1
用 OpenAI 官方 SDK 直连(聊天):
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token-abc123")
resp = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role":"user","content":"用 1 句话介绍 vLLM 是什么?"}],
)
print(resp.choices[0].message.content)
流式(server-sent events)回传示例:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token-abc123")
stream = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role":"user","content":"逐步回答:如何在容器中部署 vLLM?"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta and delta.content:
print(delta.content, end="", flush=True)
以上代码/参数与文档一致:通过 api_server 启动;使用官方客户端设置 base_url 指向 /v1;返回对象字段与 OpenAI 对齐;扩展参数通过 extra_body 传递。(nm-vllm.readthedocs.io)
3.2 SamplingParams:必会即用
vLLM 的采样参数设计遵循 OpenAI Completion/Chat 的语义,外加若干增强(beam search、min_p、guided_* 等)。常见字段及说明(综合 vLLM 文档多个版本页面信息,以下为实用汇总):(docs.vllm.ai)
| 字段 | 作用(直观解释) | 取值建议/经验 |
|---|---|---|
max_tokens |
最多生成多少新 token | 压成本/稳定性时务必设上限(如 256/512/1024) |
temperature |
温度,越高越随机 | 0–0.7 信息密集;>0.7 创造性更强 |
top_p |
nucleus sampling 累积概率阈值 | 与 temperature 联动;常用 0.9–0.98 |
top_k |
仅从前 k 个候选采样 | 大模型一般 -1(禁用)或 20–50 |
presence_penalty |
存在惩罚(促使覆盖新词) | 0–1 之间,小幅提升去重复 |
frequency_penalty |
频率惩罚(抑制重复词) | 0–1 之间,文本去复读利器 |
stop/stop_token_ids |
早停控制(字符串/ID) | 强约束格式常配合使用 |
use_beam_search/best_of |
束搜索/候选数 | 需要更确定输出时考虑,注意吞吐影响 |
min_p |
Nucleus 的替代变种,罕见 token 更易入选 | 与 top_p 二择一即可 |
guided_* |
结构化输出(JSON/Regex/Grammar/Choice) | 复杂结构首选 guided_json/grammar |
备注:Chat/Completions 的支持与例外见“OpenAI 兼容服务”页面;扩展参数通过
extra_body传入,示例见下。(nm-vllm.readthedocs.io)
结构化输出(扩展参数示例):
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token-abc123")
schema = {
"type": "object",
"properties": {
"title": {"type":"string"},
"tags": {"type":"array","items":{"type":"string"}}
},
"required": ["title","tags"]
}
resp = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role":"user","content":"以 JSON 输出:给本文拟一个标题并列 3 个标签"}],
extra_body={"guided_json": schema, "temperature": 0},
)
print(resp.choices[0].message.content) # 返回即符合 schema
该能力来自 vLLM 的“额外参数”设计,文档列出了 guided_json/regex/grammar/choice 及可选 guided_decoding_backend。(nm-vllm.readthedocs.io)
3.3 vllm serve:启动参数与开箱套路
虽然 api_server 已能跑,但生产/预生产建议使用命令式 vllm serve(或容器镜像)并搭配关键参数。Red Hat 的 vLLM 文档对关键四参给了清晰解释:
--tensor-parallel-size:按 GPU 拆分模型;--gpu-memory-utilization:显存利用率上限(默认 0.9);--max-model-len:限制上下文长度上限;--max-num-batched-tokens:单步批处理 token 上限(吞吐关键)。(docs.redhat.com)
此外,“完整参数列表”涵盖模型、权重加载格式、KV Cache 精度、tokenizer 池、并行策略等,适合做模板化封装。(docs.redhat.com)
常用启动清单(NVIDIA 举例):
vllm serve meta-llama/Meta-Llama-3-8B-Instruct \
--dtype auto \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.9 \
--max-model-len 8192 \
--max-num-batched-tokens 2048 \
--api-key token-abc123 \
--chat-template /path/to/template.jinja # 部分模型需要
如果模型仓库未提供 Chat Template,可手工指定,否则 Chat 请求会报错。文档明确可通过
--chat-template传入 Jinja 模板文本或文件路径。(nm-vllm.readthedocs.io)
量化/特性可用性提示(扩展)
官方与生态对 FP8/AWQ 等量化模型的 serve 命令保持一致(仅模型名不同),例如 Qwen 团队给出了 FP8/AWQ 的用法与硬件能力说明(FP8 需 Ada/Hopper 及以上架构)。(qwen.readthedocs.io)
3.4 最小可行 Runbook(含健康检查 / 限流建议)
下面给出一个自检友好的 Runbook,覆盖下载—启动—连通—观测—告警全链路。
3.4.1 启动前检查
-
模型可用性与 Chat Template
- Hugging Face 模型是否需要申请访问?(私有/协议)
- Chat 模型是否内置
chat_template?若无,准备好--chat-template。(nm-vllm.readthedocs.io)
-
GPU/驱动与内存预算
- 预估
max_model_len × batch_token组合是否会 OOM;必要时降低--max-num-batched-tokens或--max-model-len。官方优化页也建议通过这两项约束并行度以节省 KV Cache 空间。(docs.vllm.ai)
- 预估
-
容器/进程形态
- 容器启动请设置合适的
--shm-size、HF token(如需);Red Hat 文档给出了 Podman 示例与关键环境变量。(docs.redhat.com)
- 容器启动请设置合适的
3.4.2 启动与连通
-
服务启动:
vllm serve(或python -m ...api_server)+ 关键参数。(nm-vllm.readthedocs.io) -
健康检查:
- 官方/社区对
/health的讨论指出:该端点在模型加载后才返回 200(启动初期会不可用),因此就绪探针与存活探针应分离,必要时自定义/ready。(GitHub) - 指标端点:
/metrics(Prometheus),可观测运行/等待请求数、LoRA 请求信息等指标,Red Hat 文档列举了关键指标名。(docs.redhat.com)
- 官方/社区对
-
客户端连通:使用 OpenAI 官方 SDK(上节示例)完成 Chat 与流式校验。(nm-vllm.readthedocs.io)
3.4.3 限流 / 节流与错误处理(4xx/5xx)
现状与建议:
- vLLM 原生“主动 429”能力有限(社区 issue 反馈尚未完备的“繁忙即 429”机制),更多应由网关/反向代理实现(如 NGINX/Envoy/Traefik 或云 API 网关),同时结合并发/令牌感知。(GitHub)
- 运营实践建议采用token 维度配额(每分钟/小时的输入/输出 token限额)+ 并发会话上限。参考通用 LLM API 节流设计经验与文章。(compute.hivenet.com)
- 对 vLLM 实例侧,使用
--max-num-batched-tokens、--max-model-len、--gpu-memory-utilization进行物理层面的“吞吐边界”收敛,避免因超长上下文或巨大 batch 触发 OOM/抖动。(docs.redhat.com)
错误处理要点(对调用方):
- 429 Too Many Requests:在 vLLM 侧未必触发(见上);如由网关返回,需指数退避并在 header 中读取限流窗口(若有);OpenAI 生态中也常见“平台繁忙导致 429”的情形,调用方按惯例做重试/降级。(OpenAI Developer Community)
- 5xx:模型下载失败/冷启动超时/后端过载等可能导致 5xx,外层需熔断与重试策略;在 vLLM 侧配合
/metrics进行突发观测与告警;另外,学术/实践报道亦提到 vLLM 在高压场景可能出现节流/抖动。(docs.redhat.com)
N×M 维度限流方案(参考蓝图)
- 维度:每 API Key × 每路由 × 输入/输出 token × 并发连接;
- 策略:硬阈值(拒绝/429)、软阈值(排队/等待)、配额刷新(滑动窗口/令牌桶);
- 位置:网关优先(负责绝大多数策略),应用层补充(例如在 FastAPI 中读取
/metrics指标做自适应 backpressure)。参考 Runpod 的 vLLM 负载均衡与健康检查教程。(docs.runpod.io)
3.5 “常见问题”快速定位
-
启动后 Chat 报错:多半因缺少 chat template,用
--chat-template指定模板文件或模板字符串。(nm-vllm.readthedocs.io) -
吞吐上不去/TTFT 偏大:
- 先压低
--max-model-len与提升--max-num-batched-tokens以增加并行度(权衡 TPOT/尾延迟); - 观察
/metrics的队列与运行请求数,定位瓶颈。(docs.redhat.com)
- 先压低
-
OOM 或波动:减少
--max-num-batched-tokens或--max_num_seqs(后者在优化指南中同义地影响批并发),并将--gpu-memory-utilization设为安全阈值(如 0.85)。(docs.vllm.ai) -
SDK 连接失败:确认
base_url指向http://host:8000/v1,以及--api-key与请求 header 一致;端口是否暴露;容器网络是否允许入站。(nm-vllm.readthedocs.io)
3.6 实验:启动 vLLM 服务 + OpenAI 客户端连通性(含流式)
实验目的:
- 用任意 HF 指令模型启动
vllm serve; - 用 OpenAI 官方 Python 客户端发起聊天与流式请求,确认连通/回显;
- 记录 TTFT(首 token 时间)与 QPS(可通过并发发压或外部压测器)。
步骤:
- 拉起服务
vllm serve NousResearch/Meta-Llama-3-8B-Instruct \
--dtype auto \
--gpu-memory-utilization 0.9 \
--max-model-len 8192 \
--max-num-batched-tokens 2048 \
--api-key token-abc123
若报 Chat 模板相关错误,追加
--chat-template。(nm-vllm.readthedocs.io)
- 功能连通(非流式)
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token-abc123")
r = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role":"user","content":"给出 3 条使用 vLLM 的最佳实践"}],
temperature=0.2,
max_tokens=200,
)
print(r.choices[0].message.content)
-
流式连通(SSE)
见 3.1.2 的 streaming 代码(逐块打印)。(nm-vllm.readthedocs.io) -
健康与指标
curl http://localhost:8000/metrics | head(确认指标输出);- 若需要就绪探针,在外层(如 K8s/自定义网关)实现
/ready并校验num_requests_running/ num_requests_waiting等指标阈值。(docs.redhat.com)
- 限流演练(可选)
- 在网关配置并发/令牌桶;
- 人为制造超并发,验证 429/队列行为与客户端重试策略。(Medium)
3.7 实操补充:OpenAI 兼容的“扩展参数”
vLLM 允许通过 extra_body={...} 传递扩展字段,用于结构化输出和特殊解码策略。文档给出了完整列表:guided_json、guided_regex、guided_choice、guided_grammar、guided_decoding_backend 等;Chat/Completions 两侧均有对应支持集合。(nm-vllm.readthedocs.io)
例:受限多选(classification)
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token-abc123")
labels = ["正向","中性","负向"]
r = client.chat.completions.create(
model="NousResearch/Meta-Llama-3-8B-Instruct",
messages=[{"role":"user","content":"情感极性:我对新功能很期待,但担心稳定性。"}],
extra_body={"guided_choice": labels, "temperature": 0},
)
print(r.choices[0].message.content) # 必为上述三者之一
3.8 运行参数速查(常更易用)
下表对“快速上手阶段最容易用到”的 serve 参数做归纳(以稳定实践为导向;完整清单以 Red Hat 文档为准):(docs.redhat.com)
| 分组 | 参数 | 用途 | 备注 |
|---|---|---|---|
| 模型 | --model / --revision / --trust-remote-code |
指定模型与版本 | 私有/需协议模型要配置 HF token(环境变量) |
| 精度 | --dtype / --kv-cache-dtype |
权重/激活与 KV Cache 精度 | auto 常用;KV Cache 可选 FP8 等 |
| 并行 | --tensor-parallel-size |
多 GPU 张量并行 | 与拓扑绑定,单机多卡常用 |
| 内存/吞吐 | --gpu-memory-utilization / --max-model-len / --max-num-batched-tokens |
控制显存与批处理 | 三者联动决定吞吐与稳定 |
| 安全 | --api-key |
启用 API 鉴权 | 客户端需带 Authorization: Bearer |
| Chat | --chat-template |
Chat 格式化 | 无模板的指令模型需要 |
| 监控 | (内置)/metrics |
Prometheus 指标 | 观测队列、运行中请求等 |
| 生态 | --lora-modules |
装载 LoRA 适配器 | 详见第 4 章 |
3.9 可靠性与可观测性
- Metrics:访问
/metrics可获得vllm:num_requests_running / waiting / swapped / lora_requests_info等指标(不同版本可能有所增减),用于构建 Grafana 面板与 SLO。Red Hat 文档与 vLLM 早期/版本化文档对这些指标有说明。(docs.redhat.com) - 健康检查:
/health在模型加载完后才 200,K8s 就绪探针需延迟/重试;社区也讨论过引入/ready的最佳实践。(GitHub) - 网关集成:参考 Runpod/社区教程以实现负载均衡与健康路由。(docs.runpod.io)
3.10 常见 4xx/5xx 与定位手册(浓缩)
| 状态码 | 场景 | 处理建议 |
|---|---|---|
| 400 | 参数非法(如 model 不匹配、max_tokens 过大) |
校正采样参数;必要时降 max_model_len 与 max_tokens |
| 401 | 未带 Authorization 或 key 错误 |
确认 --api-key 和客户端一致 |
| 404 | 路由不对(应指向 /v1/...)或 model 名称不匹配 |
确认 base_url 与 model |
| 409 | 资源状态冲突(极少见) | 重试或清理任务 |
| 429 | 外层网关限流或平台繁忙 | 指数退避;对 vLLM 原生 429 不要过度依赖,转向网关/代理侧实现。(OpenAI Developer Community) |
| 5xx | 冷启动超时/下载失败/后端过载 | /metrics + 日志定位;容器拉起/网络/HF token 检查;必要时降并发与 batch。(docs.redhat.com) |
3.11 高阶一口气:从“脚本 → 服务 → 可观测”
- 脚本阶段:确认
LLM + SamplingParams能在本机跑通(样例见 3.1.1)。(nm-vllm.readthedocs.io) - 服务阶段:
vllm serve融合关键四参;openai客户端连通并校验流式。(docs.redhat.com) - 可观测:拉
/metrics指标,结合网关实现令牌感知限流与并发上限,并针对 429/5xx 做降级/重试。(docs.vllm.ai)
3.12 最小可行推理脚本与服务启动 Runbook(可直接复用)
A. 离线脚本(含批量)
# offline_batch.py
from vllm import LLM, SamplingParams
prompts = ["总结:什么是 PagedAttention(50 字以内)?"] * 4 # 批量
sampling = SamplingParams(temperature=0.2, top_p=0.9, max_tokens=80)
llm = LLM(
model="facebook/opt-125m",
tensor_parallel_size=1, # 单卡可设 1
)
outs = llm.generate(prompts, sampling_params=sampling)
print([o.outputs[0].text.strip() for o in outs])
关键点:离线
LLM也支持tensor_parallel_size等配置,便于在脚本中做多卡测试。(vllm.readthedocs.io)
B. 服务启动(生产友好默认)
# 预设:NVIDIA 单机单卡;端口 8000;需要鉴权
export HF_HUB_ENABLE_HF_TRANSFER=1
vllm serve NousResearch/Meta-Llama-3-8B-Instruct \
--dtype auto \
--gpu-memory-utilization 0.9 \
--max-model-len 8192 \
--max-num-batched-tokens 2048 \
--tensor-parallel-size 1 \
--api-key ${VLLM_API_KEY:?missing} \
--chat-template /path/to/template.jinja
C. 健康检查/限流建议(可复制到平台手册)
-
存活探针:TCP/HTTP 200(/health),注:加载完成前不返回 200。
-
就绪探针:自定义
/ready(由网关/sidecar 提供),条件:/metrics中vllm:num_requests_running< 阈值,vllm:num_requests_waiting< 阈值;- 最近 1 分钟 5xx 比例 < X%。(GitHub)
-
限流:
- 每 Key:并发连接 ≤ N;输入/输出 token 每分钟限额;
- 每实例:合适的
--max-num-batched-tokens与--max-model-len; - 返回码:建议在网关层实现 429,并带
Retry-After。(compute.hivenet.com)
3.13 FAQ 速解卡
-
为何我用 OpenAI SDK 直连就能通?
因为 vLLM 的服务实现了 OpenAI Chat/Completions API 的兼容层,SDK 只需改base_url与api_key即可。(nm-vllm.readthedocs.io) -
哪些 OpenAI 参数暂不支持?
Chat 的tools/tool_choice、Completions 的suffix不支持,其它大多支持。(nm-vllm.readthedocs.io) -
如何做 JSON/Regex/Grammar 约束?
通过扩展参数guided_json/regex/grammar/choice(extra_body传入)。(nm-vllm.readthedocs.io) -
如何观察吞吐与排队?
/metrics里有当前运行/等待请求等;结合 Grafana/Prometheus 做可视化。(docs.vllm.ai) -
限流/429 为什么说要靠网关?
vLLM 侧对“繁忙返回 429”的支持并不完备(社区 issue 反馈),而网关天然适合做配额与并发控制。(GitHub)
3.14 小结与本章 Checklist
你应该已经能够:
- 用
LLM + SamplingParams在本地完成离线批量推理;(nm-vllm.readthedocs.io) - 启动
vllm serve并通过 OpenAI 官方 SDK 完成聊天与流式连通性测试;(nm-vllm.readthedocs.io) - 掌握关键四参(
gpu_memory_utilization / max_model_len / max_num_batched_tokens / tensor_parallel_size)的调节方向;(docs.redhat.com) - 在外层网关实现token 感知 + 并发限流,配合
/metrics做健康/就绪判断与告警。(docs.vllm.ai)
附:可复制的“服务启动 Runbook(健康检查/限流版)”
-
准备
- 选择模型并确认 Chat Template;
- 估算 max context / batch tokens,结合显存给出首版参数。(nm-vllm.readthedocs.io)
-
启动
vllm serve <model> --dtype auto --gpu-memory-utilization 0.9 --max-model-len 8192 --max-num-batched-tokens 2048 --api-key ...- 记录启动日志里显存分配与 tokenizer 加载信息。(docs.redhat.com)
-
探活与连通
curl /metrics应有 vLLM 指标;- 用
openaiSDK 跑一条 Chat + 一条 Streaming。(docs.redhat.com)
-
网关策略
- 并发上限(每 key、全局);
- token 限额(输入/输出/总);
- 默认重试与
Retry-After; - 429/5xx 的熔断/灰度。(compute.hivenet.com)
-
监控与告警
- 队列/运行中请求、TTFT/TPOT(可由客户端埋点上报)、OOM/异常日志;
- 根据服务 SLA 设阈值(如
num_requests_waiting连续 > X 触发扩容/流量调度)。(docs.redhat.com)
参考与延伸
- OpenAI 兼容服务总览、示例与扩展参数;包括
extra_body用法与不支持项。(nm-vllm.readthedocs.io)- Red Hat vLLM 服务器参数与指标清单(清晰、系统,适合做企业内模板)。(docs.redhat.com)
- 离线推理与
LLM / SamplingParams快速入门。(nm-vllm.readthedocs.io)- 节流/限流最佳实践与 Token-aware 方案。(compute.hivenet.com)
——至此,你已经完成 “第 3 章:快速上手:离线推理 + OpenAI 兼容服务” 的全部学习与实践闭环。下一步建议在你的机型/模型上沉淀一份参数基线表(含 max_model_len / max_num_batched_tokens / gpu_memory_utilization 三元组),并持续根据 /metrics 与压测数据微调。
更多推荐


所有评论(0)