vLLM 的核心卖点是 PagedAttention,这点没错。但坦白说,PagedAttention 只解决了一个问题:显存管理。而一个真正能用的 LLM 推理服务,要操心的远不止这些——模型权重怎么分片、怎么量化、Token 化、LoRA 热切换、多模态输入、水印生成、甚至语法约束输出……这些零零碎碎的需求,才是线上服务的常态。

今天聊的 TGI(Text Generation Inference),是 HuggingFace 的官方推理服务。它跟 vLLM 目标一致,都是为了高效推理,但切入点完全不同。vLLM 是从 KV Cache 管理这个点开始突破,而 TGI 从一开始就盯着模型生态的兼容性。它的野心很明确:要把 HuggingFace Hub 上那几十万个模型都伺候好,而不只是伺候 Llama 和 Mistral 这两位“明星”。
TGI 的架构:不止一个 Scheduler
从架构上看,TGI 也有一套清晰的流水线。从 HTTP/gRPC API 进来,先经过一个 Router 负责把请求路由到对应的模型,支持同时服务多个模型。然后进入 Scheduler,这个调度器跟 vLLM 的类似,但额外支持了 Chunked Prefill。最后是 Model Runner,负责实际执行推理,支持 PyTorch、TensorRT、FlashInfer 等多种后端。再往下,就是 KV Cache、Weight Loader、Tokenizer 这些基础组件了。
TGI vs vLLM:五个关键差异
1. Chunked Prefill(分块预填充)
第 1 篇里提过,vLLM 最初是没有 Chunked Prefill 的,但 TGI 有。这个差异在特定场景下影响巨大。
没有 Chunked Prefill 时,情况是这样的:如果来了一个 Prompt 长达 10K Token,系统会先花 200ms 做 Prefill,这段时间 GPU 满负荷运转,但其他请求的 Decode 步骤只能干等着。这就会导致整体延迟的剧烈抖动。
有了 Chunked Prefill,处理方式就灵活多了。系统可以把一个 10K Token 的 Prompt 切成 5 个 2K 的块,每处理一个块,就穿插着执行一轮所有请求的 Decode 步骤。这样,Prefill 和 Decode 交替进行,任何一个请求的 Decode 步骤都不会被长时间阻塞。
对于超长 Prompt 场景(比如 RAG 里把多篇文档塞进上下文),Chunked Prefill 就变得至关重要——它直接保证了服务的 P99 延迟不会因为某个大 Prompt 而失控。
2. 量化方案:GPT-Q 和 AWQ 是一等公民
在量化这件事上,TGI 对 HuggingFace 上最广泛使用的量化格式做了更深入的优化。支持的量化方案包括:AWQ、GPT-Q、BitsAndBytes、EETQ 和 FP8。
值得重点说的是,TGI 对 AWQ 的路由专门做了 CUDA Kernel 优化,根据社区的测试数据,量化模型的推理延迟通常比 vLLM 低 10-15%。原因很简单,HuggingFace Hub 上大量模型都是以 AWQ 格式发布的,TGI 对这些模型的“即开即用”体验,可以说是碾压 vLLM 的。
3. LoRA 热切换:多租户场景的核心能力
有些场景下,同一个 Base Model 需要服务不同的租户——比如电商客服、金融客服、技术支持,每个都需要不同的微调。如果每次都要重新加载模型,那效率就太低了。
TGI 支持在运行时直接加载或卸载 LoRA Adapter,无需重启服务。启动时加几个参数就行:--enable-lora 开启功能,--max-loras 10 控制同时加载的 adapter 数量,--max-cpu-loras 50 则可以在 CPU 内存里缓存更多待命的 adapter。
在实际调用时,不同请求在 API 里指定 lora_id,TGI 就会动态切换 Adapter 权重。每次切换只涉及几 MB 的 LoRA 权重矩阵,完全不需要动那几十 GB 的 Base Model。vLLM 新版本也开始支持这个功能,但 TGI 的实现更早,也更加成熟。
4. 语法约束输出(Structured Generation / Guided Decoding)
有些场景需要模型输出严格格式化的 JSON,比如必须包含 sentiment、reason、confidence 这几个字段,且每个字段都有明确的类型和取值范围。普通的生成方式,全靠模型“猜”,能不能输出正确格式全凭运气。
TGI 的做法是在 Decode 阶段实时约束 Token 的候选集——在 Softmax 之后、采样之前,把不符合 Grammar 的 Token 概率全部置零。这样,每个位置只会从符合语法的 Token 里进行抽样,最终输出自然就是严格合规的 JSON 了。它支持 JSON Schema、Regex、甚至 Context-Free Grammar 等多种约束方式。
5. 水印生成(Watermarking)
TGI 还内置了 Watermark 功能,可以在生成的文本中嵌入可检测的数字签名。原理是在 Token 采样阶段,对候选 Token 做“绿色”和“红色”的二分法打标,采样时偏好“绿色”的 Token。后续可以用统计方法检测一段文本是否由该 TGI 实例生成。这是 HuggingFace 独有的功能,vLLM 并没有。
启动方式
推荐用 Docker 方式启动,命令非常直观,同时兼容 OpenAI Chat API,调用方式跟 vLLM 一致,迁移成本很低。
什么时候选 TGI
| 场景 | TGI 适合? |
|---|---|
| 使用 HuggingFace Hub 模型 | 首选——无缝集成 |
| 超长 Prompt(>10K) | Chunked Prefill 降低 P99 延迟 |
| 多租户 LoRA 服务 | 最佳选择,LoRA 热切换成熟 |
| 需要 JSON/Regex 约束输出 | 原生支持 Grammar 约束 |
| 多模态模型(LLaVA, Idefics3) | 原生支持图像输入 |
| 单模型高并发推理 | 跟 vLLM 性能相当,选部署习惯 |
| 不想用 Docker | vLLM 的 Python 直接启动更简单 |
一句话总结
从性能上看,TGI 和 vLLM 其实不相上下,因为两者的核心优化思路——PagedAttention 加上 Continuous Batching——是一致的。TGI 真正的差异化优势在于“模型生态”:对 AWQ 等量化方案的深度优化,成熟的多租户 LoRA 热切换,多模态输入,结构化的输出约束,以及内置的水印功能。这些要么是 vLLM 没有的,要么是做得不如 TGI 深入的地方。所以,如果你深度依赖 HuggingFace 生态,TGI 会是一个非常自然的选择。
