1.1 大模型部署场景与性能挑战
我在过去两年里陆续参与了大模型落地的项目,场景覆盖在线客服、代码补全、文档摘要、知识库问答和批量报告生成。不同业务对性能的胃口差别很大。在线客服希望用户说完话,屏幕在几百毫秒内出现第一个字;代码补全要求流式输出顺滑,打字节奏不能断;离线报告生成可以接受分钟级等待,可它常常一次塞进来几百上千条请求。模型部署性能对比放在这些场景里看,才会知道延迟、吞吐、显存和成本各自有多重要。
从运维视角,我担心的不只是单次推理快不快。GPU 利用率忽高忽低、并发一上来延迟暴涨、长上下文把显存吃满、扩容后吞吐没有线性增长,这些都会把上线计划拖乱。我见过一个客服机器人白天响应很稳,晚高峰并发翻三倍后首 Token 延迟从 400 毫秒冲到 3 秒,用户直接转人工。那次之后,我对大模型部署的性能挑战有了更具体的认识:它不是一张跑分图,而是一组和业务峰值绑在一起的约束。
我作为技术负责人时,还要算另一笔账。同样一张卡,跑一个 7B 模型和跑一个 70B 模型,能承载的并发完全不同;同样一个模型,用 FP16 和 INT8,显存占用和输出质量也会拉出差距。模型部署性能对比能帮我把这些变量摆到桌面上,避免用“感觉够快”来做决定。
1.2 为什么需要框架级部署性能对比
我一开始也有个朴素想法:模型权重不变,推理框架换来换去,性能差距能有多大。实际压测给我上了一课。vLLM 和 TensorRT-LLM 在请求调度、KV Cache 管理、连续批处理、量化支持、图优化和部署方式上各有思路。它们面对低并发、高并发、长上下文、短输出这些负载时,表现会分叉。框架级部署性能对比的价值,就是把这些分叉量出来,而不是停在文档宣传和社区口碑上。
我站在架构师的位置看,选型会牵动上线节奏、硬件采购、扩容方式和运维复杂度。开发同学关心 API 兼容、调试体验和生态工具。业务方只关心用户等多久、每千 Token 花多少钱。模型部署性能对比把这些视角串起来,让团队讨论时有共同语言。单看“每秒生成多少 Token”不够,单看“首 Token 延迟多低”也不够。
我实际做对比时,会尽量固定模型版本、硬件型号、驱动版本、CUDA 版本、输入长度和输出长度。这样得到的差异才更接近框架本身带来的差异。模型部署性能对比不是学术排名,它要回答几个很具体的问题:低并发下谁先出字,高并发下谁不崩,长上下文谁更省显存,多卡扩展谁更省心,单位 Token 成本谁更低。
1.3 本文评测范围、目标与读者收益
这篇内容会围绕 vLLM 与 TensorRT-LLM 展开,评测范围包括推理延迟、首 Token 延迟、端到端响应时间、吞吐量、并发能力、批处理效率、显存占用、资源利用率和多 GPU 扩展性。测试模型会覆盖常见的 7B、13B、70B 级别,硬件环境以 NVIDIA A100、H100、L40S 这类 GPU 为参考,精度会涉及 FP16、INT8、FP8 等常见配置。负载会分成短上下文、长上下文、低并发、高并发和流式输出几类。
我写这些内容的目标,是让正在做模型部署的工程师、架构师、技术负责人和算力采购同学拿到一套可复用的观察方法。你会看到怎样设计压测、怎样读 P50/P90/P99 延迟、怎样判断吞吐瓶颈、怎样比较显存和成本。模型部署性能对比的结论不能替代你自己的业务压测,它可以帮你少走一些弯路,少被单一跑分带偏。
读完这一章,你会对后面的对比框架和指标有整体印象。我会用一线视角记录测试思路、踩过的坑和选型判断。文末会给出决策矩阵和优化策略,把模型部署性能对比落到低延迟服务、高吞吐平台和成本敏感型业务的具体选择上。
2.1 vLLM 与 TensorRT-LLM 的架构特点与部署方式
我第一次把 vLLM 和 TensorRT-LLM 放在同一台机器上跑起来的时候,感受挺直接的。vLLM 的安装体验像 pip install 之后配个模型路径就能启动,PagedAttention 和连续批处理是它的核心卖点,KV Cache 按页管理,显存碎片少,请求来了能动态拼批。TensorRT-LLM 走的是另一条路,它需要先把模型编译成 TensorRT 引擎,过程里要做图优化、层融合、kernel 自动调优,编译一次可能花十几分钟到半小时,拿到引擎之后推理效率很高,部署侧更像传统的高性能推理服务。
我作为运维人员看这两套的部署方式,差别会体现在日常维护里。vLLM 对模型格式和 HuggingFace 生态友好,换模型、调参数、扩副本都比较灵活,适合快速迭代。TensorRT-LLM 的引擎和 GPU 架构、TensorRT 版本、CUDA 版本绑定比较紧,换卡或者升级驱动可能需要重新编译,好处是编译后的执行路径更精简。我遇到过团队在广州机房编译好的引擎拿到北京机房另一批卡上直接报错,回头重新走编译流程。这个特点在选型时不能忽略。
我从小团队负责人的角度算过人力成本。vLLM 上手快,新人半天能跑通一个 demo,遇到问题社区 issue 和文档也比较多。TensorRT-LLM 的学习曲线更陡,需要理解 TensorRT 的优化机制和引擎构建流程,可一旦跑顺,性能调优的空间更大。两套框架都在快速演进,vLLM 在量化支持和多模态上补得很快,TensorRT-LLM 在 FP8、FP4 和 Blackwell 架构上的适配比较积极。模型部署性能对比不能只看当前版本,还要看团队能不能跟上框架的迭代节奏。
2.2 推理延迟、首 Token 延迟与端到端响应时间
我在做性能对比时,会把延迟拆成三个数字来看。首 Token 延迟是用户感知最强的一个指标,它决定用户说完话之后要等多久才能看到第一个字。推理延迟更多指模型完成一次前向计算的时间,在流式输出场景里,它对应每个 Token 之间的间隔。端到端响应时间是从请求发出到最后一个 Token 返回的总时长,它把排队、预填充、解码、网络传输都算进去了。这三个数字经常被混在一起说,实际优化方向完全不同。
我印象很深的一次压测里,两个框架在低并发下的首 Token 延迟差了将近一倍,可端到端响应时间只差 15%。原因是输出长度比较长,首 Token 的优势被后面的解码时间摊薄了。用户体感上,首 Token 延迟低会让交互更跟手,端到端低则影响批量任务的完成时间。模型部署性能对比要按业务场景选主指标,客服和对话机器人优先看首 Token,离线摘要和报告生成更在意端到端。
我测首 Token 延迟的时候会特别留意预填充阶段。输入长度从 512 涨到 8192,预填充的计算量增长很快,首 Token 延迟可能从 200 毫秒涨到 1.5 秒。vLLM 的 PagedAttention 在长输入下对显存的管理比较细,TensorRT-LLM 的 kernel 融合在预填充阶段能压掉一些开销。我把这些数据按输入长度画成曲线之后,选型讨论才不再停留在“谁更快”这种笼统判断上。
2.3 吞吐量、并发能力与批处理效率
吞吐量是我在高并发场景里最关心的指标。它通常用每秒生成的 Token 数或者每秒完成的请求数来衡量。我做过一个对比,同样一张 A100 跑 7B 模型,TensorRT-LLM 在 FP16 下的峰值吞吐能比 vLLM 高出一截,可这个优势在低并发下几乎看不到。吞吐量的价值要结合并发数来读,单请求跑分高不代表服务能力强,能在几百并发下稳住吞吐才有意义。
并发能力是另一个容易被低估的维度。我见过一个服务在 50 并发时表现良好,加到 200 并发后延迟 P99 直接失控,原因是批处理策略和显存调度跟不上。vLLM 的连续批处理能在请求生命周期里动态加入和移除序列,适合请求长度参差不齐的在线服务。TensorRT-LLM 在固定 batch 或者 in-flight batching 模式下效率很高,需要提前配置好最大 batch size 和 KV Cache 预留。两种思路对应不同的业务形态,短请求密集和长请求混合的负载表现会分叉。
我评估批处理效率时会看一个关键比值:有效 Token 吞吐除以理论峰值。这个比值反映了框架把 GPU 算力转化成实际输出的能力。批处理规模从 8 涨到 64,吞吐通常上升,可延迟也会上升,存在一个收益递减的拐点。我一般会把这个拐点找出来,结合业务能接受的最大延迟反推合理的批处理上限。模型部署性能对比里的吞吐数字,不带批处理配置和延迟约束去看,参考价值会打折扣。
2.4 显存占用、资源利用率与扩展性指标
显存是我踩坑最多的一个维度。模型权重、KV Cache、激活值、框架自身开销都会占显存。70B 模型用 FP16 加载光权重就要 140GB 左右,单卡放不下,得走张量并行。KV Cache 随着并发数和上下文长度增长,长上下文场景里它甚至比模型权重还吃显存。vLLM 的 PagedAttention 把 KV Cache 按块管理,浪费少,能支撑更大的并发。TensorRT-LLM 需要提前设置 KV Cache 的大小,设小了并发上不去,设大了显存浪费。
资源利用率我主要看 GPU 计算利用率、显存带宽利用率和 SM 占用率。有些框架吞吐高是因为把 GPU 压得很满,有些是因为调度做得好、空转少。我在监控面板上见过 GPU 利用率 90% 但吞吐不高的案例,排查后发现是 kernel 启动开销和内存拷贝拖了后腿。TensorRT-LLM 编译后的引擎在这方面通常更干净,vLLM 在 Python 层的调度开销会随并发上升而增加。
扩展性指标关注多卡和多机场景。张量并行能降低单卡显存压力,流水线并行适合超大模型,数据并行用来堆吞吐。我测过 2 卡、4 卡、8 卡的扩展曲线,vLLM 在张量并行下的吞吐增长比较平稳,TensorRT-LLM 在 NVLink 连接良好的机器上扩展效率更高。跨节点走 InfiniBand 的时候,通信开销会吃掉一部分扩展收益,两个框架的表现都会变差。模型部署性能对比如果不覆盖多卡,结论只适用于单卡场景。
2.5 测试模型、硬件环境与负载设定
我选测试模型的原则是覆盖主流参数规模。7B 到 8B 级别适合单卡部署,是很多中小团队的主力;13B 到 14B 对显存要求更高,单卡 FP16 比较紧张;70B 级别必须多卡,代表大企业和高要求场景。模型类型上我会选 Llama 系列、Qwen 系列和 Mistral 系列,它们的社区支持好,两个框架的适配都比较成熟。量化版本会测 FP16、INT8 和 FP8,观察精度下降和性能提升之间的权衡。
硬件环境我以 NVIDIA 的卡为主。A100 80GB 是很多机房的存量主力,H100 代表新一代性能,L40S 在推理场景性价比不错。我会记录驱动版本、CUDA 版本、TensorRT 版本、PyTorch 版本,这些信息对结果复现很重要。同一批测试尽量在同一台机器上完成,避免不同机器的散热和功耗策略干扰。网络方面,单机内 NVLink 和 PCIe 的差距很大,多机测试要标注互联方式。
负载设定我会分几类来构造。短上下文短输出模拟在线对话,输入 128 Token 输出 128 Token。长上下文模拟文档问答,输入 8192 Token 输出 512 Token。低并发用 1 到 4 个并发请求,高并发用 64 到 256 个并发请求。流式输出测试会记录每个 Token 的到达时间,批处理测试会扫 batch size 从 1 到 64 的曲线。模型部署性能对比的负载设定要尽量贴近真实业务,合成负载和实际流量之间的差距,往往就是压测结论和线上表现的差距。
3.1 基准测试流程与工具链选择
我搭测试环境的时候习惯先把流程固定下来,跑分结果才有可比性。整个过程分四步:环境准备、预热、正式采集、数据落盘。环境准备阶段我会把两个框架的版本号、CUDA 版本、驱动版本全记在一张表里,每轮测试前重新确认一次。预热特别容易被跳过,模型第一次加载和 kernel 第一次编译会让前几个请求的数字很难看,我一般先跑 20 到 50 个请求丢掉,让缓存和编译都稳定下来再开始计数。
工具链我常用的有三类。一类是框架自带的 benchmark 脚本,vLLM 仓库里的 benchmark_serving 和 benchmark_throughput,TensorRT-LLM 的 trtllm-bench,这些脚本和框架契合度最高,参数也最全。另一类是通用压测工具,我用 Locust 和 wrk 构造过带真实流量特征的请求,好处是能模拟用户思考间隔和请求长度分布。还有一类是自定义 Python 脚本,通过 OpenAI 兼容接口发请求,灵活度高,适合做流式输出和细粒度时间戳采集。我通常混着用,自带脚本出基准数字,自定义脚本验证端到端体验。
采集环节有个细节我一直比较在意:客户端的耗时测量点。只测服务端日志里的时间,网络传输和序列化开销就丢了。我后来改成客户端打时间戳,记录请求发出、首 Token 到达、每个中间 Token 到达、最后一个 Token 到达这几个节点,服务端也同步记录内部时间,两边一对比就能看出瓶颈在框架里还是在网络上。
这套方法跑起来麻烦一点,得到的结论可靠得多。
3.2 单请求延迟测试与流式输出测试
单请求延迟测试是我每次对比的起点。并发设为 1,排除排队和批处理的影响,先看两个框架在裸奔状态下的差距。我测的项目包括首 Token 延迟、每 Token 平均间隔、总输出时间。输入输出长度会扫几组固定值,比如 128/128、512/512、2048/512、8192/512。这组数据能回答一个基础问题:模型换个框架,单用户的体感会不会变。我做过一次 Llama-3-8B 的测试,TensorRT-LLM 在 FP16 下每 Token 间隔比 vLLM 短一些,首 Token 延迟的差距反倒不明显,原因是两个框架在预填充阶段都把算力吃满了。
流式输出测试我会单独做一轮。非流式的端到端时间好测,可实际产品里用户看到的是逐字蹦出来的效果,两种体验不完全一致。我写了个脚本记录每个 Token 的到达时间戳,画成累计曲线。曲线斜率代表解码速度,起点对应首 Token 延迟,曲线上的台阶能暴露调度抖动。有一次我发现某个配置下前 10 个 Token 很快,之后速度掉下来,排查发现是 KV Cache 分页触发了换页。这种问题只看总时间根本发现不了。
我还会测一组"流式 vs 非流式"的对照。同一个请求,一个走 stream=True,一个走 stream=False,比较总耗时。理论上两者应该接近,实测里流式版本偶尔慢 5% 到 10%,开销来自 SSE 编码和多次网络往返。这个差距在高并发下会被放大。做模型部署性能对比,把测试方式和线上调用方式对齐很重要,否则测出来的数字和实际体验会脱节。
3.3 不同并发下的 P50、P90、P99 延迟对比
并发扫描是我最看重的一组实验。我一般设 1、4、8、16、32、64、128、256 这几个档,每个档位跑 3 到 5 分钟,收集所有请求的延迟再算分位数。P50 反映大部分用户的中位体验,P90 和 P99 反映长尾。在线服务里长尾比中位数更值钱,用户投诉的往往是那 1% 的慢请求。我见过 P50 只有 400 毫秒、P99 冲到 8 秒的服务,几个超长请求堵住了批处理队列。
两个框架在并发上升时的曲线形状不一样。vLLM 的连续批处理在并发爬升时延迟增长比较平滑,P99 的抬头相对晚一些。TensorRT-LLM 在低并发下延迟更低,并发超过某个阈值后 P99 会出现比较陡的上升,跟 KV Cache 预留和最大 batch 配置有关。我把两条曲线画在一张图上,选型讨论就有了抓手:业务峰值并发落在哪一段,对应框架的表现如何,一目了然。
测分位数还有个坑是样本量。并发 256 跑 30 秒,样本可能上千个,P99 对应第 10 慢的请求,统计上还算稳。并发 1 跑 30 秒只有几十个样本,P99 基本等于最大值,参考意义不大。我现在的做法是低并发档位拉长测试时间,或者干脆只报 P50 和最大值,避免用不可靠的分位数误导结论。
3.4 批处理规模、量化精度与性能关系测试
批处理规模的扫描我从 1 扫到 64,个别场景会到 128。每档测吞吐和延迟两个指标,画出吞吐-延迟曲线。曲线上有个拐点,拐点之前加 batch 吞吐涨得快、延迟涨得慢,拐点之后吞吐基本持平、延迟继续爬。这个拐点就是业务能接受的批处理上限。vLLM 的动态批处理让这个拐点比较靠后,TensorRT-LLM 在配置好的固定 batch 下拐点前的效率更高。我把拐点对应的 batch size 记下来,调服务参数时直接参考。
量化精度的测试我会用同一份权重走不同路径。FP16 是基准,INT8 和 FP8 各跑一遍。测的项目除了延迟和吞吐,还要加上输出质量的抽样对比。我做过一次 INT8 量化的测试,吞吐涨了接近 40%,生成的一段技术文档里出现了两次术语错误,FP16 版本没有这个问题。量化带来的性能收益是实打实的,精度损失需要业务侧确认能不能接受。我一般建议先在非关键链路灰度,观察一段时间再决定要不要全量。
量化精度和框架支持度也有关联。vLLM 的 AWQ、GPTQ、FP8 支持比较全,切换成本低。TensorRT-LLM 在 FP8 上的 kernel 优化做得比较深,H100 上跑 FP8 的收益明显。我在 A100 上试 FP8 效果一般,硬件本身对 FP8 的支持不如 H100。这套测试做完,我基本能给出一个二维建议表:什么硬件配什么精度配什么框架。
3.5 多 GPU 与分布式部署性能测试
多卡测试我按张量并行走,2 卡、4 卡、8 卡各测一遍。测之前先确认互联方式,NVLink 和 PCIe 的差距能到两倍以上。70B 模型 FP16 单卡放不下,张量并行是必须的,我重点看两件事:扩展效率和通信开销。理想情况下 2 卡吞吐翻倍,实际能到 1.7 到 1.9 倍就算不错。vLLM 在张量并行下的扩展曲线比较稳,TensorRT-LLM 在 NVLink 全互联的机器上效率更高。我把每档的吞吐和单卡对比,算出扩展效率,低于 0.8 的配置我会去查通信是不是瓶颈。
跨节点测试我用过 2 机 4 卡和 2 机 8 卡两种拓扑,互联走 InfiniBand。跨机之后通信延迟上升,两个框架的吞吐都会掉一截,掉多少跟模型大小和并行策略有关。Pipeline 并行对跨机通信的容忍度比张量并行高一些,代价是流水线气泡会吃掉一部分效率。我测过 70B 模型 2 机 4 卡张量并行的配置,吞吐只有单机 4 卡的七成左右,这个损耗要在容量规划里提前算进去。
分布式测试里我还会关注稳定性和故障恢复。跑 30 分钟以上的长测,看显存有没有泄漏、吞吐有没有衰减。有一次跑到第 20 分钟吞吐突然掉了一半,日志里是某个 rank 的通信超时触发了重试。这类问题在短测里根本暴露不出来。
多卡多机的测试成本高,我一般只在最终选型前做一到两轮完整的长测,前面用单卡数据快速筛掉明显不合适的组合。
4.1 低并发场景下的延迟优先表现
低并发场景我一般把并发压在1到4。这个区间用户对延迟最敏感,每多几十毫秒都能感觉到。TensorRT-LLM在这个区间的单请求延迟让我印象很深。Llama-3-8B FP16,A100 80G,输入512输出128,TensorRT-LLM首token大概180毫秒,每token 18毫秒左右。vLLM同条件首token 220毫秒上下,每token 22毫秒。差的不算天翻地覆,放到连续对话里,用户等第一个字的时间差了一截。
我琢磨过这个差距的来源。TensorRT-LLM把计算图编译成engine,kernel融合做得很细,预填充和解码阶段的算子调度开销小。vLLM的PagedAttention在低并发下没什么发挥空间,注意力计算本身省不了多少,反而多了一层块管理的开销。低并发时GPU算力吃不满,TRT-LLM的固定开销低,优势就出来了。
低并发也分几种。单用户聊天、代码补全、语音助手,这些场景并发不高,延迟要求苛刻。TensorRT-LLM在这类业务里体感更好。我试过把vLLM的调度参数调激进一些,首token延迟能压下去一点,追平TRT-LLM还是费劲。代价是部署复杂度上去了,engine编译、版本匹配、量化校准,每个环节都要人盯着。
4.2 高并发场景下的吞吐量优先表现
并发爬到32以上,局面反过来。vLLM的连续批处理开始发力,吞吐曲线往上翘。我测过并发128、输入输出长度混合的负载,vLLM的总吞吐能到TensorRT-LLM的1.1到1.3倍。请求长度越不齐,这个差距越明显。TRT-LLM的in-flight batching也能动态调度,它更依赖配置,max_num_tokens、max_batch_size这些参数设得不对,吞吐直接掉一档。
高并发下TensorRT-LLM的P99延迟抬头更早。并发过了64,它的P99开始陡升,vLLM的P99还在缓慢爬。我画过两条曲线,vLLM的拐点靠后,TRT-LLM的拐点靠前。在线服务里P99一高,用户投诉就来了。vLLM的调度器能更细地切分计算和显存,把长请求和短请求混在一个batch里跑,GPU利用率拉得高。
TRT-LLM在高并发下不是没优势。请求模式稳定、batch固定的时候,它的单位算力效率很高,吞吐能追回来甚至反超。我试过固定输入512输出256、并发64的场景,TRT-LLM吞吐比vLLM高8%左右。这种场景适合离线批处理或者内部服务,流量特征可预测。在线业务流量忽高忽低,vLLM的弹性更值钱。
4.3 长上下文、连续批处理与显存管理对比
长上下文是我最关心的测试项之一。上下文拉到8K、16K、32K,显存管理的好坏直接决定能不能跑。vLLM的PagedAttention把KV Cache切成块,按需分配,碎片少。我跑32K上下文、并发16的测试,vLLM显存占用比较平稳,还能塞下更多请求。TensorRT-LLM也有分页KV Cache,配置项更多,显存预留偏保守,同样硬件下能支持的并发数少一些。
连续批处理方面,vLLM的调度粒度细。新请求进来可以插到正在解码的batch里,不用等当前batch跑完。TRT-LLM的in-flight batching也能做类似的事,它的调度器更偏向静态规划,请求长度差异大时会有气泡。我观察过GPU利用率曲线,vLLM在高并发混合负载下能维持在80%以上,TRT-LLM偶尔掉到60%再弹回去。
显存管理还有个隐性差异。vLLM的块管理让显存超卖变得可行,多个请求共享物理块,显存利用率高。TRT-LLM的engine加载后会占一块固定workspace,模型越大这块越大。我测70B模型时,vLLM在4卡A100上能跑并发64,TRT-LLM同配置并发上限大概40出头。TRT-LLM的单请求延迟还是低,并发容量吃亏。长上下文场景下,这个差距会被放大。
4.4 资源成本、单位 Token 成本与稳定性对比
算成本不能只看吞吐。单位Token成本等于GPU小时费用除以吞吐。高并发场景下vLLM吞吐高,单位Token成本低。我按A100每小时2美元算过一笔账,并发128时vLLM每百万Token成本比TRT-LLM低20%到30%。低并发场景反过来,TRT-LLM延迟低,GPU利用率也低,单位Token成本高出一截。量化能拉低成本,TRT-LLM在H100上跑FP8的收益特别明显,vLLM的FP8支持也不错,差距在缩小。
稳定性方面我有过一些教训。vLLM社区版迭代快,新特性多,偶尔遇到显存缓慢增长或者调度器卡住。我跑过一次8小时长测,第6小时显存涨了5%左右,重启后恢复。TRT-LLM编译成engine之后运行很稳,长测没出现过类似问题。它的版本绑定太紧,升级TensorRT版本要重新编译engine,量化校准也要重做。vLLM改个pip包就能换版本,运维灵活度高。
人力成本容易被忽略。TRT-LLM部署门槛高,要懂编译、量化、并行策略调优,招人或者培养人都要时间。vLLM开箱即用,文档和社区案例多,小团队也能快速上线。我见过一些团队为了追TRT-LLM的低延迟,投入两个月调优,最后延迟降了15%,人力成本早就超过GPU省下来的钱。选型时这笔账得算进去。
4.5 典型业务场景下的框架选型建议
实时对话和低延迟客服,并发不高,延迟SLA卡得死。这种场景TensorRT-LLM更合适,首token和每token延迟都低,用户体感好。前提是团队有部署和调优能力,愿意接受编译和版本管理的麻烦。我一般建议先拿vLLM做原型,验证业务逻辑,等延迟成为瓶颈再切TRT-LLM。
高并发API服务、请求长度变化大、流量波峰波谷明显,vLLM是更稳的选择。连续批处理和显存管理让它在高并发下吞吐高、P99可控,单位Token成本低。长上下文文档问答也推荐vLLM,PagedAttention对显存友好,能撑住更长的上下文和更多并发。离线批处理任务如果请求模式固定,TRT-LLM在固定batch下效率高,可以优先考虑。
选型没有标准答案。我现在的做法是看三个维度:延迟敏感度、并发规模、团队能力。延迟敏感且并发低,选TRT-LLM。并发高且流量不可预测,选vLLM。团队精力有限,vLLM的维护成本更低。预算充足可以混合部署,低延迟链路走TRT-LLM,高吞吐链路走vLLM,用网关做分流。框架都在快速演进,今天的结果过半年可能就变了,持续评测比一次性选型更重要。
5.1 面向低延迟的优化策略
我一般先看业务对延迟的容忍度。实时对话、语音助手、代码补全,这些场景用户盯着屏幕等第一个字,首token延迟超过300毫秒体感就差了。TensorRT-LLM在这块有天然优势,我会优先考虑它。优化路径从模型量化开始,FP8或者INT8校准,把权重和激活压下去,计算量少一截。A100上跑FP8的Llama-3-8B,首token能压到150毫秒以内。量化校准需要一批代表性数据,校准集选得不好,精度掉得厉害,我踩过这个坑。
编译engine的时候我会调几个关键参数。max_batch_size设小一点,低延迟场景不需要大batch,设大了反而增加调度开销。max_input_len按业务实际输入长度来,别留太多余量。还有kernel融合,TensorRT-LLM自动做,有些自定义算子需要手动写plugin。我试过把prefill和decode阶段的注意力算子融合,每token延迟降了2毫秒左右。投机解码也能用,小模型草稿加大模型验证,延迟能再降一截,实现复杂度高,得权衡。
vLLM在低延迟场景不是不能用。把gpu_memory_utilization调高,block_size设小,调度策略改成FCFS,首token延迟能追近一些。我试过vLLM加投机解码,效果有,不如TRT-LLM稳定。低延迟优化没有银弹,硬件选择也重要。H100比A100的首token延迟低不少,预算够就上。网络延迟、tokenizer速度、前端框架这些环节也会拖后腿,别只盯着推理引擎。
5.2 面向高吞吐的优化策略
高吞吐场景我关注的是单位时间内能处理多少请求。vLLM的连续批处理是核心武器,新请求随时插入正在运行的batch。我会把max_num_seqs调大,默认256,根据显存和延迟SLA往上加。max_num_batched_tokens也要调,设小了调度器频繁切换,设大了长请求会挤占短请求。我一般从4096开始试,观察GPU利用率和P99延迟。PagedAttention让显存碎片少,KV Cache按块分配,并发数能拉高。我跑过并发256的混合负载,vLLM吞吐到TensorRT-LLM的1.3倍。
多卡部署对吞吐提升明显。张量并行切分模型权重,流水线并行切分层,两者可以组合。vLLM支持张量并行,配置简单,启动时指定tensor_parallel_size就行。TensorRT-LLM的多卡配置更复杂,需要编译时指定并行策略,调优空间大。我试过4卡A100跑70B模型,vLLM张量并行吞吐线性度不错,TRT-LLM在固定batch下效率更高,弹性差一些。量化对吞吐帮助大,FP8比FP16吞吐翻倍,精度损失可控。vLLM的FP8支持在H100上表现好,TRT-LLM的FP8更成熟。
调度策略也影响吞吐。vLLM默认的调度器偏向公平,可以改成优先处理短请求,减少长请求占用。我试过设置调度优先级,短请求延迟降了,长请求延迟涨了,看业务取舍。GPU利用率是吞吐的镜子,我习惯盯着nvidia-smi,利用率低于70%说明有优化空间。批处理大小、并发数、序列长度分布,这三个变量互相拉扯,调参要有耐心。离线批处理场景可以把batch固定,TRT-LLM效率高,vLLM也能用,吞吐差距不大。
5.3 模型部署性能对比决策矩阵
选型这件事我习惯画一个矩阵。横轴放延迟敏感度,纵轴放并发规模。低延迟低并发,TensorRT-LLM。低延迟高并发,混合部署或者咬牙上TRT-LLM加多卡。高延迟低并发,vLLM够用,运维省心。高延迟高并发,vLLM首选。团队能力也放进去,TRT-LLM需要编译、量化、调优经验,人力储备不足就选vLLM。成本维度看单位Token成本和人力成本,高并发下vLLM单位成本低,低并发下TRT-LLM延迟低但GPU利用率低,单位成本反而高。
我做过一个简化的决策表:
| 场景特征 | 推荐框架 | 理由 |
|---|---|---|
| 实时对话,并发<8 | TensorRT-LLM | 首token和每token延迟低 |
| 在线API,并发>64,流量波动大 | vLLM | 连续批处理吞吐高,P99可控 |
| 长上下文文档问答,并发16-32 | vLLM | PagedAttention显存管理好 |
| 离线批处理,请求模式固定 | TensorRT-LLM | 固定batch下单位算力效率高 |
| 团队人手少,快速上线 | vLLM | 开箱即用,社区支持好 |
| 预算充足,延迟SLA严苛 | 混合部署 | 低延迟链路TRT-LLM,高吞吐链路vLLM |
矩阵不是死的。我见过业务从低并发涨到高并发,vLLM一直没换,延迟SLA放宽了一点,成本省了不少。也见过团队为了追TRT-LLM的低延迟,投入两个月调优,最后延迟降了15%,人力成本早超过GPU省的钱。选型要算总账,别只盯一个指标。框架都在快速迭代,今天矩阵里的结论,半年后可能就变了。
5.4 未来框架演进与持续评测建议
vLLM和TensorRT-LLM的版本更新很快。vLLM社区活跃,每个月都有新特性,PagedAttention的变体、投机解码、量化支持都在进步。TensorRT-LLM跟着TensorRT和CUDA走,新硬件适配快,H100、B200上的性能提升明显。我习惯每季度跑一次基准测试,用同一套脚本、同一批模型、同样的负载。指标记录首token延迟、每token延迟、吞吐、P99、显存占用、单位Token成本。测试结果存下来做趋势对比,别靠记忆。
持续评测要自动化。我一般用locust或者wrk压测,配合Prometheus和Grafana看实时指标。测试用例覆盖低并发、高并发、长上下文、混合长度。每次框架升级或者硬件更换,跑一遍回归。我遇到过升级vLLM版本后吞吐涨了10%,也遇到过显存泄漏,跑了8小时才发现。自动化能提前发现问题,别等线上出事。
未来框架演进有两个方向我比较关注。一个是编译优化和运行时调度的融合,vLLM在尝试torch.compile,TensorRT-LLM在简化engine编译流程。另一个是异构硬件支持,NPU、TPU、推理专用芯片。选型时留好抽象层,别把业务代码绑死在某个框架的API上。我现在的做法是用OpenAI兼容接口做一层封装,底层框架可替换。这样框架升级或者切换,业务侧改动小。持续评测不是为了选出一个永远的赢家,是为了在变化中保持判断力。