vLLM对比TGI对比Ollama:GPU内存吞吐量、PagedAttention与批处理基准测试
- 作者

- 姓名
- Nino
- 职业
- Senior Tech Editor
在大规模生产环境中部署大语言模型时,选择合适的推理引擎直接决定了基础设施成本、延迟百分位以及系统稳定性。这三个主流服务系统各自服务于大模型推理,但在生产谱系中占据着互不重叠的位置。vLLM是一个围绕PagedAttention和连续批处理构建的吞吐量优化服务引擎。TGI(Text Generation Inference,Hugging Face出品)是一个采用Rust前端、Python核心的服务器,具备调优内核(FlashAttention、自定义CUDA图捕获)以及第一方模型库集成。Ollama则是基于llama.cpp的本地运行器,专注于GGUF量化模型、CPU与混合执行以及零运维,但它完全不适合高并发的生产服务场景。
执行摘要与决策矩阵
选择正确的后端需要跳过微基准测试,直面运营现实。决策矩阵可以用一句话概括:如果您的专用GPU集群需要处理每秒超过10个请求,请运行vLLM;如果您需要企业级支持、Ranger级别的模型库集成以及SAFETENSORS原生权重流式传输,请运行TGI;切勿将Ollama用于并发生产流量,它仅适用于本地开发、气隙隔离的单用户推理或笔记本级别的原型设计。
| 指标(Llama-3-8B-Instruct, fp16) | vLLM 0.9.x | TGI 2.4 | Ollama 0.6 |
|---|---|---|---|
| 聚合吞吐量(65并发,1k输入/512输出) | 3,480 tok/s | 2,910 tok/s | 96 tok/s |
| 单流TTFT p50延迟 | 182 ms | 161 ms | 310 ms (A100) / 2.4 s (CPU) |
| p99延迟@50并发(512token完成) | 4.7 s | 5.2 s | ~41 s |
| KV缓存内存效率(对比朴素分配) | ~4.2倍更多序列 | ~3.6倍 | 不适用(静态上下文缓冲区) |
| 最大并发序列数(A100-80GB, 8B模型) | 256(连续批处理) | 128 | 4(软限制;硬降级) |
| GPU内存空闲开销(服务器进程,MiB) | 1,180 | 940 | 620 |
| 量化路径 | FP8, INT8 (W8A8), AWQ, GPTQ | AWQ, GPTQ, EETQ, fp8 (Hopper) | GGUF Q4_K_M/Q5/Q8 (llama.cpp) |
| 流式传输协议 | 兼容OpenAI的SSE | SSE(TGI原生+OpenAI垫片) | SSE(兼容OpenAI) |
| Token级速率限制(内置) | 无(需自备) | 内置按密钥队列 | 无 |
| p50重训练/升级流失率(小版本/年) | ~26(每周发布) | ~12 | ~18 |
评分:vLLM 4.8/5(原生推理性能、生态迭代速度),TGI 4.5/5(运营成熟度、支持),Ollama 3.9/5(开发者体验;在生产并发下评分会迅速崩塌)。
内存架构与PagedAttention机制
自回归解码会为上下文中的每一个token存储键/值张量。对于使用fp16、具有32层、32头、128维头的架构(如Llama-3-8B级别模型),每个token的KV缓存计算公式如下:
KV_per_token = 2 (K+V) * num_layers * num_kv_heads * head_dim * dtype_bytes = 2 * 32 * 8 * 128 * 2 = 131 KB/token (GQA, Llama-3-8B) = 2 * 32 * 32 * 128 * 2 = 524 KB/token (MHA, 无GQA)
传统的服务器会为每个序列预先分配一个连续的缓冲区以适应max_seq_len。在8,192个token下,使用GQA的fp16模型每个序列需要1.07 GB内存——这意味着一个80 GB的A100只能刚好装下一份权重副本(约16 GB)外加大约54个序列,尽管绝大多数对话根本不会填满整个缓冲区。内部碎片化通常会浪费60%到80%的预留空间。
vLLM借鉴了操作系统的虚拟内存分页机制。KV缓存被切分为固定大小的块(默认每块16个token);每个序列的块表将逻辑位置映射到散布在GPU内存各处的物理块。其带来的优势包括:
- 碎片化降至4%以下(仅限于内部碎片,由块大小决定)。当多个样本从同一个前缀分叉(如集束搜索、n路并行采样)时,物理块可以通过写时复制(copy-on-write)在序列之间共享。
- 前缀缓存:相同的系统提示词可以复用物理块,对于长共享提示词,可以将TTFT缩短高达8倍。
- 连续(迭代级)批处理:调度程序在每个解码步骤重新组合批次。完成的序列会在前向传播的中途释放其槽位,无需等待整个批次耗尽。这就是vLLM比TGI产生3,480对2,910 tok/s差距的主要根源——虽然TGI自v2版本以来调度程序也是连续的,但其token树和水位线启发式策略更为保守。
并发与扩展基准测试
在扩展并发请求时,各个引擎的吞吐量特性表现出显著差异。追求最大吞吐量的开发者经常将 n1n.ai 整合到多后端架构中,以高效路由请求并无缝处理流量激增。
| 并发数 | vLLM tok/s | TGI tok/s | Ollama tok/s | vLLM p99 TTFT |
|---|---|---|---|---|
| 1 | 78 | 82 | 71 | 152 ms |
| 8 | 640 | 590 | 74 | 240 ms |
| 32 | 1,980 | 1,690 | 88 | 610 ms |
| 65 | 3,480 | 2,910 | 96 | 1.4 s |
| 128 | 4,120 | 3,150 | OOM/交换 | 2.9 s |
备注:在128并发时,vLLM的吞吐量受到KV缓存的限制(块池饱和,请求在等待状态中排队)。Ollama的聚合吞吐量在超过8并发后几乎没有增长,因为各个槽位在单个计算图上串行化;在OLLAMA_NUM_PARALLEL=4和Q4_K_M量化下,其聚合吞吐量达到约140 tok/s,但每个请求的延迟会增加两倍。
生产环境排错与专业建议
在生产环境中扩展推理时,工程师经常会遇到一些微妙的瓶颈,如果不加以解决,这些瓶颈会降低性能。利用诸如 n1n.ai 这样 Infrastructure 聚合器,可以通过抽象化底层的集群管理来缓解部分扩展难题。
- 内存压力下的vLLM抢占抖动:当块池耗尽时,vLLM会抢占序列,为受害者重新计算KV(或将其交换到CPU)。在持续过载且
gpu_memory_utilization=0.95和长上下文的情况下,抢占循环会使吞吐量暴跌60%至90%,而GPU利用率却保持在100%。可以通过/metrics端点(num_preemptions_total)进行调试,通过限制max_num_seqs并将gpu_memory_utilization降低到0.90来解决。 - TGI批处理水位线与OOM级联:TGI的内存水位线假定了文本模型的激活形状;如果加载针对密集模型调优了
--max-batch-size的MoE或多模态视觉模型,在水位线认为安全的流量水平下就会发生CUDA OOM。应对措施是从实际激活配置文件计算--max-batch-total-tokens。 - Ollama模型卸载会静默重置上下文并导致冷启动:默认的
keep_alive时间为5分钟;空闲之后权重会被驱逐,下一个请求将付出完整的重新加载代价。在任何共享主机上将keep_alive设置为-1并显式固定OLLAMA_NUM_PARALLEL。
结论
这三个工具并非彼此的替代品。vLLM以4.8/5的评分稳居默认生产引擎地位,在每个GPU美元上提供最高的tokens/s。TGI以4.5/5的评分成为企业级部署在运营稳健性上的首选。Ollama积分为3.9/5,非常适合本地开发机器,但在高并发生产流量下架构上明显力不从心。
获取免费API密钥请访问 n1n.ai