起因
公司不想全部 LLM 调用都走 OpenAI / Anthropic API:
- 成本:长上下文 + 高 QPS → API 月几万刀
- 数据敏感:医疗 / 金融数据不送 cloud
- 自由度:fine-tune 自己 model
开源 LLM(Llama 3 / Qwen 2 / DeepSeek 等)质量足够替代 GPT-4 一些场景。
推理框架选 vLLM(Berkeley 出,paged attention,事实标准)。
装
pip install vllm
需要 NVIDIA GPU + CUDA。RTX 4090 / A100 / H100 / L40。
跑
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-8B-Instruct \
--port 8000
启动后兼容 OpenAI API 格式:
from openai import OpenAI
client = OpenAI(base_url='http://localhost:8000/v1', api_key='x')
res = client.chat.completions.create(
model='meta-llama/Meta-Llama-3-8B-Instruct',
messages=[{'role': 'user', 'content': '你好'}],
)
print(res.choices[0].message.content)
现有 OpenAI client 一行改 base_url 就能换成自己的 vLLM。
性能 vs HF transformers
跑 Llama 3 8B / 单 A100:
| 推理速度 | |
|---|---|
| HuggingFace transformers | 30 tok/s |
| vLLM | 800 tok/s(continuous batching) |
| TGI (huggingface) | 600 tok/s |
vLLM 的 paged-attention + continuous batching 让 GPU 利用率拉满 →
20x HF transformers。
跑大 model
70B 模型需 80GB+ VRAM。单 A100 80GB 跑 fp16 紧。
量化 + tensor parallel:
# 4-bit AWQ 量化 → 40GB 装得下 single A100
python -m vllm.entrypoints.openai.api_server \
--model TheBloke/Llama-3-70B-Instruct-AWQ \
--quantization awq
# 多 GPU tensor parallel
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-70B-Instruct \
--tensor-parallel-size 4
4 张 A100 跑 70B fp16 → 充足空间 + 速度更快。
paged attention 是什么
LLM 推理时每个 sequence 有 KV cache(每 token 的 attention key/value
存住)。
传统:每 sequence 预留最大 length 的 contiguous block → 浪费(多数
sequence 短)。
paged:把 KV cache 切成固定大小 page(类似 OS virtual memory)→
按需分配 / 共享相同 prefix。
效果:
- 内存利用率 90%+ vs 传统 30-50%
- 同 GPU 能跑更多 concurrent request
- prefix caching:相同 system prompt 的多个请求共享 prefix cache
continuous batching
老办法 static batching:等够 N 个 request → 一起跑 → 等最慢的 → 返回。
有 request 早完成也要等。
continuous batching:每生成 1 token 就检查能不能塞新 request。
不浪费 GPU cycle。
Time GPU
0 [A:gen, B:gen, C:gen, D:gen] # A B C D 同 batch
1 [A:gen, B:gen, C:gen, D:gen, E:start] # E 加入
2 [A:done, B:gen, C:gen, D:gen, E:gen] # A 完成腾出 slot
3 [F:start, B:gen, C:gen, D:gen, E:gen] # F 加入
吞吐量是传统 batching 2-5x。
prefix caching
system prompt 经常一样:
You are a helpful assistant. Today is 2026-05-25. Answer concisely.
[user message: ...]
vLLM 0.4+ 默认开 prefix cache:相同 prefix 的 KV cache 共享 → system
prompt 不重新算 → 加速。
特别适合 chatbot / agent 多 turn 对话。
structured output
GPT-4 / Claude 都支持 JSON mode / function calling。vLLM 0.4+ 也有:
res = client.chat.completions.create(
model=...,
messages=[...],
extra_body={
'guided_json': {
'type': 'object',
'properties': {
'name': {'type': 'string'},
'age': {'type': 'integer'},
},
'required': ['name', 'age'],
},
},
)
底层用 outlines / xgrammar 强制 token 选择符合 schema → 100% 合规 JSON。
LoRA 多租户
部署一个 base model + 多个 LoRA fine-tune 一起 serve:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-8B \
--enable-lora \
--lora-modules sql=./loras/sql-lora medical=./loras/medical-lora
client.chat.completions.create(model='sql', ...)
client.chat.completions.create(model='medical', ...)
多个特化 model 共享同 base → 显存省 + 切换零开销。
监控
vLLM 暴露 Prometheus metrics:
--enable-metrics
# /metrics endpoint
关键指标:
vllm:num_requests_runningvllm:gpu_cache_usage_percvllm:time_to_first_token_secondsvllm:e2e_request_latency_seconds
Grafana dashboard 看吞吐 / latency / cache 利用。
与替代方案对比
| vLLM | TGI | llama.cpp | ollama | |
|---|---|---|---|---|
| 目标 | 高吞吐 GPU server | 同 | CPU/GPU 单机 | 单用户简单 |
| 性能 | 最高 | 中高 | 中(CPU 优秀) | 中 |
| API | OpenAI-compat | 自家 + OAI | 自家 + OAI | 自家 |
| 量化 | AWQ / GPTQ / FP8 | 同 | GGUF | GGUF |
| 适合 | 生产 server | 生产 server | 笔记本 | 个人 |
生产用 vLLM。个人 / 笔记本用 ollama。
实战 cost 对比
跑 Llama 3 70B 处理 100M tokens/月:
| 方案 | 月成本 |
|---|---|
| OpenAI GPT-4 API | ~$8000 |
| Anthropic Claude Sonnet | ~$6000 |
| Together / Fireworks API(70B) | ~$900 |
| 自托管 vLLM + 2× A100 cloud | ~$2500(GPU 租金) |
| 自托管 + own H100 | ~$0(一次性买卡) |
自托管 break-even 大约 200M tokens/月(vs cloud API)。
量大 + 控制需求 → 自托管。量小 → API。
容器化部署
FROM vllm/vllm-openai:latest
CMD ["--model", "meta-llama/Meta-Llama-3-8B-Instruct", "--port", "8000"]
# k8s deployment
resources:
limits:
nvidia.com/gpu: 1
prod 跑 NVIDIA GPU operator 配 GPU node + vLLM container。
踩过的坑
-
OOM:模型 + KV cache 超 VRAM → OOM。
--gpu-memory-utilization 0.9
留 buffer;或者降--max-model-len。 -
量化精度损失:AWQ 4-bit 比 fp16 任务上有 1-3% 精度损失。
测过再上。 -
prefix cache 没用上:system prompt 略有不同(如时间戳) →
prefix 不匹配。把动态部分放后面。 -
OpenAI client 兼容性:某些参数(如
tools)vLLM 还不支持
→ 用基础 chat completions。 -
生产 reload model:vLLM 不支持热重载。换 model 必须重启容器。
blue-green deploy。
登录后参与评论。