将 vLLM 部署到 production
在生产环境中部署 vLLM:在 Linux 上安装它(通过 pip 或 Docker 镜像 vllm/vllm-openai),使用您的模型启动 vllm serve,设置 --gpu-memory-utilization 和 --max-model-len,启用 --api-key,然后在服务器前部署反向代理。服务器监听 8000 端口,提供兼容 OpenAI 的 API。它一次只为一个模型提供服务,着重满足大量用户同时使用时的吞吐量需求。
vLLM 是为让大量并行请求共享一个 GPU 而设计的推理服务器。本指南涵盖内存容量规划(真正的核心问题)、安装、启动、Docker 和 systemd、关键参数、吞吐量测量及安全,并作出一项重要纠正:--api-key 选项只保护部分路由。
#vLLM 的功能与要求
vLLM 是诞生于加州大学伯克利分校 Sky Computing 实验室的开源推理引擎。其核心理念 PagedAttention 按页管理注意力机制的键值缓存,类似于操作系统的虚拟内存。根据该项目 2023 年的最初公告,当时的现有系统浪费了很大一部分内存,而在当时的测试中,vLLM 的吞吐量最高达到 Hugging Face Transformers 的 24 倍、TGI 的 3.5 倍。这些数值年代较早,而且仅适用于该测试环境:它们反映的是一个方向,并不代表您使用自己的模型和显卡时能获得的结果。
前置要求方面,当前文档要求 Linux 和 Python 3.10 至 3.13;在 Mac 上则有独立路径,即 vLLM-Metal,其基于 MLX。服务端提供兼容 OpenAI 的 API,默认监听 8000 端口,且每次仅支持一个模型运行:若需同时运行多个模型,则需部署多个实例。
#何时选择 vLLM 而非 Ollama
只需 1 小时,即可在您的电脑上拥有专属的免费 ChatGPT — LM Studio、Ollama、Open WebUI、您的文档,无需云端。
- 在线空间,终身可用
- PDF + 文件
- 30 天内退款
区别不在于能否并行处理请求——Ollama 也具备这一能力——而在于内存的共享方式。根据 Ollama 的常见问题解答,对一个模型进行并行处理时,上下文大小会乘以请求数量:2,000 个 token 的上下文在 4 个并行请求下,会变成内存中预先保留的 8,000 个 token 的上下文。vLLM 按需以块为单位分配缓存,并将正在处理的请求合并到同一批计算中。
| 标准 | Ollama | vLLM |
|---|---|---|
| 并发用户数 | 1 到若干个;OLLAMA_NUM_PARALLEL 参数控制并行度 | 数十个并发请求 |
| 提供的模型 | 多个模型,按需加载和卸载 | 每个实例仅一个 |
| 部署 | 一个安装命令 | Python、CUDA及需调整的参数 |
| 量化方式 | GGUF,选择丰富 | Hub 上的格式(AWQ、GPTQ、FP8);部分支持 GGUF |
| 监控指标 | 本指南中未详细说明 | 有文档说明的/metrics端点 |
| 典型用途 | 个人工作站、小团队 | 内部服务或产品 |
实用原则:如果同时使用模型的人数少于三人,或者您希望经常更换模型,Ollama 就足够了。超过这一人数,或持续提供同一个模型的服务时,vLLM 带来的收益就值得承担其复杂性。对比指南详细说明了如何选择。
#哪些情况下不宜选择 vLLM
对于独自使用一块 8 至 12 GB 显存 GPU 的用户,vLLM 没有任何帮助:显存不足以容纳共享缓存,而 Ollama 或 llama.cpp 启动起来更简单。如果您一天中要在五个模型之间切换,vLLM 就不太适合,因为每换一个模型都需要重新启动一个实例。在 Mac 上,路线不同,依赖的是 MLX。最后,如果您需要的是供团队使用的聊天界面,而不是高负载 API,那么 Ollama 搭配 Open WebUI 的技术栈更能满足需求,运维工作也更少。
#确定内存需求:首先要做的计算
vLLM服务器的规模由键值缓存决定,而非模型权重。加载模型后,vLLM会预留GPU内存的一部分,当前配置代码默认为92%,剩余部分全部用于缓存。这一剩余空间决定了可以同时存在的对话token数量,从而决定了可同时服务的用户数量。
以 Qwen2.5-7B-Instruct 为例,其模型说明列出了 76.1 亿个参数、28 层和 4 个键值头(分组注意力)。16 位精度下的权重大小约为 15.2 GB。单个 token 的缓存大小为 2(键和值)× 28 层 × 4 个头 × 128 维 × 2 字节,即 57 344 字节,约 56 KiB。
| GPU内存 | 按 92% 预留的显存 | 留给缓存的剩余空间 | 缓存令牌(上限) | 折合为每次 4,096 token 的请求数量 |
|---|---|---|---|---|
| 24 GB | 22.1 GB | 6.9 GB | 约 12 万 | 约29 |
| 48 GB | 44.2 GB | 28.9 GB | 约 50 万 | 约120 |
| 80 GB | 73.6 GB | 58.4 GB | 约 100 万 | 约 250 |
这些上限估算偏高:计算缓冲区和CUDA图会占用一部分剩余显存,而模型也可能有不同的内存占用特征。这一方法仍适用于任何模型:查看模型说明中的层数和键值头数量,计算每个token的内存开销,再用剩余显存除以这一开销。如果日志中出现抢占,文档建议提高gpu_memory_utilization或降低max_num_seqs。
有两种方法可以在不更换显卡的情况下扩大缓存:加载模型的量化版本,减少权重占用的内存;或限制 --max-model-len,避免为无人使用的上下文长度预留空间。前者可能略微降低质量;后者只要请求保持简短,就没有代价。
#1. 安装
文档建议使用uv,它会根据您的CUDA驱动程序自动选择合适的PyTorch版本。对于AMD GPU,安装通过专用索引完成;对于Intel、TPU或Ascend,存在相应的插件。在生产环境中,Docker镜像可避免CUDA版本冲突,仅通过更改标签即可更新。
#2. 启动服务器
vllm serve 命令取代了旧的 python -m vllm.entrypoints.openai.api_server 调用方式,当前文档已不再使用后者。首次启动时,模型权重会从 Hugging Face 下载:请预留磁盘空间(16 位的 7B 模型约需 15 GB)。服务器默认采用模型仓库中的 generation_config.json 文件,也就是模型发布方推荐的采样参数;--generation-config vllm 可恢复 vLLM 的默认值。
#3. Docker 和 systemd
官方镜像 vllm/vllm-openai 是最稳妥的选择。请挂载 Hugging Face 缓存,避免重新下载权重,并为编译缓存挂载一个卷:否则,每个新容器都会从空缓存启动,重新编译其模型的产物。请注意,该镜像默认以 root 用户运行;文档介绍了使用非特权用户运行的方法(--user 2000:0)。
#4. 重要参数
| 参数 | 角色 | 建议 |
|---|---|---|
| --gpu-memory-utilization | 预留的 GPU 显存比例(默认值为 0.92) | 如果其他进程正在使用 GPU,则调低;如果日志显示发生抢占,则调高 |
| --max-model-len | 支持的最大上下文长度 | 尽可能低:每个上下文 token 都会消耗缓存 |
| --max-num-seqs | 单批次中请求的最大数量 | 内存不足时调低 |
| --tensor-parallel-size | 将模型分布在节点中的多个 GPU 上 | 仅当单张 GPU 的显存容纳不下模型时 |
| --api-key | 部分路由需要密钥 | 参见安全章节:单独使用不足 |
| --generation-config vllm | 忽略模型的generation_config.json文件 | 回答与您的预期不符时使用 |
文档提出的一条原则是:如果单个 GPU 就能容纳模型,那么分布式运行很可能没有必要;如果单个 GPU 容纳不下,但一个节点能容纳,则通过 --tensor-parallel-size 使用张量并行。已量化的模型直接从 Hub 加载,无需特殊选项:--quantization 选项仅用于动态量化。
#5. 正确测量吞吐量
vllm bench serve命令会向服务器发送请求,并报告吞吐量、首个token生成前的等待时间(TTFT)以及token之间的延迟。文档指出,这些基准测试主要用于评估功能和检测回归问题,并建议使用GuideLLM测试生产环境服务器。
#部署与运行
完成容量规划后,上线始终遵循同一套流程。这套流程适用于约二十人的团队,共同使用一个拥有70亿至80亿参数、运行在24 GB或48 GB显存显卡上的模型进行查询。
- 01选择模型和格式每个实例只运行一个模型。请根据可用内存,优先选择提供已量化或 16 位模型权重的仓库。
- 02计算缓存按照容量规划部分中按每个 token 计算的方法,确定 --max-model-len 和 --max-num-seqs 的值。
- 03在Docker中启动使用官方镜像,挂载Hugging Face缓存,并使用固定版本标签而非latest,以避免更新导致行为变化。
- 04添加代理使用配置了路由白名单、TLS 和请求速率限制的反向代理,再辅以 API 密钥。
- 05测量使用 vllm bench serve 工具进行负载测试,改变随机种子,记录 TTFT 和总吞吐量。
- 06监测将 /metrics 端点的数据采集接入您的监控工具。
需要监控的是预示缓存不足的信号:日志中的抢占、TTFT 上升,以及等待队列变长。文档指出,抢占的默认模式是重新计算;它能保护服务,但会增加端到端延迟。如果抢占变得频繁,请提高 gpu_memory_utilization、缩短上下文,或限制并发请求数量。最后的办法是增加一块 GPU,并通过张量并行将模型分配到多块 GPU 上。
#6. 安全与对外开放:仅有 --api-key 还不够
与人们常以为的相反,vLLM 支持通过 --api-key 或 VLLM_API_KEY 环境变量验证 API 密钥。但安全文档强调:该密钥仅保护 /v1、/v2、/inference 和 /cohere 路径下的接口。其他路径不进行身份验证,包括非 /v1 的推理路径、控制路径如 /pause 或 /abort_requests,以及 /health。因此,切勿仅依赖 --api-key 实现安全防护。
- 反向代理
- 在 vLLM 前面部署 nginx、Envoy 或 Kubernetes 网关,仅允许白名单中的路由访问,其余全部拦截。
- 网络
- 使用 VPN 或隔离网络:分布式部署中各节点之间的通信默认没有安全保护。
- 开发模式
- 切勿在生产环境中启用 VLLM_SERVER_DEV_MODE=1:该设置会暴露危险接口。
- 限制
- 按照文档建议,在代理层实施请求速率限制和请求验证。
- 日志
- 记录发送者和发送内容,以支持调试和审计。
vLLM 在生产环境中是否优于 Ollama?+
如何启动一个兼容 OpenAI API 的 vLLM 服务?+
vLLM需要多少VRAM?+
仅使用 --api-key 选项是否足以保障 vLLM 的安全?+
vLLM 是否支持 Mac 或 AMD 显卡?+
有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。