大模型推理引擎对比:vLLM、TensorRT-LLM与SGLang的性能基准分析 大模型推理引擎对比vLLM、TensorRT-LLM与SGLang的性能基准分析一、推理引擎的核心竞争力大模型推理的性能瓶颈不是算力而是显存带宽和KV Cache管理效率。单张A100的算力为312 TFLOPSFP16但HBM带宽仅为2TB/s。对于自回归生成任务每生成一个token都需要访问整个KV Cache本质上是访存密集型memory-bound而非计算密集型compute-bound。推理引擎的价值就在于如何用更少的显存存储更多的KV Cache提高并发如何在有限的显存带宽下提高token生成速度降低延迟以及如何在并发和延迟之间找到最优平衡点。vLLM、TensorRT-LLM和SGLang分别从不同角度解决了这些问题。graph TD subgraph vLLM V1[PagedAttention] -- V2[KV Cache分页管理] V2 -- V3[显存利用率提升2-4倍] V4[Continuous Batching] -- V5[动态合并请求] V5 -- V6[吞吐量提升5-10倍] end subgraph TensorRT-LLM T1[图编译优化] -- T2[算子融合Kernel调优] T2 -- T3[NVIDIA GPU极致性能] T4[In-flight Batching] -- T5[请求级调度] T5 -- T6[延迟降低30-50%] end subgraph SGLang S1[RadixAttention] -- S2[前缀共享缓存] S2 -- S3[多轮对话场景5倍加速] S4[Structured Output] -- S5[约束解码] S5 -- S6[JSON/Regex输出保证] end style vLLM fill:#7B1FA2,color:#fff style TensorRT-LLM fill:#76B900,color:#000 style SGLang fill:#E65100,color:#fff二、PagedAttention与显存管理革命vLLM的核心贡献是PagedAttention——将操作系统中的虚拟内存分页思想引入KV Cache管理。传统的KV Cache管理方式为每个请求预分配一块连续的显存区域大小按最大序列长度预留。这种方式的显存浪费触目惊心如果最大序列长度为4096而实际只用了500超过85%的显存被浪费。PagedAttention将KV Cache切分为固定大小的pageblock每个page可以非连续地存储在显存的任意位置。请求按需分配page不再预留给最大序列长度。类比的话这就是把KV Cache从数组变成了链表——失去了随机访问的便利但获得了显存分配的灵活性。工程上的细节是PagedAttention允许不同请求之间共享同一个page——比如当多个请求共享相同的system prompt时这个prompt的KV Cache只需要存一份。在多轮对话场景中不同对话可能共享相同的上下文前缀共享机制可以进一步压缩显存。三、Continuous Batching与吞吐量优化传统推理服务的batching方式是静态的——必须等一个batch中的所有请求都完成才能开始下一批。对于生成长度差异悬殊的场景有的请求只需要20个token有的需要2000个这意味着短请求被长请求严重拖累。Continuous Batching也称In-flight Batching或Iteration-level Scheduling的核心改进是每个forward pass结束后已经完成的请求立即退出batch新请求立即加入。batch的组成在每个token生成步中动态变化。这相当于把调度粒度从请求级细化到了迭代级。vLLM和TensorRT-LLM都实现了这个机制但实现路径不同。vLLM在Python层面通过精细的异步调度实现灵活但有小量开销。TensorRT-LLM在C Runtime中实现调度更为高效但灵活性受限——它的调度器与编译后的引擎紧耦合。 Continuous Batching的核心调度逻辑示意 展示batch在每次迭代中的动态变化 class ContinuousBatchingScheduler: 请求级迭代调度器 def __init__(self, max_batch_size: int, max_tokens_per_iter: int): self.max_batch_size max_batch_size self.max_tokens_per_iter max_tokens_per_iter self.running: List[Request] [] self.waiting: Deque[Request] deque() def schedule(self) - List[Request]: 每步迭代调用返回本步参与forward的请求 scheduled [] token_count 0 # 第一步已完成请求退出 newly_finished [r for r in self.running if r.is_finished()] for req in newly_finished: self.running.remove(req) # 释放占用的KV Cache block req.release_kv_cache_blocks() # 第二步从等待队列补充新请求 while (len(scheduled) self.max_batch_size and token_count self.max_tokens_per_iter and self.waiting): next_req self.waiting.popleft() if next_req.can_allocate_kv_cache(): scheduled.append(next_req) self.running.append(next_req) token_count 1 # 每请求每步生成1个token else: # KV Cache不足请求放回等待队列头部 self.waiting.appendleft(next_req) break # 不再尝试因为后续请求也可能内存不足 # 第三步已有运行中的请求继续参与 for req in self.running: if req not in scheduled: if token_count self.max_tokens_per_iter: scheduled.append(req) token_count 1 return scheduled def step(self, logits: torch.Tensor, scheduled: List[Request]): 处理一个forward pass的输出 for i, req in enumerate(scheduled): next_token self.sample(logits[i]) req.append_token(next_token) if next_token req.eos_token_id or req.reached_max_length(): req.mark_finished()四、三维度基准测试对比评价推理引擎性能需要从三个维度看吞吐量Throughputtokens/s、首Token延迟TTFTTime To First Token和每Token生成时间TPOTTime Per Output Token。吞吐量维度在A100-80GB上使用LLaMA-2-70B模型、QPS32的并发场景下vLLM v0.5.0的吞吐量约为2800 tokens/sTensorRT-LLM约为3500 tokens/s高出约25%SGLang约为3100 tokens/s。TensorRT-LLM的领先优势来自NVIDIA原生的Kernel优化和图级编译但这种优势在非NVIDIA GPU上无法复制。TTFT维度关键影响因子是prompt的prefill阶段效率。对于1024 token的promptvLLM的P50 TTFT约为180msTensorRT-LLM约为150msSGLang在RadixAttention命中前缀缓存时可以达到惊人的45ms。TPOT维度各引擎差距较小。在batch size16条件下三者的P50 TPOT都在18-22ms范围。TPOT主要受限于显存带宽引擎层面的优化空间有限。SGLang的差异化优势在于RadixAttention的前缀共享。在多轮对话每轮共享system prompt和历史对话和Few-shot prompting场景中命中前缀缓存后TTFT可以降低5-10倍。如果你的业务场景大量涉及共享前缀如客服对话、RAG应用SGLang可能是更有性价比的选择。五、总结推理引擎的选择不是一个技术问题而是一个场景适配问题。如果使用NVIDIA GPU且需要极致的单卡性能TensorRT-LLM是首选——但需要接受它的部署复杂度和厂商锁定。如果需要快速部署和良好的生态支持vLLM是当前最成熟的选择。如果业务中大量存在共享前缀场景多轮对话、RAGSGLang的RadixAttention可能带来数量级的TTFT改善。更务实的选择是多引擎共存。不同模型、不同场景可以使用不同的推理引擎——vLLM用于通用推理服务TensorRT-LLM用于性能敏感的热点模型SGLang用于对话类应用。统一的上层路由多引擎后端在成本和性能上都比All-in-one方案更有竞争力。