推理服务器 vLLM & SGLang

vLLM / SGLang - LLM Inference Engine

vLLM 与 SGLang 是当前 LLM 高吞吐推理的两大主流开源推理框架:通过 PagedAttention KV 缓存分页管理 + 连续批处理 Continuous Batching,把单机吞吐量提升 5 到 10 倍。

详细解释

vLLM(UC Berkeley 2023 RISE Lab 出品)SGLang(LMSYS 2023 年底起出品) 是把”大模型推理部署”这件事从”用 HuggingFace transformers.pipeline,A100 每秒只能处理 3 个请求”改造成”同一张 A100 每秒处理 40+ 请求、QPS 翻 10 倍、P99 延迟反而更低”的两个开源推理引擎。二者的核心思路高度相似(因为它们的第一作者其实是同一批 LMSYS 学者的前后两篇论文):把 GPU 显存里最大的那块浪费——KV Cache 碎片——用操作系统虚拟内存的”页式管理 + 换入换出”思路给解决了。理解了 PagedAttention,就理解了 2024-2025 整个 LLM 推理部署的革命。

过去 HF 原生推理为什么慢?KV 显存碎片

假设你开一个 13B BF16 模型,KV Cache 每 token 每个 head 存 K 和 V 各一份,总大小大约是 每用户每个 token:2 bytes × 2(K+V) × 层数 × 头维度 × 头数 = 约 2KB 每 Token。也就是说用户打 1 万 token 的长文,KV Cache 就占 20MB

老式 HF pipeline 怎么管?对每一个请求(request),它会预先分配一块”最大长度 × 2KB”的连续显存块,比如设 max_context=4096,就预分配 8MB 给这个请求。问题:

  • 这个用户实际只说了 500 Token,剩下 7.5MB 就白白占着(内碎片);
  • 请求结束释放后,这块 8MB 区域与下一块可能不相邻(外碎片),新来一个更长的请求就塞不进;
  • 为了减少碎片,推理端只能让 GPU 一次处理 4-8 个请求(batch size=8),空着 60% 的显存不敢用。

vLLM / SGLang 把 KV Cache 切成了 256 或 512 Token 一页的 Block 页,用指针表(Block Table,类似 CPU 页表)来管理:

  • 请求长 2000 Token 就给它 4 页(每页 512),零散的最后一页也只占 200 Token;
  • 多请求可以共享相同的前缀页(Prefix Sharing / Prompt Sharing —— 同一个 System Prompt 被一万个用户共用时,这 2000 Token 只存一份 KV!);
  • 请求结束立即把页回收进 free pool,分给新来的请求;
  • 这样 GPU 显存利用率能从 30% 跑到 80% 甚至 90%,所以同样一张卡 QPS 翻 5 到 10 倍。

vLLM vs SGLang 2025 年选型对比

维度vLLM(v0.7.x)SGLang(v0.4.x)
核心卖点最稳最大众,兼容几乎所有开源模型架构、所有 LoRA 新架构极端场景更快(RadixAttention 前缀树共享),自带 Server 少 20% 代码,支持 Function Calling / Constrained Decoding 原生
KV 管理算法PagedAttention(分页 + 页表),共享前缀靠手动 enable enable_prefix_caching=TrueRadixAttention(前缀 KV 自动构 Radix Trie 树,完全自动共享,新用户跟历史请求只要前 500 token 一样就自动复用)
推理服务器 API原生兼容 OpenAI /chat/completions / /completions,官方 vllm serve 一条命令起服务;异步 + 多 GPU Tensor Parallel 自动python -m sglang.launch_server 同样支持;官方报在 DeepSeek-V2、Mixtral 这类 MoE 上吞吐比 vLLM 高 30%
Tool Use / Constrained Decode第三方 lm-format-enforcer / outlines 集成;2025 Q2 官方出了 guided decoding原生内置:JSON Schema / Regex / Function Calling 的参数全格式严格校验(FC 成功率 > 99%),不需要额外包
多 Lora / 多租户支持动态 LoRA 热插拔 + 多租户隔离;社区已跑 100+ LoRA 共享一张 A100原生支持 S-LoRA 多租户 + 动态加载延迟更低
生态 & 文档最成熟,几乎所有新模型架构第一时间先合 vLLM;唯元智创兼容 SDK 已跑通生态略小但 LMSYS 官方维护 + Chatbot Arena 同款后端;适合追求极致吞吐

唯元智创自己的推理后端在 2024 下半年做了 A/B:相同集群下 SGLang 跑 70B Qwen2.5 吞吐 +23%、冷启动 TTFT 更低,所以我们 70B / 110B 大卡集群现在主力用 SGLang;小模型(7B/14B)继续 vLLM,省掉集成 guided-decoding 的额外依赖。

两条工程最佳实践(上线避坑)

  1. Prefix Sharing 要主动做,别等框架自动:把 System Prompt + 知识库 RAG 固定块(比如”你是唯元智创的客服…”+公司地址电话三包政策那 1500 字)做成常量字符串,所有用户请求前面完全相同,vLLM 的 enable_prefix_caching=True 或 SGLang RadixAttention 会自动把这 1500 Token 的 KV 缓存在第一页,之后一万个用户完全不重算——首字延迟 TTFT 从 1500ms 降到 300ms,GPU 利用率还掉 30%。
  2. Continuous Batching 参数要按你的业务(长还是短)调
    • 短对话 API(意图识别 / 分类):max_num_batched_tokens=32768 调大,让 GPU 一次塞 200 个请求;
    • 长文 RAG 问答(输入动辄 16k):max_num_batched_tokens 调到 16384,max_num_seqs=64,防止塞几个长请求就 OOM;
    • 代码生成(输出 > 2048 Token 常见):开 chunked_prefill=True(vLLM),把 Prefill 阶段切分和 Decode 阶段交错,不卡后面短请求的首字延迟。

常见问题

我是小公司一张 4090 24G,选 vLLM 还是 HF TGI?
直接 vLLM。24G 消费级卡跑 Qwen2.5-7B-Instruct-GPTQ-Int4 量化,HF pipeline 大概能跑 30-50 req/h,vLLM 同模型能跑 1500+ req/h,完全是同一个数量级的差距,而部署难度只多一条命令(pip install vllm + vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ)。TGI(HuggingFace Text Generation Inference)最大的优势是和 HF Hub 自动拉模型集成,性能介于原生 HF 和 vLLM 之间,适合纯 HF 重度用户。
Tensor Parallel(TP)多少张卡合适?
按模型 BF16 原始大小和单卡显存除一下,再留 1/3 给 KV Cache。例如 70B BF16 需要 140G 权重;A100-80G × 2 卡只有 160G,KV Cache 只剩 20G 不够塞用户,所以 TP=2 会经常 OOM;TP=4(320G 总显存,KV 能占 180G)才稳。简单经验表:7B/14B → TP=1 单卡;32B/40B → TP=2;70B/72B → TP=4;110B/405B → TP=8 起步。注意 TP 越大卡间通信越多,单个请求的延迟反而越高(因为每步都要 AllReduce),所以如果你的业务是并发 10 左右、更在意延迟,宁可拿 4 张卡做 4 份 TP=1 的副本负载均衡,比一份 TP=4 强得多。
我能把 vLLM 推理结果从”OpenAI 兼容端点”直接喂给 SDK 用吗?
100% 可以,这也是 vLLM 最大的落地便利。vLLM serve 一启动默认就在 http://localhost:8000/v1/ 挂了和 OpenAI 完全一样的 /chat/completions/completions/embeddings/models 四个端点,支持 stream=true、tools/tool_choice、response_format 等所有主流字段。你原来写的 client = OpenAI(api_key="x", base_url="https://api.weimeta.cn/v1") 只要把 base_url 改成本地 vLLM 的,代码一行不用换就能跑(模型名换成你起服务时传的那个)。唯元智创 本身的 SDK 也是这么设计的,所以用户本地开发用 vLLM,生产切换成我们云端,迁移零成本。