
引言:大模型推理为何成为部署瓶颈
2024年以来,大语言模型(LLM)的能力持续攀升,从GPT-4、Claude 3到Llama 3、Qwen2,模型参数量动辄数百亿,推理成本居高不下。当企业从”调API体验”转向”私有化生产部署”时,推理引擎的选择直接决定了吞吐量、延迟和硬件利用率——这三大指标又反过来决定了项目的ROI。
目前在开源社区和工业界,vLLM、TensorRT-LLM(NVIDIA)和SGLang(LMSys / UC Berkeley)是三款最受关注的推理引擎。它们各自采用了不同的优化路径:vLLM 以 PagedAttention 闻名,TensorRT-LLM 依赖 NVIDIA 的极致编译优化,SGLang 则在请求调度和执行层面创新。本文将从架构原理、部署体验、性能对比、生产化适配四个维度,对三款引擎做一次深度横向评测与实战讲解。
vLLM:PagedAttention 与高吞吐利器
核心架构解析
vLLM 由 UC Berkeley 的 SkyLab 团队开发,其最大的技术贡献是 PagedAttention 机制。传统推理引擎中,KV-Cache 是连续分配的,导致严重的内存碎片化——GPU显存可能剩余总量不少,但碎片太多,无法容纳下一个请求的KV-Cache块。PagedAttention 借鉴了操作系统虚拟内存的”分页”思想,将KV-Cache划分为固定大小的Block(默认16个token),通过Block Table实现非连续物理内存的逻辑连续映射。
这一设计的直接收益有两点:显存利用率从40%-60%提升至95%以上;支持Copy-on-Write机制,在Parallel Sampling等场景下共享KV-Cache块,进一步节省显存。
部署实战:Docker + OpenAI兼容API
# 拉取vLLM官方镜像(推荐使用最新版本)
docker pull vllm/vllm-openai:latest
# 启动服务,以Qwen2-72B-Instruct为例
docker run --gpus all \
-p 8000:8000 \
-v /data/models:/models \
vllm/vllm-openai:latest \
--model /models/Qwen2-72B-Instruct \
--tensor-parallel-size 4 \
--max-model-len 32768 \
--gpu-memory-utilization 0.92 \
--dtype bfloat16 \
--enforce-eager
参数说明:--tensor-parallel-size 4 表示张量并行度=4(适用于多卡场景);--gpu-memory-utilization 0.92 控制KV-Cache预分配的显存比例;--enforce-eager 在部分模型上绕过CUDA Graph以降低首次Token延迟。
vLLM 提供了完全兼容 OpenAI Chat Completion 和 Completion 的 API,客户端可使用 openai 库直接调用:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed"
)
response = client.chat.completions.create(
model="/models/Qwen2-72B-Instruct",
messages=[{"role": "user", "content": "请用Python实现一个LRU缓存"}],
max_tokens=2048,
temperature=0.7
)
print(response.choices[0].message.content)
vLLM的优势与局限
| 优势 | 局限 |
|---|---|
| 部署最简单,Docker一键启动 | 对MoE类模型优化不如SGLang |
| 社区活跃,模型兼容性最好 | 首次Token延迟高于TensorRT-LLM |
| 支持Prefix Caching、Speculative Decoding | CUDA Graph稳定性偶有问题 |
| OpenAI兼容API生态成熟 | 长序列场景显存调度开销 |
TensorRT-LLM:NVIDIA的极致编译优化
核心架构解析
TensorRT-LLM 是 NVIDIA 官方出品的推理框架,本质上是 TensorRT 在大模型场景的扩展。它的核心理念是“编译时优化 + 运行时plugin”:
- 图优化:将Transformer计算图做算子融合(Fuse LayerNorm + ResidualAdd、Fuse QKV投影等),减少Kernel Launch开销。
- 量化支持:原生支持 FP16、BF16、INT8、INT4、FP8 量化(H100),且提供 Weight-Only、SmoothQuant、AWQ、GPTQ 等量化格式。
- In-Flight Batching:相当于 vLLM 的 Continuous Batching,但更早实现且在底层做了更多CUDA Stream层面的编排。
- Page Attention:vLLM 的 PagedAttention 启发下,TensorRT-LLM 0.7+ 也引入了类似机制。
部署实战:模型编译 + Triton推理服务器
TensorRT-LLM 的部署路径分两步:先编译模型为 TRT-LLM 引擎文件,再通过 Triton Inference Server 提供服务。
# 第一步:构建Docker镜像(推荐使用NVIDIA官方镜像)
docker pull nvidia/cuda:12.5.0-devel-ubuntu22.04
# 克隆并安装
git clone https://github.com/NVIDIA/TensorRT-LLM.git
cd TensorRT-LLM
make -C docker build
# 第二步:编译模型(以Llama-3-70B为例)
python3 examples/llama/build.py \
--model_dir /models/Llama-3-70B-Instruct \
--dtype bfloat16 \
--use_gpt_attention_plugin bfloat16 \
--use_gemm_plugin bfloat16 \
--max_batch_size 64 \
--max_input_len 8192 \
--max_output_len 2048 \
--output_dir /models/trt-engines/llama3-70b \
--world_size 8 \
--multi_query_mode
编译完成后,通过 Triton 的 Python Backend 或 C++ Runtime 部署:
# 使用Triton部署
docker run --gpus all --rm \
-p 8000:8000 -p 8001:8001 -p 8002:8002 \
-v /models:/models \
nvcr.io/nvidia/tritonserver:24.06-trtllm-python-py3 \
tritonserver --model-repository=/models/triton_model_repo
TensorRT-LLM的优势与局限
| 优势 | 局限 |
|---|---|
| 推理延迟最低(尤其首Token延迟) | 编译过程繁琐,模型变更需重新编译 |
| 量化支持最全面,FP8/KV-Cache INT8 | 仅支持NVIDIA GPU |
| 与Triton无缝集成,生产化程度高 | 社区规模不如vLLM |
| 算子融合极致,GPU利用率高 | 对HuggingFace格式模型有兼容问题 |
SGLang:RadixAttention 与结构化推理
核心架构解析
SGLang 由 UC Berkeley 的 LMSys 团队(即Chatbot Arena背后的团队)开发。它的创新点不在显存管理,而在请求级调度和结构化编程模型。其核心机制包括:
- RadixAttention:用基数树(Radix Tree)来管理KV-Cache的复用。当多个请求共享公共前缀(如System Prompt)时,RadixAttention可以自动检测并复用已有的KV-Cache块,比vLLM的Prefix Caching更高效。
- SGLang Programming Language:一个嵌入Python的DSL,允许开发者用结构化编程方式定义LLM的多轮交互逻辑、约束解码、分支等。
- Data-Aware Scheduling:调度器不仅看请求到达时间,还考虑KV-Cache的复用关系,将能共享前缀的请求调度到一起。
部署实战:快速启动与结构化编程
# 安装SGLang(支持CUDA 12.1+)
pip install "sglang[all]"
# 启动服务
python -m sglang.launch_server \
--model-path /models/Qwen2-72B-Instruct \
--tp 4 \
--host 0.0.0.0 \
--port 30000 \
--context-length 32768 \
--enable-prefix-caching
SGLang 的一大特色是结构化编程。以下是一个使用 SGLang 做 JSON 结构化输出的例子:
import sglang as sgl
@sgl.function
def extract_info(s, text):
s += "从以下文本提取信息:\n"
s += text + "\n"
s += "以JSON格式输出:\n"
s += sgl.gen("name", max_tokens=50)
s += sgl.gen("age", max_tokens=10)
s += sgl.gen("city", max_tokens=50)
# 编译并运行
func = extract_info.compile()
result = func(text="张三今年28岁,住在北京市朝阳区")
print(result["name"], result["age"], result["city"])
这种方式避免了传统Hack的方式(System Prompt要求JSON格式输出+正则解析),而是从编程层面保证输出的结构化。
SGLang的优势与局限
| 优势 | 局限 |
|---|---|
| RadixAttention在共享前缀场景极优 | 生态较新,工具链不成熟 |
| 结构化编程简化复杂Agent场景 | 部分高级功能文档不够完善 |
| 对MoE模型(DeepSeek-V2, Mixtral)支持好 | 社区规模小于vLLM |
| 支持Constrained Decoding(正则约束输出) | 仅限NVIDIA GPU(vLLM已支持AMD) |
三款引擎的性能对比
以下基于A100-80G * 8节点,测试Llama-3-70B-Instruct(BF16)各引擎的关键指标(数据来自公开评测和社区报告):
| 指标 | vLLM (0.6.0) | TensorRT-LLM (0.11.0) | SGLang (0.3.0) |
|---|---|---|---|
| 吞吐量 (Req/s) – BS=32 | 8.2 | 10.5 | 9.1 |
| 首Token延迟 (ms) – BS=1 | 185 | 112 | 168 |
| GPU显存利用率 | 94% | 88% | 92% |
| 部署复杂度 | ★☆☆☆☆ | ★★★★☆ | ★★☆☆☆ |
| 模型兼容性 | ★★★★★ | ★★★☆☆ | ★★★★☆ |
| 量化支持 | FP16/INT8/AWQ/GPTQ | FP16/BF16/INT8/INT4/FP8/AWQ | FP16/INT8/AWQ |
从数据可以看到一个清晰的画像:
- 追求极致吞吐和首Token低延迟 → 选 TensorRT-LLM,代价是部署复杂度高。
- 快速上线、模型频繁切换 → 选 vLLM,社区最活跃,踩坑资源最多。
- 共享前缀场景多(如System Prompt长、Multi-Turn对话)、需要结构化输出 → 选 SGLang。
生产级部署的实战建议
多引擎混合架构
在大规模生产环境中,实际可以采用多引擎混合架构:
┌─────────────────────────────────────┐
│ Load Balancer │
│ (Nginx / Envoy / Traefik / k8s) │
└────┬──────────┬──────────┬──────────┘
│ │ │
┌──▼──┐ ┌──▼──┐ ┌──▼──┐
│vLLM │ │TRT- │ │SGL │
│Pool │ │LLM │ │Pool │
└─────┘ └─────┘ └─────┘
- 在线推理(延迟敏感):TensorRT-LLM Pool,处理核心API请求。
- 离线批处理(吞吐优先):vLLM Pool,最大化吞吐量。
- 复杂Agent任务(结构化需求):SGLang Pool,利用结构化编程能力。
关键配置参数调优
不论使用哪款引擎,以下参数对生产性能影响巨大:
- 调度策略:高并发场景推荐
max_num_seqs适中的配置,避免单批次过大导致TTFT增长。vLLM推荐256-512,SGLang推荐128-256。 - Prefix Caching:如果固定System Prompt较长(如Agent工具说明、角色设定),务必开启Prefix Caching。vLLM 使用
--enable-prefix-caching,SGLang 默认启用 RadixAttention。 - Speculative Decoding:vLLM和TensorRT-LLM均支持推测解码,搭配一个小的Draft Model(如用68M的模型预测70B的输出)可在保持准确率的同时提升2-3倍生成速度。
- Context Length:不要盲目使用模型的最大长度。根据实际业务数据分布,设置合理的
max-model-len或max_input_len能显著减少显存浪费。 - CUDA Graph:在网络稳定的生产环境,强烈推荐开启CUDA Graph(vLLM默认启用),可将每一次推理的Kernel Launch开销从几百微秒降到接近零。但首次构建Graph时需预热,且Graph变更(如Batch Size变化)有重建代价。
监控与运维
# vLLM自带Prometheus指标
curl http://localhost:8000/metrics
# 关键指标说明
# - vllm:num_requests_running 当前正在处理的请求数
# - vllm:gpu_cache_usage 显存缓存使用率
# - vllm:avg_prompt_throughput 平均Prompt处理吞吐
# - vllm:avg_generation_throughput 平均生成吞吐
# TensorRT-LLM + Triton 可集成 Prometheus + Grafana 监控
# SGLang 也提供了OpenMetrics端点
总结与选型建议
综合来看,三款引擎各有明确的适用场景,不存在”万能最佳选择”:
| 场景 | 推荐引擎 | 理由 |
|---|---|---|
| 快速PoC / 频繁换模型 | vLLM | 部署最简单,模型兼容性最好 |
| 生产GPU集群部署 | TensorRT-LLM | 延迟最低,硬件利用率最高 |
| 多轮对话 / Agent系统 | SGLang | RadixAttention + 结构化编程 |
| MoE模型推理 | SGLang | 对MoE架构优化较好 |
| H100/FP8推理 | TensorRT-LLM | 唯一原生支持FP8量化 |
| 低预算(消费级显卡) | vLLM | 社区资源多,调优经验丰富 |
技术选型没有银弹。推荐的做法是:先以vLLM快速跑通端到端流程,确定模型和业务稳定后,根据性能瓶颈选择TensorRT-LLM或SGLang做深度优化。同时,关注三者的社区动态——vLLM正在引入更多底层优化,TensorRT-LLM在简化编译流程,SGLang在扩展模型支持。2024年下半年,三者的差距正在快速缩小,最终胜出的将是生态和社区活跃度。
如果你正在规划企业的LLM推理Infra,建议搭建一个统一的推理网关(如基于Envoy + K8s),将多引擎以Pool方式接入。这样既能享受各自引擎的独特优势,又能通过统一的API和监控层降低运维复杂度。未来随着MCP(Model Context Protocol)、OpenTelemetry等标准的普及,推理Infra的组件化程度会进一步提高,今天的选型决策应该尽量保持灵活性和扩展性。
汤不热吧