在真实GPU主机上对SGLang和vLLM进行推理性能基准测试,并详细记录两者在Ubuntu 24.04上的安装失败踩坑经验,特别警告0.9显存陷阱导致的OOM问题。
两个开源引擎目前主导着自托管 LLM 推理领域:vLLM 和 SGLang。两者承诺完全相同的事情——给它们一个 Hugging Face safetensors 模型,它们就会启动一个超快的、OpenAI 兼容的 API 端点。
然而,比较 SGLang 与 vLLM 的标准基准测试存在一个显而易见的问题:业余爱好者在一块租来的消费级 GPU(如 RTX 4090)上对这些企业级引擎进行基准测试。要理解真实的 TTFT(Time To First Token,首 token 到达时间)和 TPOT(Time Per Output Token,每输出 token 耗时)指标,你必须分析这些引擎如何在裸机 GPU 托管架构上编排内存和并发。
在深入性能数据之前,你必须解决这两个框架在 Ubuntu 24.04 上都会遇到的灾难性安装失败问题。
⚠️ 关键警告:0.9 VRAM 死亡陷阱 大多数官方文档会告诉你设置 --gpu-memory-utilization 0.9(vLLM)或 --mem-fraction-static 0.9(SGLang)。如果你跑的是 80GB H100,这会分配 72GB。在 CUDA Graph 编译期间,引擎需要的临时系统 RAM 与 GPU 分配量成正比。这会立即耗尽宿主机的 RAM 并触发 OS 级别的 OOM(Out-Of-Memory)杀死进程。务必将此参数缩放到 0.8 或 0.85。
💡 SRE 隐藏宝藏:ninja-build 与 PyTorch 地狱 SGLang 利用 FlashInfer 在首次启动时编译高度优化的 CUDA 内核。如果你的 Linux 服务器缺少 ninja-build 包,服务器会立即崩溃并抛出 FileNotFoundError。此外,标准 pip 安装经常引发 PyTorch 版本冲突。通过预装 ninja 并直接从其发布索引根据你的 CUDA 版本获取最新的 FlashInfer wheel 来绕过这个依赖地狱。
# 1. 安装关键构建工具以防止 FlashInfer 编译崩溃
sudo apt update && sudo apt install -y python3-venv python3-pip git ninja-build build-essential
# 2. 创建隔离环境以防止 Python 全局污染
python3 -m venv /opt/llm_engine
source /opt/llm_engine/bin/activate
# 3. 安全安装 SGLang,绕过依赖地狱
pip install --upgrade pip
pip install "sglang[all]"
pip install flashinfer -i https://flashinfer.ai/whl/cu124/torch2.4/
# 4. 安全安装 vLLM
pip install vllm
在比较 SGLang 与 vLLM 时,你必须理解它们的架构哲学。vLLM 使用 PagedAttention,它将 KV Cache 当作 OS 虚拟内存来处理以消除碎片化。SGLang 使用 RadixAttention,它将 KV cache 当作压缩树结构来处理以最大化前缀共享。
纯批处理吞吐量(vLLM 胜出):如果你在处理 10,000 个完全独立的 prompt(无共享上下文),vLLM 高度优化的 C++ PagedAttention 队列可以完美处理连续批处理。
多轮对话与 Agents(SGLang 碾压):虽然 vLLM 提供了 --enable-prefix-caching 标志,但其块级存储在处理复杂对话分支时力不从心。在 agentic 工作流中,多个用户共享完全相同的 System Prompt。SGLang 通过 Radix 树及其现代基于 Rust 的路由器精确计算一次,交付快 5 倍的 TTFT 并节省高达 80% 的 VRAM。
工程师犯的最危险的错误是将 GitHub 文档中的默认启动命令直接复制到生产服务器上。
🚨 关键安全警报:未认证暴露 运行 vllm serve --host 0.0.0.0 或 sglang.launch_server --host 0.0.0.0 会将你的 LLM 引擎直接绑定到公共互联网。这些框架没有内置的 API 密钥认证或速率限制。攻击者会扫描你的 IP,窃取你的 GPU 计算资源,并执行恶意的 Prompt Injection 来劫持你的 agents。永远不要在没有反向代理的情况下绑定到 0.0.0.0!
始终将引擎严格绑定到 127.0.0.1(localhost),并在其前方放置一个安全的 Web 服务器(如 Caddy 或 Nginx):
# 安全部署:严格绑定到 localhost (127.0.0.1),内存份额为 0.8
# SGLang 示例:
python -m sglang.launch_server \
--model-path Qwen/Qwen2.5-7B-Instruct \
--host 127.0.0.1 --port 30000 \
--mem-fraction-static 0.8
# vLLM 示例:
vllm serve Qwen/Qwen2.5-7B-Instruct \
--host 127.0.0.1 --port 8000 \
--gpu-memory-utilization 0.8
为了高效地服务大型模型(如 Llama 70B 或 DeepSeek),你必须使用张量并行(--tp 2 或 --tp 8)将模型权重拆分到多个 GPU 上。
但是,如果你在多 GPU 配置下以 Docker 容器运行这些工作负载,而没有添加 --ipc=host 标志,NVIDIA 集合通信库(NCCL)将无法利用共享内存。这会导致静默的、灾难性的性能下降。
在共享云 VM 上部署 LLM 推理会引入虚拟机管理程序延迟和"嘈杂邻居" I/O 争用。要实现真正的微秒级 TTFT 并利用 vLLM 和 SGLang 所需的完整 NVLink 速度,请部署在 ServerMO USA 专属裸机服务器上。我们的基础设施完全绕过虚拟化,提供专属的 PCIe Gen5 通道和无计量网络带宽,确保你的推理引擎以绝对峰值理论吞吐量运行。
SGLang 和 vLLM 哪个更适合多轮 AI Agents?
SGLang 在多轮 AI Agents 方面明显优于 vLLM。虽然 vLLM 提供 --enable-prefix-caching,但其块级存储在处理复杂分支时力不从心。SGLang 的 Radix 树架构原生处理多轮 agents 和动态上下文,交付快 5 倍的 TTFT 并节省高达 80% 的 VRAM。
为什么 vLLM 在 80GB H100 GPU 上会以 OutOfMemoryError 崩溃?
崩溃通常是由设置 --gpu-memory-utilization 为 0.9 或 0.95 引起的。在 CUDA Graph 捕获期间,引擎分配的临时系统 RAM 与 GPU 内存成正比。这耗尽了宿主机的 RAM,触发 OS 级别的 OOM 杀死。为了稳定编译,始终将其缩放到 0.8。
如何在 Ubuntu 24.04 上修复 SGLang 中的 FlashInfer 编译错误?
SGLang 依赖 FlashInfer 在首次启动时编译 CUDA 内核。如果你缺少 ninja-build OS 包,它会抛出 FileNotFoundError。通过 sudo apt install ninja-build 安装它。此外,确保获取与你的 CUDA 环境匹配的最新版 FlashInfer wheel。
SGLang 是否像 vLLM 一样支持多 GPU 张量并行?
是的,SGLang 完全支持张量并行(例如 --tp 2 或 --tp 8)。但是,通过 Docker 运行时,必须包含 --ipc=host 标志。没有它,NVIDIA 集合通信库(NCCL)无法使用共享内存进行 GPU 间通信。
为什么我应该在裸机上而不是云 VM 上运行 LLM 推理? 云 VM 引入了虚拟机管理程序延迟和"嘈杂邻居" I/O 争用,这会严重降低 Time-Per-Output-Token(TPOT)。裸机 GPU 服务器提供不受限制的、直接访问 PCIe Gen5 通道和 NVLink 互联的能力,提取硬件理论吞吐量 100% 的性能。
👉 阅读 ServerMO 上的完整基准测试:SGLang vs vLLM: Install, Serve, and Benchmark on Bare Metal | ServerMO