大模型实战指南(11)——推理框架选型实战:vLLM × SGLang × TensorRT-LLM 深度对比与部署指南
大模型实战指南(11)——推理框架选型实战:vLLM × SGLang × TensorRT-LLM 深度对比与部署指南
这是《大模型实战指南》系列第十一篇。前十篇我们从 Token、上下文窗口、温度采样、Embedding、Harness、微调、推理优化、RAG、Agent 一路拆到多模态,把大模型从“会打字的魔法盒子”拆成了一套可操控的工程系统。这一篇解决所有工程师都会遇到的那道坎:模型选好了、甚至微调好了,怎么把它部署成高并发、低延迟、能扛住真实流量的线上服务?
先看一个 2026 年 8 月 26 日深夜的真实场面:阿里 Qwen 团队开源了 Qwen3.8-Flash-Next(125B 总参数、仅激活 6B,Qwen4 架构预览版),几乎同一时间智谱开源了 GLM-5.3-Flash(320B-A18B 原生多模态)。模型发布本身已经够炸,但更热闹的是评论区——大家问得最多的不是“模型有多强”,而是“用什么框架能跑起来”。就在同一天,vLLM 发布 v0.28.0(584 个 commit、270 位贡献者、GitHub Star 突破 90k),三天前 SGLang 刚发布 v0.5.18(710 个 PR、212 位贡献者、Star 达 32.5k)。模型发布日,就是推理框架的“day-0 适配战”开打日。
这篇不讲虚的。三大框架的核心原理、架构差异、代码实操、选型决策树,全部拆开给你看。读完你能回答三个问题:它们各自在解决什么问题、为什么这样设计、你的场景该选哪个。

一、为什么需要推理框架:不是“能跑”就行
先搞清楚一个根本问题:为什么不能直接用 HuggingFace Transformers 跑推理?
Transformers 库的设计目标是“通用”和“易用”,不是“高性能”。当你用它跑一个 70B 模型时,它做的事情大致是:加载模型权重 → 逐个 token 前向传播 → 返回结果。看起来没毛病,但三个致命问题会让你的 GPU 利用率低到令人发指。
1.1 显存碎片:GPU 的“城中村”
大模型推理的核心数据结构是 KV Cache(键值缓存)。第七篇讲过,模型每生成一个 token,都要把前面所有 token 的 Key 和 Value 存起来,下一轮 attention 计算要用。
问题在于:你不知道用户会生成多少个 token。所以 Transformers 的做法是按最大长度(比如 4096)预分配一整块连续显存。用户可能只生成了 50 个 token,但 4046 个 token 的空间就这么浪费了。这种浪费叫“内部碎片”——分配了但没用。
更糟糕的是“外部碎片”。多个请求并发时,每个请求都要预留一大块连续显存。假设 8 张 H100、80GB 显存,一个 70B 模型权重占掉约 140GB(FP16),剩下约 500GB 给 KV Cache。按每请求预分配 4096 token 的连续空间,每个请求约需 2-4GB,理论上能容纳 125-250 路并发。但实际上呢?请求是动态到来和释放的,显存被切得七零八碎——你可能有 200GB 空闲,但最大连续空闲块只有 4GB,新请求来了分配不了。实际并发可能只有十几路。碎片率高达 40%-60%。
这就像城市里的“城中村”:明明有很多空地,但每块都太小、太分散,盖不了新楼。
1.2 批处理困境:GPU 的“空载巡航”
GPU 的吞吐量高度依赖批处理(Batching)。GPU 上有数千个并行计算单元(SM),batch 越大,越能填满这些单元。一次处理 32 个请求的效率远高于一次处理 1 个请求的 32 倍——因为 batch 小的时候,大量 SM 在空转。
但 Transformers 的批处理是静态的:你得等一批请求都到齐了再一起处理。用户请求是随机到达的,你可能等 5 秒才凑够 32 个请求,这 5 秒里 GPU 在空转。更别说有些请求生成完了、有些还在生成——传统批处理必须等最慢的那个请求完成才能接下一批,这就是“批处理冻结”(Batch Frozen)。一个生成长文的请求会把整批都拖住。
打个比方:静态批处理就像一辆大巴车,必须等满座才发车,到了终点站所有人一起下车。哪怕有人只坐一站,也得陪着你跑到终点站。GPU 大量时间在“等满”和“等完”中空转。
1.3 计算与访存的矛盾:Prefill 和 Decode 是两种完全不同的活
大模型推理分两个阶段,对硬件资源的需求完全矛盾:
- Prefill(预填充):一次性处理用户的完整输入,生成 KV Cache 和第一个输出 token。这是计算密集型——输入越长,矩阵乘法越多,GPU 算力(FLOPS)是瓶颈。一张 H100 有 989 TFLOPS(FP16),Prefill 阶段可以把它吃满。
- Decode(解码):基于已有的 KV Cache,逐个生成后续 token。每生成一个 token 只需做一次矩阵乘(规模是 hidden_size × vocab_size),但要读取全部 KV Cache(可能几十 GB)。这是访存密集型——GPU 显存带宽是瓶颈。H100 有 3.35 TB/s 带宽,Decode 阶段大部分时间在等数据从显存搬到计算单元。
一个吃算力,一个吃带宽。如果把两者混在同一组 GPU 上跑,Prefill 在狂跑算力时,Decode 的算力单元在空转;Decode 在等数据搬运时,Prefill 的算力单元也在空转。两边都吃不饱,GPU 利用率可能只有 30%-40%。
推理框架就是来解决这三个问题的。不同的框架,解题思路不同,这就是它们差异的根源。
二、vLLM:用“虚拟内存”管理显存
2.1 一句话定位
vLLM 是 UC Berkeley Sky Computing Lab 开发的高性能推理引擎,2023 年 6 月首次发布(论文发表在 SOSP 2023),核心创新是 PagedAttention——借鉴操作系统的虚拟内存分页机制管理 KV Cache。截至 2026 年 8 月,GitHub Star 90.2k,是大模型推理的事实标准。
2.2 核心原理:PagedAttention
操作系统的虚拟内存怎么管理内存?物理内存被分成固定大小的页(Page,通常 4KB),进程看到的是连续的虚拟地址,但实际映射到离散的物理页。这样既不需要预分配连续大块,也不会浪费空间。
vLLM 把这个思路搬到了 GPU 上。KV Cache 不再按最大长度预分配一整块,而是被分成固定大小的“块”(Block,默认 16 个 token 一块)。一个请求实际用了多少 token,就分配多少块,用多少给多少。关键是:这些块在物理显存上不需要连续——它们通过一张“块表”(Block Table)映射到逻辑序列。
块表的工作方式:
每个请求有一张块表,记录它的逻辑块(Block 0、Block 1、Block 2…)分别对应物理显存中的哪个块。比如一个请求用了 50 个 token,需要 4 个块(50 / 16 向上取整),块表里记着:
逻辑块 0 → 物理块 #7
逻辑块 1 → 物理块 #3
逻辑块 2 → 物理块 #12
逻辑块 3 → 物理块 #5
物理块 #7、#3、#12、#5 在显存里完全不连续,但 attention 计算时,GPU kernel 会根据块表去正确的物理位置取 KV Cache,对模型透明。这就是 PagedAttention 对 attention kernel 的核心改动——传统 attention kernel 假设 KV Cache 是连续的,PagedAttention kernel 改成按块表间接寻址。
Copy-on-Write 实现前缀共享:
块表机制还有一个杀手级应用:前缀共享。如果两个请求共享相同的前 100 个 token(比如同样的 system prompt),vLLM 可以让它们的块表前几项指向同一个物理块。这不是拷贝,而是“引用”——多个逻辑块映射到同一个物理块。
当某个请求需要修改这个块的内容时(比如 attention 计算需要写入新的 KV),才触发 Copy-on-Write:复制一份物理块,修改块表指向新块。这和操作系统 fork 进程时共享内存页、写入时才复制的机制一模一样。
| 维度 | 传统方案(Transformers) | vLLM PagedAttention |
|---|---|---|
| 分配方式 | 按最大长度预分配连续大块 | 按需分配 16-token 固定块 |
| 显存碎片 | 40%-60% 浪费(内部+外部) | <4% 浪费(仅最后一块) |
| 并发能力 | 受限于预分配总量 | 受限于实际使用量 |
| 前缀共享 | 不支持 | Copy-on-Write 块引用 |
| 请求释放 | 整块释放 | 块级别释放,立即可被新请求复用 |
效果立竿见影:同样的硬件,vLLM 的并发请求数可以是 Transformers 的 3-5 倍,因为显存不再被浪费在“预留但没用”的空间上。论文中的实测数据:LLaMA-13B 在 A100 上,vLLM 的吞吐量是 HuggingFace Transformers 的 8.5 倍,是 TGI(Text Generation Inference)的 2.2 倍。

2.3 连续批处理(Continuous Batching)
vLLM 的第二个关键创新是连续批处理(也叫 In-Flight Batching、Iteration-Level Batching)。
传统静态批处理的问题在于“等”:等满才发车、等完才接新客。连续批处理把粒度从“批次级”细化到“迭代级”——每个 decode iteration(每生成一个 token)都检查:
- 有没有请求生成了 EOS(结束符)?有就立刻踢出 batch,释放它的 KV Cache 块
- 有没有新请求在排队?有就立刻插进 batch,分配 KV Cache 块
- 重新计算 batch 大小,执行本轮 attention + FFN 前向
这就像流水线而不是大巴车。大巴车要等满座才发车、到站才下车;流水线上,产品随时进、随时出,传送带始终满载运行。GPU 始终满载,没有空等时间。
但这带来一个调度挑战:不同请求的序列长度不同,每轮 iteration 的 batch 里可能混着“刚开始 prefill 的长请求”和“decode 快结束的短请求”。vLLM 的调度器需要处理 prefill 和 decode 的混合调度,这个能力叫“Chunked Prefill”——把长输入的 prefill 拆成多个 chunk,和 decode 混在一起跑,避免一个长 prefill 阻塞所有 decode。
2.4 2026 年最新进展:v0.28.0
vLLM 在 2026 年的迭代速度极其密集。v0.28.0(2026 年 8 月 26 日发布)的几个关键更新:
- DeepSeek-V4 全面支持:sparse MLA(Multi-head Latent Attention)端到端工作,覆盖 plain decode、MTP(Multi-Token Prediction)和 DSpark 投机解码;AMD Quark NVFP4 量化支持
- Kimi-K3 全栈优化:Decode Context Parallel(DCP)、融合 FlashKDA decode/prefill kernel、自适应投机 token budget(TTFT 提升约 60%)、共享专家分片(每 GPU 省约 17GB 显存)
- E/P/D 分离:Model Runner V2 支持预填充/编码/解码三阶段分离部署
- 分层 KV Cache 卸载:支持磁盘级卸载,突破显存物理限制。热数据在 GPU 显存,温数据在 CPU 内存,冷数据在 SSD,按访问频率自动迁移
- Rust 前端与 gRPC:多模态图像推理走 gRPC,protobuf schema 发布到 Buf,降低 Python GIL 瓶颈
- 新默认值:
max_num_batched_tokens从 8192 提升到 16384;Blackwell CUDA graph 捕获默认提升到 1024
这些更新的密度说明一件事:vLLM 已经不是“能跑就行”的学术项目,而是被各大厂拿来跑生产级服务的工程系统。阿里云 PAI、AWS SageMaker、火山引擎等云厂商的推理服务默认底座都是 vLLM。
2.5 快速部署示例
vLLM 的上手门槛很低,几行代码就能起一个 OpenAI 兼容的推理服务:
# 安装
# pip install vllm
# 方式一:命令行启动 OpenAI 兼容服务(单卡)
# python -m vllm.entrypoints.openai.api_server \
# --model meta-llama/Llama-3.1-8B-Instruct \
# --tensor-parallel-size 1 \
# --max-model-len 8192 \
# --gpu-memory-utilization 0.9
# 方式一升级:多卡部署 + 量化 + 前缀缓存
# python -m vllm.entrypoints.openai.api_server \
# --model meta-llama/Llama-3.1-70B-Instruct \
# --tensor-parallel-size 4 \
# --max-model-len 32768 \
# --gpu-memory-utilization 0.9 \
# --enable-prefix-caching \
# --quantization awq \
# --enable-chunked-prefill \
# --max-num-batched-tokens 16384
# 方式二:Python API 离线推理
from vllm import LLM, SamplingParams
llm = LLM(
model="meta-llama/Llama-3.1-8B-Instruct",
tensor_parallel_size=1,
max_model_len=8192,
gpu_memory_utilization=0.9,
enable_prefix_caching=True,
)
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=512,
)
prompts = [
"用三句话解释什么是 PagedAttention",
"vLLM 的连续批处理和传统批处理有什么区别?",
]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated = output.outputs[0].text
print(f"Prompt: {prompt}")
print(f"Output: {generated}")
print("---")
关键参数说明:
| 参数 | 作用 | 推荐值 | 踩坑提示 |
|---|---|---|---|
tensor_parallel_size |
张量并行度(几张卡) | 按显卡数设 | 单卡放不下才加卡,TP 通信有开销 |
max_model_len |
最大上下文长度 | 按实际 P99 长度的 1.2-1.5 倍 | 设太大浪费显存预分配 |
gpu_memory_utilization |
显存利用率上限 | 0.85-0.90 | 生产环境别超过 0.90 |
enable_prefix_caching |
前缀缓存 | True | 有固定 system prompt 时收益大 |
enable_chunked_prefill |
分块预填充 | True | 避免长输入阻塞短请求 |
quantization |
量化方式 | awq / gptq / fp8 | FP8 精度损失最小,吞吐翻倍 |
max_num_batched_tokens |
单批最大 token 数 | 8192-16384 | 值越大吞吐越高但延迟也高 |
三、SGLang:用“基数树”加速推理
3.1 一句话定位
SGLang 由 LMSYS Org(就是做 Chatbot Arena 的团队)开发,2023 年 12 月首次提交论文(arXiv:2312.07104),2024 年 1 月首次发布,核心创新是 RadixAttention——用一棵基数树(Radix Tree)管理 KV Cache,让多请求共享公共前缀缓存。截至 2026 年 8 月,GitHub Star 32.5k,是增速最快的推理框架。
3.2 核心原理:RadixAttention
先看一个场景:Agent 多轮对话中,每一轮都会带上之前所有的对话历史。第 10 轮对话的输入,前 9 轮的内容和第 9 轮完全一样。如果每轮都重新计算这些 token 的 KV Cache,就是纯粹的浪费——10 轮对话里,前 9 轮的 KV Cache 被重复计算了 9 次。
vLLM 的 PagedAttention 也有前缀缓存,但它是基于哈希匹配的——exact match,你换了哪怕一个字符就命中不了。而且缓存淘汰是 LRU(最近最少使用),不考虑请求之间的结构关系。换句话说,vLLM 的前缀缓存是“全有或全无”:要么整个前缀完全匹配命中,要么一个 token 都复用不了。
SGLang 的 RadixAttention 用一棵基数树来管理所有请求的 KV Cache,解决这个问题:
基数树的数据结构:
基数树是一种压缩前缀树(Patricia Trie 的变体)。在 SGLang 中:
- 树的每条边代表一段 token 序列(不是一个 token,而是一段——这是“压缩”的关键)
- 每个节点存储这段 token 序列对应的 KV Cache 指针(指向物理显存块)
- 从根到某个节点的路径,就是某个请求的完整输入
- 两个请求共享的公共前缀,在树上就是共享的路径前缀
新请求到来的处理流程:
- 匹配:从树根开始,沿着边逐 token 比较新请求的输入。命中到哪算哪——即使只差最后一个 token,前面的所有 KV Cache 都能复用。这叫“部分命中”
- 分裂:如果匹配到某条边的中间就断了(比如边上存的是“Hello World”但请求只有“Hello Wo”),就把这条边拆成两条:已匹配部分和新分支
- 插入:把未匹配的剩余 token 序列作为新边插入树中,分配新的物理块存储这些 token 的 KV Cache
- 引用计数:每个节点维护一个引用计数,表示有多少活跃请求正在使用这个节点的 KV Cache
缓存淘汰机制:
当显存不够时需要淘汰缓存。RadixAttention 的淘汰策略是“树结构感知”的:只能删除引用计数为 0 的叶子节点(没有活跃请求在用、且没有子节点依赖它)。从叶子往根删,保证不会删掉一个正在被共享的前缀。这比 vLLM 的 LRU 策略精确得多——LRU 可能把一个“很久没用但马上会再用”的前缀删了。

举个具体例子:用户 A 问“请解释什么是 PagedAttention”,用户 B 问“请解释什么是 RadixAttention”。两个请求共享前缀“请解释什么是”,在基数树上共享同一条边。用户 A 的“请解释什么是”→“PagedAttention”和用户 B 的“请解释什么是”→“RadixAttention”是两条不同的子边。前 8 个 token 的 KV Cache 只计算一次,两个请求共享。vLLM 的哈希匹配做不到这种部分共享。
| 维度 | vLLM 前缀缓存 | SGLang RadixAttention |
|---|---|---|
| 数据结构 | 哈希表 | 基数树(压缩前缀树) |
| 匹配方式 | 哈希精确匹配 | 最长前缀匹配 |
| 部分命中 | 不支持 | 支持(命中到哪算哪) |
| 缓存淘汰 | LRU 全局策略 | 树结构感知淘汰(引用计数) |
| 多轮对话 | 每轮全量重算 | 自动复用历史前缀 |
| Agent 场景 | 优势不明显 | 显著优势 |
| 论文报告吞吐提升 | — | 最高 6.4x |
SGLang 论文报告的数据:在 Agent 多轮对话场景下(共享前缀占比 >50%),RadixAttention 相比无缓存基线最高 6.4 倍吞吐提升。在 Agent workload 基准测试 ShareGPT 和 AgentBench 上,SGLang 比 vLLM 领先 3-5 倍。
3.3 结构化输出加速
SGLang 的另一个杀手特性是结构化输出(Structured Generation)。当你需要模型输出 JSON、XML 或遵循特定 schema 的内容时,传统做法是让模型自由生成,然后用正则表达式或 JSON parser 提取——但模型经常生成不合法的 JSON,你只能重试,浪费 token 和时间。
SGLang 的做法是在解码过程中直接施加约束(叫“Constrained Decoding”)。原理是:
- 你提供一份 JSON Schema(定义字段名、类型、约束)
- SGLang 内部用一套有限状态机(FSM)解析 schema,构建合法 token 的转移规则
- 每生成一个 token,SGLang 检查当前状态下的合法 token 集合,把不合法的 token 概率置为零(logits mask)
- 采样器只从合法 token 中采样,模型永远不会生成不合法的 JSON
效果:不需要重试,不需要后处理,一次生成就是合法 JSON。在需要大量结构化输出的 Agent 场景(比如工具调用、function calling),这比“生成后修复”快得多,而且避免了重试浪费的 token 成本。
3.4 2026 年最新进展:v0.5.16 → v0.5.18
SGLang 在 2026 年的迭代同样猛烈,三个版本密集连发:
- v0.5.16(7 月 25 日)——DSpark 置信度驱动投机解码:不固定草稿长度,而是根据草稿模型自身的置信度动态调整验证窗口大小;DeepSeek-V4-Pro TP8 B300 上达到 383.7 tok/s(accept length 约 5)
- v0.5.17(8 月 8 日)——Kimi-K3 day-0 支持:2.8T 参数 LatentMoE,896 专家 top-16 路由,1M 上下文,69 层 KDA 线性注意力 + 24 层 MLA,原生 MXFP4 检查点,DCP + DSpark 投机解码 + 分块预填充流水线并行。同期还引入 Rust 前端(网络入口到 GPU 调度器之间迁移到多线程 Rust)、DWDP 预填充并行(通过 NVLink P2P 预取对端专家权重、本地计算所有专家,消除 EP all-to-all token 分发,4x B200 上比 DEP4 快 1.92x)、Session-aware 统一 Radix Cache(Agent/RL 场景下请求携带 session_id,淘汰策略感知会话引用)
- v0.5.18(8 月 22 日)——NVFP4 在 AMD 上运行:将 NVIDIA NVFP4 权重反量化再重量化为 MXFP4,无需全精度中间副本;还有 710 PR、212 贡献者的社区规模
3.5 快速部署示例
# 安装
# pip install "sglang[all]"
# 方式一:命令行启动 OpenAI 兼容服务
# python -m sglang.launch_server \
# --model-path meta-llama/Llama-3.1-8B-Instruct \
# --tp 1 \
# --context-length 8192 \
# --enable-radix-cache
# 方式一升级:多卡 + 量化 + 结构化输出约束
# python -m sglang.launch_server \
# --model-path meta-llama/Llama-3.1-70B-Instruct \
# --tp 4 \
# --context-length 32768 \
# --enable-radix-cache \
# --quantization fp8 \
# --enable-structured-output
# 方式二:Python API(离线推理 + 结构化输出)
import sglang as sgl
@sgl.function
def multi_step_qa(s, question):
s += "你是一个技术助手。请回答以下问题:\n"
s += question
s += "\n请用 JSON 格式输出,包含 answer 和 confidence 两个字段。"
# 启动运行时
runtime = sgl.Runtime(
model_path="meta-llama/Llama-3.1-8B-Instruct",
tp_size=1,
)
# 结构化输出:直接约束为 JSON
response = runtime.run(
"请用 JSON 格式描述 HTTP 和 HTTPS 的区别,包含 protocol、port、security 三个字段",
temperature=0.0,
json_schema={
"type": "object",
"properties": {
"protocol": {"type": "string"},
"port": {"type": "integer"},
"security": {"type": "string"},
},
"required": ["protocol", "port", "security"],
},
)
print(response)
SGLang 独特的 DSL 编程接口(@sgl.function)让你可以用声明式的方式定义多步推理流程,SGLang 自动处理 KV Cache 管理和批处理调度,特别适合 Agent 场景中“先搜索、再判断、再生成”的多步链路。
四、TensorRT-LLM:NVIDIA 的性能天花板
4.1 一句话定位
TensorRT-LLM 是 NVIDIA 官方开源的大模型推理引擎,2023 年 10 月发布,基于 TensorRT 深度学习推理优化器构建,用 C++/CUDA 深度优化,在 NVIDIA 硬件上把推理性能压榨到极致。截至 2026 年 8 月,GitHub Star 14.5k,9000+ commits。
4.2 核心原理:编译式优化
vLLM 和 SGLang 是“解释执行”的——模型加载进来,每次推理都是动态执行计算图。TensorRT-LLM 是“编译执行”的——它先把模型编译成一个优化过的 TensorRT 引擎,这个引擎针对你的具体硬件、模型结构和精度配置做了大量优化。
为什么编译能提升性能?因为推理和训练不同——训练需要灵活的计算图来做反向传播,推理不需要。推理的计算图是固定的(每次都是前向传播),所以可以在推理前做一次“预优化”,把所有可以提前算的都提前算好。
TensorRT 编译引擎时做的核心优化有四类:
1. 算子融合(Kernel Fusion)
Transformer 模型里有很多小算子串行执行。比如一个标准的 MLP 层:MatMul → Bias Add → GELU Activation,这是三个独立的 GPU kernel。每次 kernel launch 有约 5-10 微秒的开销(CPU 向 GPU 发指令、GPU 等待调度),而且中间结果要写回显存再读出来。
TensorRT 把这三个算子融合成一个 kernel:输入数据进 GPU,一口气算完 MatMul + Bias + GELU,中间结果不落显存,直接在寄存器里传给下一步。省了 2 次 kernel launch 开销,省了 2 次显存读写。
实际效果:一个 70B 模型有 80 层 Transformer,每层有多个可融合的算子组,融合后 kernel launch 次数从数百次降到几十次,端到端延迟降低 15%-25%。
2. 精度优化(Precision Calibration)
TensorRT-LLM 支持多种精度:FP32 → FP16 → FP8 → INT8 → INT4 → FP4。精度越低,计算越快、显存越省。
关键问题是:哪些层可以用低精度、哪些层必须保持高精度?TensorRT 的做法是“精度校准”(Calibration)——用一批代表性数据跑推理,统计每层激活值的分布范围,自动决定哪些层可以安全降到 INT8/FP8 而不损失精度。这比一刀切量化精准得多。
在 Blackwell 架构(B200/GB200)上,TensorRT-LLM 支持原生 FP4(NVFP4),把权重和激活从 16 位压到 4 位,显存占用降为原来的 1/4,吞吐提升 4-8 倍。NVIDIA 官方数据:Llama 4 Maverick 在 B200 上突破 1000 TPS/user。
3. CUDA Graph 静态化
正常推理流程是:CPU 发指令 → GPU 执行 → CPU 等结果 → CPU 发下一条指令。这个 CPU-GPU 来回通信的延迟约 5-10 微秒/次,一个 decode iteration 有几十次 kernel launch,光通信开销就几百微秒。
CUDA Graph 把整个计算图“录制”下来,之后每个 iteration 只需一次 CPU → GPU 的图启动指令,GPU 自己按图执行所有 kernel,不再需要 CPU 逐条指挥。这对 decode 阶段特别有效——decode 的计算量小,CPU-GPU 通信开销占比高(可能 20%-30%),用 CUDA Graph 后这部分开销几乎归零。
4. Plugin 机制
对于标准算子,TensorRT 有内置融合。但对于特殊模型结构(如 FlashAttention、GPTQ/AWQ 量化、Mamba 的 selective scan),标准 TensorRT 不认识。Plugin 机制允许你写自定义 CUDA kernel 注册到引擎中,享受 TensorRT 的调度优化但用你自己的算子实现。
代价是:编译引擎需要时间(大模型可能 10-30 分钟),换模型要重新编译,换硬件也要重新编译(H100 上的引擎不能在 A100 上跑)。灵活性远不如 vLLM/SGLang。
4.3 In-flight Batching:TensorRT-LLM 版的连续批处理
TensorRT-LLM 也有连续批处理,叫 In-flight Batching,和 vLLM 的 Continuous Batching 概念一样——请求动态加入和离开 batch。但实现层面不同:
- vLLM 的调度在 Python 层,用 asyncio 管理
- TensorRT-LLM 的调度在 C++ 层,更底层,调度开销更小(约 50-100 微秒 vs Python 层的 200-500 微秒)
在低延迟场景(要求 TTFT < 100ms),这个调度开销差异会有体感。但对于大多数在线服务,两者差异不大。
4.4 2026 年定位:Blackwell 上的极致性能
2026 年,TensorRT-LLM 的角色越来越聚焦于“在 NVIDIA 硬件上跑出极致性能”:
- Blackwell FP4/FP8 量化:在 B200/GB200 上把 FP4 推理推到极致,NVIDIA 官方宣称 Llama 4 Maverick 在 B200 上突破 1000 TPS/user 大关
- NIM 微服务:通过 NVIDIA NIM 直接下载部署模型,TensorRT-LLM 作为底层引擎,一行命令拉起预编译引擎
- DeepSeek-V4 适配:2026 年 7 月发布技术博客,详述 DeepSeek-V4 在 Blackwell 上的模型专用优化和 Agent 工作负载优化
- DWDP 分布式权重并行:NVIDIA 自研的 MoE 预填充并行策略,在 NVL72 机架上实现高性能推理
- 扩散模型支持:2026 年 4 月起支持视觉生成模型,不只是 LLM 了
但 TensorRT-LLM 在 2026 年面临一个现实挑战:vLLM 和 SGLang 的性能正在快速逼近它,而且部署灵活性远胜于它。很多团队的策略变成了“开发用 vLLM/SGLang,极致性能场景用 TensorRT-LLM”。
4.5 快速部署示例
# TensorRT-LLM 的部署流程分两步:构建引擎 + 运行推理
# 第一步:构建引擎(以 Llama 为例,FP8 量化)
# 使用 trtllm-build 命令行工具构建
# trtllm-build \
# --model_dir ./llama-3.1-8b-hf \
# --output_dir ./trt-engine \
# --dtype float16 \
# --use_gemm_plugin \
# --use_rmsnorm_plugin \
# --max_batch_size 32 \
# --max_input_len 8192 \
# --max_output_len 512
# FP8 量化版(需要 H100/H200)
# trtllm-build \
# --model_dir ./llama-3.1-8b-hf \
# --output_dir ./trt-engine-fp8 \
# --dtype float16 \
# --use_fp8 \
# --gemm_plugin float16 \
# --max_batch_size 64 \
# --max_input_len 8192 \
# --max_output_len 512
# 第二步:运行推理
import tensorrt_llm
from tensorrt_llm.runtime import ModelRunner
runner = ModelRunner.from_dir(
engine_dir="./trt-engine",
rank=0,
)
# 单次推理
output = runner.generate(
input_ids=[1, 2, 3, 4, 5], # tokenized input
max_new_tokens=128,
temperature=0.7,
top_p=0.9,
)
print(output)
五、三大框架横向对比
5.1 架构对比
| 维度 | vLLM | SGLang | TensorRT-LLM |
|---|---|---|---|
| 开发者 | UC Berkeley | LMSYS Org | NVIDIA |
| 首次发布 | 2023.06 | 2024.01 | 2023.10 |
| GitHub Star | 90.2k | 32.5k | 14.5k |
| 实现语言 | Python + CUDA | Python + CUDA + Rust | C++ + CUDA |
| 核心创新 | PagedAttention | RadixAttention | 编译式优化 |
| 显存管理 | 块表分页 | 基数树 + 块表 | 编译时静态规划 |
| 批处理 | Continuous Batching | Continuous Batching | In-flight Batching |
| 前缀缓存 | 哈希精确匹配 | 基数树最长前缀匹配 | 不支持 |
| 结构化输出 | 支持 | 原生支持(FSM 约束) | 支持 |
| 硬件支持 | NVIDIA + AMD + Intel | NVIDIA + AMD | 仅 NVIDIA |
| 部署灵活度 | 高 | 高 | 中(需编译) |
| 极致性能 | 高 | 高(Agent 场景突出) | 最高(同硬件) |
| 社区活跃度 | 最高 | 快速增长 | 中等 |
5.2 性能对比(2026 年公开数据)
以下数据来自社区公开测评,具体数字随硬件、模型、配置不同差异较大,仅供参考:
| 指标 | vLLM v0.28 | SGLang v0.5.18 | TensorRT-LLM |
|---|---|---|---|
| 通用吞吐(Qwen2-7B/A100) | 基准线 286 tok/s | 约持平 280-310 tok/s | 约 210-250 tok/s |
| 首 Token 延迟 TTFT | 92ms | 良好(前缀命中时极低) | 优秀(70-80ms) |
| 多轮对话吞吐 | 良好 | 显著领先 3-5x(前缀复用) | 良好 |
| 结构化输出 JSON | 支持但需后处理 | 原生 FSM 约束,零重试 | 支持但需后处理 |
| MoE 模型支持 | DeepSeek-V4 全链路 | Kimi-K3 day-0 支持 | NIM 适配 |
| Blackwell FP4 | 支持 | 支持 | 原生最优 |
| 启动速度 | 快(秒级) | 快(秒级) | 慢(编译 10-30 分钟) |
| Agent 场景吞吐 | 基准线 | 领先 20%-40% | 领先 10%-15% |
一个关键结论:三个框架在“通用吞吐”上的差距正在缩小。真正的差异在特定场景——Agent 多轮对话选 SGLang,极致低延迟选 TensorRT-LLM,其他都选 vLLM。
5.3 成本对比:自部署经济账
以部署 70B 模型为例:
| 方案 | 硬件 | 月成本(含运维) | 吞吐量 | 每 M token 成本 |
|---|---|---|---|---|
| vLLM + AWQ INT4 | 2x A100 80G | 约 1.5 万元 | 约 2000 tok/s | 约 2.6 元 |
| vLLM + FP8 | 2x H100 | 约 2.5 万元 | 约 3000 tok/s | 约 3.2 元 |
| SGLang + RadixAttention(Agent 场景) | 2x A100 80G | 约 1.5 万元 | 约 2600-3000 tok/s | 约 1.8-2.1 元 |
| TensorRT-LLM + FP8 | 2x H100 | 约 2.5 万元 | 约 3000 tok/s | 约 3.2 元 |
| DeepSeek API(高峰) | 0 | 按量付费 | 不限 | 27 元/M token |
| DeepSeek API(低谷) | 0 | 按量付费 | 不限 | 13.5 元/M token |
自部署在中等流量下成本远低于 API 调用。但前提是:硬件利用率要高。如果 GPU 大部分时间空转,自部署反而更贵。这也是为什么推理框架选型——决定了同样的硬件能扛多少流量。
5.4 选型决策树

你的场景是什么?
├── 边缘端 / 个人电脑 / CPU 推理
│ └── 选 llama.cpp 或 Ollama(不在本文范围,但记住这两个)
├── GPU 服务端
│ ├── 需要极致性能、只用 NVIDIA 硬件
│ │ └── 选 TensorRT-LLM
│ ├── Agent / 多轮对话 / 结构化输出为主
│ │ └── 选 SGLang
│ ├── 通用场景、快速部署、多硬件支持
│ │ └── 选 vLLM(默认首选)
│ └── 不确定
│ └── 选 vLLM(最安全的选择)
六、2026 年推理框架的五个热点
6.1 day-0 模型支持战:发布即适配
2026 年 8 月 26 日深夜,阿里开源 Qwen3.8-Flash-Next(125B 总参 / 6B 激活,Qwen4 架构预览版,多模态 MoE),智谱开源 GLM-5.3-Flash(320B-A18B 原生多模态)。第二天一早,vLLM 和 SGLang 的 GitHub 上就出现了对应的适配 PR——这就是推理框架行业的“day-0 支持战”。

“day-0”这个说法来自软件行业的“day-1 patch”——产品发布当天就出补丁。在大模型领域,day-0 支持的意思是:模型发布的当天(甚至几小时内),推理框架就能跑起来。
为什么这么卷?因为模型发布后的前 48 小时是热度窗口。用户下载模型想试用,发现框架不支持,转头就去试别的模型了。模型公司为了口碑,会在发布前 2-4 周就把模型权重给框架团队“内测”。
2026 年的 day-0 支持战已经从“能跑”升级到“跑得快”:
- Kimi-K3(2026 年 7 月底发布):SGLang 在 v0.5.17 实现 day-0 支持,不仅是加载,还做了 DCP + DSpark 投机解码 + 分块预填充流水线并行的全栈优化;vLLM 在 v0.28.0 完成全栈优化(FlashKDA kernel + 共享专家分片 + 自适应投机 budget)
- DeepSeek-V4(2026 年年中):vLLM v0.28.0 支持 sparse MLA 端到端,SGLang 同步支持
- Qwen3.8-Flash-Next(8 月 26 日):SGLang 已发布 cookbook 适配文档,vLLM 正在跟进
对普通用户来说,模型再好,没有框架适配就是“看得见摸不着”。day-0 支持战的背后,是推理框架团队对模型架构的深度理解——不是简单改个 config 就行,而是要针对新的注意力机制(MLA、KDA)、新的 MoE 路由方式写专属的 CUDA kernel。
6.2 单位 Token 成本时代:自部署 vs API 的经济账
2026 年 8 月 17 日,DeepSeek 全面调整 API 定价,首次在大模型行业引入“峰谷分时计价”:工作日 9:00-12:00、14:00-18:00 为高峰时段价格翻倍,其余时段半价。V4-Pro 高峰输出价涨到 27 元/百万 tokens(旧价 6 元,涨 350%),缓存命中输入价最高涨了 12 倍。8 月 23 日起周末全天按低谷价。

这一波涨价让“自部署还是调 API”成了热门话题。来算一笔账:
调 API 的成本:假设日均 100 万 token 输出量,高峰时段占 60%,低谷 40%。高峰:60 万 token × 27 元/百万 = 16.2 元/天;低谷:40 万 token × 13.5 元/百万 = 5.4 元/天。日均 21.6 元,月均约 648 元。看起来不多?但这是单路并发的价格。如果你的服务有 100 路并发,月成本就是 6.48 万元。
自部署的成本:一台 2×A100 服务器,月租约 1.5 万元(含电费+运维)。用 vLLM + AWQ INT4 量化部署 70B 模型,吞吐约 2000 tok/s。日均可处理约 1.7 亿 token,月处理约 50 亿 token。每百万 token 成本约 0.3 元——比 API 低谷价还便宜 45 倍。
但自部署有前提:你的流量要足够稳定、足够大。如果 GPU 大部分时间空转(利用率 <20%),自部署反而更贵。推理框架就是自部署的核心变量——框架选得好,同样的硬件吞吐翻倍,单位 Token 成本直接对半砍。这也是 2026 年推理框架选型比以往任何一年都重要的原因。
6.3 E/P/D 分离:Prefill 和 Decode 各司其职
前面讲过,Prefill 是计算密集型(吃 FLOPS),Decode 是访存密集型(吃带宽)。传统做法是两者在同一套 GPU 资源上跑,结果就是两边都吃不饱。

E/P/D 分离(Encode/Prefill/Decode Disaggregation)的思路是:把三个阶段分到不同的 GPU 池上。
- E(Encode)节点:处理多模态输入(图片/视频编码),用 ViT 等 encoder 生成 embedding
- P(Prefill)节点:专做计算密集的预填充,可以配置高算力比的 GPU(如 H100 SXM5,989 TFLOPS)
- D(Decode)节点:专做访存密集的解码,可以配置高带宽比的 GPU(如 HBM3e 带宽更高的卡)
三者通过高速网络(NVLink 900GB/s 或 RDMA 200Gbps)传输 KV Cache。关键挑战是 KV Cache 传输延迟——一个 32K 上下文的 KV Cache 约 5-10GB,通过 NVLink 传输约 10-20ms,通过 RDMA 传输约 50-100ms。如果传输比计算还慢,分离就没意义了。所以 E/P/D 分离通常需要 NVLink 级别的互联。
收益有多大?vLLM 的实验数据:在长输入场景(输入 8K+ token),E/P/D 分离比混合部署吞吐提升 30%-50%,TTFT 降低 40%。因为 Prefill 节点不需要等 Decode 节点释放显存,Decode 节点也不被 Prefill 的长计算阻塞。
vLLM v0.28 的 Model Runner V2 已经支持 E/P/D 分离,SGLang 也有 PD disaggregation 支持。2026 年这已经成为生产级推理平台的标配能力。阿里云 PAI、火山引擎等云厂商的推理服务已经默认采用 PD 分离架构。
6.4 MoE 部署:DeepSeek-V4 和 Kimi-K3 带来的新挑战
2026 年最火的模型——DeepSeek-V4-Pro(1.6T 参数 / 49B 激活)和 Kimi-K3(2.8T 参数 / 896 专家 top-16 路由)——都是超大 MoE 架构。MoE 部署对推理框架提出了全新挑战:
挑战一:显存装不下。 1.6T 参数的模型,即使 FP8 量化(每参数 1 byte),也需要 1.6TB 显存——需要 20 张 H100 80G。这还不是全部:MoE 模型的所有专家权重都要常驻显存(因为不知道哪个 token 会被路由到哪个专家),即使每次只激活一小部分。
挑战二:专家路由通信。 张量并行下,专家分布在不同 GPU 上。一个 token 被路由到某专家,但那个专家在另一张卡上——token 要通过 all-to-all 通信跨卡传送。896 个专家分布在 8 张卡上,每张卡 112 个专家,每个 token 都可能需要跨卡路由。all-to-all 通信是 MoE 推理的最大的开销,可能占端到端延迟的 30%-50%。
挑战三:负载不均衡。 某些热门专家被频繁路由到(比如处理数学的专家),其他专家闲着。这导致某些 GPU 过载、其他 GPU 空转。传统张量并行假设各卡负载均匀,MoE 打破了这个假设。
vLLM 和 SGLang 都在这个方向上密集投入:
- vLLM v0.28 的“共享专家分片”:把 MoE 中共享的专家(所有 token 都会经过的专家)在多卡间分片存储,每 GPU 省 17GB 显存。同时优化了 all-to-all 通信的 kernel 实现。
- SGLang 的 DWDP(Distributed Weighted Data Parallel)预填充并行:通过 NVLink P2P 预取对端专家权重、本地计算所有专家,消除 EP all-to-all token 分发。4x B200 上比传统 DEP4 快 1.92x。
这些优化的核心思想都是“减少跨卡通信”——要么让数据不动、权重动(DWDP),要么让共享专家分片存储减少冗余。
6.5 投机解码:让小模型猜,大模型验
投机解码(Speculative Decoding)的思路是:用一个小的草稿模型(draft model)快速生成几个候选 token,再用大模型一次性验证。如果草稿猜对了,就省了大模型逐个生成的开销;如果猜错了,大模型纠正,也不比原来慢。
为什么有效?因为大模型的 decode 是逐 token 串行的——每生成一个 token 要走一遍完整的前向传播。如果有 5 个 token 要生成,就是 5 次前向传播。投机解码让小模型快速生成 5 个候选 token(小模型推理快),然后大模型一次性并行验证 5 个 token(一次前向传播验证多个),猜对 4 个就省了 4 次大模型前向传播。
2026 年的进展是“置信度驱动”的投机解码。传统投机解码固定草稿长度(比如总是生成 5 个候选 token),但有些 token 容易猜(如“中华人民共和国”后面的“万岁”),有些难猜(如代码中的变量名)。SGLang 的 DSpark 根据草稿模型自身的置信度动态调整验证窗口大小——置信度高时多猜几个,置信度低时少猜甚至不猜。
实测数据:DeepSeek-V4-Pro 上用 DSpark 投机解码达到 383.7 tok/s,accept length 约 5(平均每轮猜对 5 个 token),比无投机解码快数倍。vLLM v0.28 也引入了 DSpark confidence-scheduled verification 和 DFlash2。
投机解码的成本是显存——草稿模型也要占显存(虽然小很多)。但对于吞吐优先的场景,这笔显存投资很划算。
七、三个真坑,每个都付过费
坑一:vLLM 的 gpu_memory_utilization 设太高导致 OOM
翻车现场:你以为设到 0.95 就是“充分利用显存”?大错特错。vLLM 启动时会按这个比例预分配显存给 KV Cache 池,但模型的权重、激活值、CUDA context、临时 buffer 都要占显存。0.95 意味着只留了 5% 的余量,一旦上下文变长或 batch 变大,立刻 OOM。
报错信息:torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate XX MiB。通常发生在流量高峰——并发请求突然增多,KV Cache 需求超过预留空间。
正确做法:生产环境从 0.85 开始,逐步上调到 0.90。留出 10%-15% 的安全余量。同时用 --max-num-batched-tokens 控制单批最大 token 数(推荐 8192-16384),避免突然冲爆显存。监控指标关注 vllm:gpu_cache_usage_perc——这个值长期 >95% 就该调参数了。
坑二:SGLang 的 RadixAttention 缓存膨胀
翻车现场:RadixAttention 的基数树会缓存所有历史请求的 KV Cache。如果你的服务请求量大、输入多样化(比如每个用户的 prompt 都不同),基数树会无限增长,最终吃光显存。表现为服务运行几小时后突然 OOM 重启。
排查过程:一开始以为是内存泄漏,提了 issue 给 SGLang 团队。人家回复“这不是 bug,是 feature”——RadixAttention 默认不限制树大小,有多少显存用多少。你的场景是每个请求 prompt 都不同(翻译服务、一次性问答),前缀复用率接近 0,但树还在疯狂长。
正确做法:设置 --radix-cache-max-key 限制树大小,或者定期清理。如果你的场景是“每次请求都不同”(比如翻译服务、一次性问答),RadixAttention 的收益有限,直接关掉用 LRU 缓存:--disable-radix-cache。RadixAttention 的价值在于“有大量共享前缀”的场景——Agent、多轮对话、few-shot 批处理。没有共享前缀的场景用,反而白费显存。
坑三:TensorRT-LLM 编译引擎的版本地狱
翻车现场:你在开发机上用 TensorRT 8.6 + CUDA 12.1 编译了一个引擎,测试通过。部署到生产环境(TensorRT 8.9 + CUDA 12.4),引擎加载报错:Engine could not be loaded。你以为是文件路径问题,折腾半天发现:TensorRT 引擎与 TensorRT 版本、CUDA 版本、驱动版本强绑定,差一个小版本就跑不了。
更恶心的场景:生产环境运行了三个月没问题,运维同事升级了 NVIDIA 驱动(从 535 到 545),所有引擎全部失效,线上服务挂了。
正确做法:
- 编译引擎和运行环境严格锁版本,用 Docker 镜像固定全栈(
nvcr.io/nvidia/tensorrt-llm:vX.Y.Z镜像里 CUDA、TensorRT、驱动版本都对齐) - 生产环境永远不随意升级驱动,升级前先在测试环境重新编译全部引擎验证
- 如果模型变更频繁,TensorRT-LLM 的编译成本(每次 10-30 分钟)会吃掉它的性能优势——这时候用 vLLM 反而更划算
八、经验清单
- 先跑通再优化:先用 vLLM 默认参数把服务跑起来,有真实流量数据后再调参。不要一上来就纠结选哪个框架,vLLM 默认参数已经能覆盖 80% 的场景。
- Agent 场景认准 SGLang:多轮对话、工具调用、结构化输出,RadixAttention 的前缀复用收益巨大(3-5 倍吞吐提升)。单轮问答场景差异不大,别为了用 SGLang 而用。
- TensorRT-LLM 适合“定型号”场景:模型不变、硬件不变、追求极致吞吐,才值得付编译成本。模型迭代频繁的团队别碰——每次换模型编译 30 分钟,开发体验极差。
- 量化是免费午餐:FP8 量化在大多数场景下精度损失可忽略(<1% benchmark 差距),吞吐翻倍。先试 FP8,不够再上 INT4/FP4。AWQ 比 GPTQ 部署更友好(不需要校准数据集)。
- 监控比选型更重要:不管选哪个框架,上线后必须监控 GPU 利用率、显存使用、请求队列长度、TTFT(首 token 延迟)、TPOT(每 token 延迟)。很多性能问题不是框架的锅,是参数没调对——比如
max_model_len设太大导致显存浪费,gpu_memory_utilization设太高导致 OOM。 - 混合部署是终极方案:大厂的生产架构往往是“vLLM 跑通用流量 + SGLang 跑 Agent 流量 + TensorRT-LLM 跑低延迟流量”,通过路由层按请求特征分发。不要试图用一个框架解决所有问题。
九、下篇预告
《大模型实战指南(12)——端侧部署:让大模型跑在手机和笔记本上》。推理框架解决了服务端部署,但不是所有场景都有 GPU 集群。手机、笔记本、边缘设备上的大模型推理——llama.cpp、MLX、Ollama 怎么选?4-bit 量化后性能还剩多少?下一篇带你从云端走到终端。
数据来源声明
本文事实性数据来源:
- vLLM GitHub Releases 页面(v0.28.0,2026-08-26 发布,584 commit,270 贡献者)
- vLLM 论文《Efficient Memory Management for Large Language Model Serving with PagedAttention》(SOSP 2023)
- SGLang GitHub Releases 页面(v0.5.18,2026-08-22 发布,710 PR,212 贡献者;v0.5.17,2026-08-08 发布;v0.5.16,2026-07-25 发布)
- SGLang 论文(arXiv:2312.07104,2023-12 提交)
- TensorRT-LLM GitHub 主页(Star 14.5k,9000+ commits,release 1.3.0rc25)
- NVIDIA 官方推理平台文档与 Blackwell 架构白皮书
- DeepSeek-V4 官方技术报告(1.6T 参数 / 49B 激活,MoE 架构)
- Kimi-K3 官方发布信息(2.8T 参数,896 专家 top-16 路由,1M 上下文)
- Qwen3.8-Flash-Next 与 GLM-5.3-Flash 官方发布信息(2026-08-26)
- 社区公开性能测评文章(CSDN、腾讯云开发者社区等)
框架版本和功能特性以官方 GitHub Release Notes 为准,性能数据为社区公开测评,实际效果因环境而异。
更多推荐


所有评论(0)