进阶服务器 / VPS 2 分钟阅读发布于 · 更新于

用 vLLM 在 RTX 4090 上搭建多模型 API 服务

用 vLLM 的连续批处理技术,在单张 RTX 4090 上提供生产级多模型 API 服务。

面向的技术栈

RTX 4090 24GB · vLLM(uv 安装)· AWQ INT4 · OpenAI 兼容 API,端口 :8000

最近一次修改后未重新实机运行 —— 命令请当作起点,而不是已验证的配方。

vLLMAWQNVIDIARTX 4090APIDocker

开始之前

一张显存足够容纳模型和 KV 缓存的 NVIDIA 显卡、较新的驱动,以及 Python 3.10 到 3.13 —— vLLM 快速入门在一个新建的虚拟环境里用 3.12,而 `uv pip install` 没有虚拟环境会拒绝运行。vLLM 是服务端,不是聊天应用 —— 当你需要一个能并发处理请求的 OpenAI 兼容端点时用它;如果只是一个人和一个模型对话,用 llama.cpp 或 Ollama。

bash
# vLLM's documented path: a fresh venv, then uv picks the torch build
# that matches your installed CUDA driver.
pip install --upgrade uv
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=auto

vllm --version

启动服务

入口是 `vllm serve` 这个 CLI。大多数教程里仍在用的 `python -m vllm.entrypoints.openai.api_server` 已经不是官方文档推荐的形式了。vLLM 会从模型配置里读出量化方式,所以对 AWQ 检查点来说通常不需要手动传 `--quantization`。

bash
vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.85 \
  --host 127.0.0.1 --port 8000

# Bind to 127.0.0.1 unless you mean to expose the machine. The default
# server has no authentication of its own.

确认它真的起来了

这个服务说的是 OpenAI 协议,所以第一步检查 models 端点 —— 只有在权重加载完、KV 缓存分配完之后它才会响应,而那正是启动过程中慢的那一段。然后发一个补全请求。

bash
curl http://127.0.0.1:8000/v1/models

curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"Qwen/Qwen2.5-7B-Instruct-AWQ","messages":[{"role":"user","content":"hi"}]}'

数字大概该是什么样

Qwen2.5 7B 在 AWQ INT4 下权重为 3.6 GB,4K 上下文合计需要 4.2 GB,32K 时升到 5.9 GB —— 权重不变,变的是 KV 缓存。在带宽 1,008 GB/s 的 RTX 4090 上,单流上限约 278 tok/s。本索引有一条可对照的 vLLM 实测记录:4090 上 Llama 3.1 8B 的 AWQ INT4,218 tok/s。批量吞吐完全是另一个数字,本站没有测过 —— 连续批处理正是使用 vLLM 的理由,但你看到的任何具体倍数都来自别人的硬件。

出问题时

吞吐崩塌,而 vLLM 每隔几秒打印的统计行里 `Preemptions:` 计数不断上涨:说明在途请求的 KV 缓存空间不够。(旧的 `PreemptionMode.RECOMPUTE` 警告来自 vLLM 已被移除的 V0 引擎 —— 现在的版本改在那行统计和 `vllm:num_preemptions` 指标里报告抢占。)提高 `--gpu-memory-utilization`,或降低 `--max-num-seqs` 减少批内请求数,或缩短 `--max-model-len` —— 多数人真正需要的是最后一个,因为 128K 的窗口会为一个根本没人发送的上下文预留缓存。启动时(而不是压力下)就显存不足:`--gpu-memory-utilization` 是相对整张卡的比例,所以任何别的东西占用的显存都会从 vLLM 的份额里扣。启动要好几分钟:那是编译和 CUDA graph 捕获;`--enforce-eager` 会跳过这两步,代价是稳态解码速度变慢 —— 这在调试迭代时是划算的,在生产里不是。

常见问题

现在启动 vLLM 服务的命令是什么?

是 `vllm serve <模型仓库>`。大多数教程里仍在用的 `python -m vllm.entrypoints.openai.api_server` 已不再是官方文档的入口形式。安装时先建虚拟环境(`uv venv --python 3.12 --seed` 后激活),再运行 `uv pip install vllm --torch-backend=auto`,uv 会根据你已安装的 CUDA 驱动选择匹配的 torch 构建。

vLLM 只能在 NVIDIA 上跑吗?

不是 —— 这是一个常见但错误的说法。vLLM 提供官方 ROCm wheel(在虚拟环境里:`uv pip install vllm --extra-index-url https://wheels.vllm.ai/rocm/`)和 ROCm Docker 镜像,另外还有 Intel XPU 与 TPU 后端。CUDA 是走得最熟的路,不是唯一的路。

vLLM 为什么在我还没发请求时就占了那么多显存?

这是刻意设计。它会预先分配 KV 缓存 —— `--gpu-memory-utilization` 就是它可以占用整张卡的比例 —— 这样批处理过程中就不必再临时分配。所以即使每个请求都只有 2K 长,设成 128K 的 `--max-model-len` 也会一直占着内存;这也是为什么遇到抢占警告时,第一个该改的通常就是把它调小。

这篇指南用到了什么

格式
AWQGPTQ

接下来

看看 🟢 RTX 4090 还能跑哪些模型反向查询 —— 24GB、8192 上下文,按质量排序

本文涉及的模型

它真的跑起来了吗?

复制命令并不等于它能用,所以站内只在这里问一次。除了你的这个回答之外,不收集任何东西。

相关指南

部署指南仅供学习参考。每个模型均有独立许可协议 — 下载或部署前请阅读 Hugging Face 官方模型卡。