在部署大语言模型时,“这台服务器每秒到底能处理多少请求”看似是一个非常简单的问题,实际却比传统Web服务复杂得多。传统API或者网站后台经常使用Requests Per Second,也就是RPS,衡量服务器单位时间内能够完成多少个请求,但在大模型服务中,一个请求和另一个请求所消耗的计算资源可能完全不同。一个Prompt只有几十个Token、最终生成几十个Token的聊天请求,与一个包含数千甚至上万个输入Token、同时要求模型生成较长答案的请求,在GPU计算量、显存占用、KV Cache容量和执行时间方面都可能存在巨大差异。如果只用RPS衡量大模型性能,很容易得到一个数字,却无法真正说明GPU究竟完成了多少模型计算工作。
因此,大模型性能测试通常需要同时关注请求吞吐量和Token吞吐量。RPS更接近业务层面的处理能力,而Tokens Per Second,也就是Tokens/s或者通常所说的Token吞吐量,则更接近模型推理引擎实际处理数据的能力。除此之外,现代大模型服务还必须观察Time To First Token,也就是TTFT,以及生成阶段的Token间隔、尾部延迟和GPU显存使用情况。只有把这些指标放在一起,才能判断一台大模型服务器究竟是“请求处理得快”,还是“GPU确实能够持续处理大量Token”。
RPS衡量的是请求,不是模型工作量
Requests Per Second的基本含义是单位时间内完成的请求数量。例如,一个服务在100秒内完成了1000个请求,那么平均吞吐量就是10 RPS。对于工作量比较稳定的传统Web应用,这个指标非常实用,因为一个API请求和另一个API请求之间的计算量通常不会出现数量级差异。
大模型服务却不具备这种稳定性。假设一台服务器可以达到10 RPS,如果每个请求平均生成20个Token,那么对应的输出Token吞吐量大约只有200 Tokens/s;如果每个请求平均生成500个Token,在同样10 RPS的情况下,输出Token吞吐量就达到5000 Tokens/s。两台服务器甚至可以拥有完全相同的RPS,却承担完全不同的模型计算负载。
这里还需要纠正一个经常出现的计算错误。RPS不能简单理解为“总请求数除以所有请求响应时间之和”。如果系统同时处理大量并发请求,那么单个请求的延迟可以叠加,而系统整体吞吐量却是按照实际测试窗口内完成的请求数量计算。比如一个测试从开始到结束持续100秒,期间完成1000个请求,那么整体平均吞吐量就是10 RPS。至于每个请求平均花费多少时间,则属于延迟指标,两者不能混成一个公式。
为什么大模型更需要Token吞吐量
Token是大模型真正处理的信息单位。用户输入的Prompt会被Tokenizer转换成Token,模型随后对这些Token进行计算,并逐步生成新的Token。因此,对于大模型推理服务器,仅仅知道“每秒完成多少请求”是不够的,还需要知道这些请求到底包含多少Token。
例如,一个代码生成服务收到大量长Prompt,每个请求平均包含4000个输入Token,并生成1000个输出Token,那么服务器面对的工作量远远高于一个平均输入只有100个Token、输出只有30个Token的聊天服务。即使两个系统最终都显示10 RPS,这两个10 RPS背后的GPU负载也完全不同。
因此,在专业Benchmark中,Token吞吐量通常比单纯RPS更具有可比价值。但这里也必须注意,“Token吞吐量”本身并不是一个完全明确的指标,因为输入Token和输出Token对应的计算阶段并不相同。如果一份测试报告只写“本服务器达到10000 TPS”,却没有说明这是输入Token、输出Token还是输入输出Token总量,也没有说明Prompt长度、输出长度和并发数,那么这个数字实际上很难与另一份测试结果直接比较。
Prefill和Decode是两种完全不同的工作
理解大模型吞吐量,必须先理解Prefill和Decode两个阶段。Prefill负责处理用户输入的Prompt。当一个请求包含几千个Token时,模型需要对这些输入进行计算并建立相应的中间状态,其中KV Cache是整个推理过程的重要组成部分。这个阶段具有较高的并行性,因此GPU的计算能力通常能够得到比较充分的利用。
完成Prefill以后,模型进入Decode阶段,也就是逐步生成答案。大语言模型通常采用自回归生成方式,每产生一个新的Token,都需要以此前已经生成的内容作为上下文继续计算。因此,对于单个请求,生成过程天然具有连续性。虽然现代推理框架可以通过Continuous Batching让多个请求同时进行Decode,但一个序列自身仍然是一Token接一Token地生成。
这也是为什么“每秒处理多少Token”必须说明测试阶段。Prefill吞吐量和Decode吞吐量并不是同一种性能。一个GPU可能在处理长Prompt时表现出极高的输入Token吞吐量,但在单用户低并发的生成阶段,每秒输出Token数量却明显低于Prefill阶段。两者并不矛盾,而是由模型推理本身的计算特征决定的。
Decode阶段为什么特别容易受到显存带宽影响
很多人在分析大模型性能时,会把注意力全部放在GPU的TFLOPS上,认为计算能力越高,生成Token速度就一定越快。实际情况并没有这么简单。尤其是在Decode阶段,模型需要不断读取模型权重以及访问KV Cache,因此显存带宽、缓存访问效率和内存访问模式都可能成为重要瓶颈。
这意味着一块理论计算能力非常强的GPU,如果显存带宽、KV Cache管理或者数据访问效率没有跟上,也不一定能够达到理想的Token生成速度。相反,一些针对推理优化的GPU架构和软件栈,即使理论算力指标不是简单地高出一倍,在特定大模型和Batch条件下也可能表现出非常明显的推理性能优势。
因此,分析大模型推理性能时,不能简单地看到“GPU利用率只有80%”就认为还有20%的性能没有使用,也不能看到GPU利用率接近100%就认为系统已经达到最佳状态。GPU可能正在等待显存访问、等待其他GPU通信,也可能因为Batch规模和请求调度方式没有达到最佳状态。
TTFT比单纯TPS更能反映聊天体验
对于在线聊天机器人,用户并不只是关心模型最终每秒生成多少Token,更关心发送问题以后多久能够看到第一个字。这就是TTFT,也就是Time To First Token。
假设服务器A和服务器B都能够达到5000 Tokens/s。服务器A在200毫秒之后开始输出第一个Token,服务器B却需要等待4秒才开始输出,然后以较高速度连续生成。从整体Token吞吐量来看,两台服务器可能非常接近,但从用户体验来看,服务器A显然更加流畅。
因此,在线LLM服务不能只追求最高TPS。如果为了提高Token吞吐量而把大量请求堆进一个大型Batch,可能会导致新请求等待更长时间,最终虽然GPU的总体吞吐量提高了,用户却感觉服务变慢了。这就是大模型推理中的典型吞吐量与延迟之间的权衡。
除了TTFT,还需要观察生成阶段的Token间隔或者TPOT等指标。TTFT主要描述用户等待模型开始回答的时间,而TPOT更接近模型开始生成以后,每个Token之间需要等待多久。对于实时聊天、语音助手、代码补全等应用,这些指标往往比一个漂亮的平均TPS数字更加有实际意义。
Continuous Batching改变了传统Batch处理方式
现代大模型推理引擎的重要优化之一就是Continuous Batching,也就是连续批处理。传统静态Batch通常需要把一批请求放在一起处理,Batch中的任务完成后才能进入下一批。对于请求持续不断到达的在线大模型服务来说,这种方式很容易造成GPU资源浪费。
Continuous Batching允许推理引擎根据每个请求当前的执行状态动态调整Batch,把新的请求加入正在执行的批次,同时把已经完成的请求移出。这样可以提高GPU的整体利用效率,特别是在多用户并发场景下,可以明显改善系统的整体Token吞吐量。
但Batch并不是越大越好。随着并发请求不断增加,KV Cache占用的显存也会增加,调度复杂度和等待时间也可能上升。如果为了追求最高Token吞吐量而无限扩大Batch,最终可能牺牲TTFT和尾部延迟。因此真正优秀的大模型服务并不是简单追求一个最高TPS,而是在吞吐量、延迟、显存占用和服务稳定性之间找到合理平衡。
vLLM和TensorRT-LLM为什么会影响性能
大模型推理性能不仅由GPU决定,推理软件同样重要。像vLLM这样的推理框架针对KV Cache管理、Continuous Batching和请求调度进行了专门优化,而TensorRT-LLM则进一步针对NVIDIA GPU的软件和硬件执行路径进行优化。
因此,同一块GPU搭配不同推理框架,最终得到的Token吞吐量可能明显不同。即使使用完全相同的框架,如果模型量化方式、上下文长度、Batch Size、并发数量、GPU数量和测试方法不同,结果也可能发生很大变化。
这也是为什么比较两个大模型服务器时,仅仅比较“用了几张GPU、每张GPU多少显存”是不够的。真正有意义的Benchmark必须说明模型版本、精度或量化方式、输入Token数量、输出Token数量、并发数、Batch策略、推理框架以及软件环境,否则所谓“每秒多少Token”很容易成为一个脱离实际环境的宣传数字。
多GPU环境还要考虑通信瓶颈
当模型规模进一步扩大到单张GPU无法容纳时,就需要使用多GPU部署。此时GPU之间的数据通信会成为新的性能因素。如果采用Tensor Parallelism等模型并行方案,不同GPU需要频繁交换数据,因此GPU之间的互联带宽和通信延迟都会影响最终推理速度。
NVLink在适合的多GPU架构中能够提供高带宽GPU互联能力,而PCIe则承担GPU与CPU以及部分设备之间的数据交换。PCIe 5.0相比上一代提供了更高的理论带宽,但这并不意味着升级到PCIe 5.0以后,大模型Token吞吐量就会自动翻倍。最终性能取决于实际的数据传输量、GPU拓扑、通信模式、软件栈以及应用是否已经受到PCIe带宽限制。
因此,多GPU Benchmark除了记录GPU型号和数量,还应该记录GPU之间采用什么互联方式、实际拓扑结构以及通信性能。否则单纯比较“8张GPU”和“8张GPU”没有太大的意义。
一个真正有价值的Benchmark应该记录什么
如果要测试一台用于生产环境的大模型服务器,最基本的做法不是运行一次程序然后得到一个TPS数字,而是建立完整的性能测试矩阵。测试至少应该记录RPS、输入Token吞吐量、输出Token吞吐量、TTFT、生成阶段Token间隔、P50/P95/P99延迟、并发请求数量、平均输入长度、平均输出长度以及GPU显存和计算资源使用情况。
对于多GPU系统,还应该进一步记录GPU之间的通信情况以及KV Cache占用情况。对于不同模型,还应该固定模型版本、量化精度和上下文长度,否则不同测试结果之间没有严格的可比性。
尤其需要注意P95和P99这类尾部延迟指标。平均延迟看起来很漂亮,并不代表所有用户体验都很好。如果95%的请求都在很短时间内完成,但剩余5%的请求需要等待很长时间,那么平均值很容易掩盖真实的服务问题。对于商业化API或者大型在线应用来说,尾部延迟往往直接影响用户体验和服务等级协议。
高TPS不一定代表更好的服务器
大模型Benchmark最容易产生的误区,就是把一个最高TPS数字当成服务器性能的全部答案。假设服务器A达到10000 Tokens/s,服务器B只有6000 Tokens/s,看起来A明显更快,但如果A是在32甚至64路并发、较短输出长度和较高TTFT条件下测试,而B是在较长上下文和严格延迟要求下测试,那么两者实际上根本没有处在相同的测试条件中。
更重要的是,生产环境通常并不是单一工作负载。客服机器人、企业知识库、代码生成、长文档总结、批量数据处理和离线推理,对性能的要求完全不同。客服系统更关心TTFT、P95延迟和稳定RPS,批量文档处理则可能更加重视总Token吞吐量,而代码补全需要同时考虑上下文长度、首Token延迟和连续生成速度。
因此,大模型服务真正应该回答的问题,并不是“这台机器每秒多少Token”,而是“在指定模型、指定上下文长度、指定并发规模以及指定服务质量要求下,这台机器能够稳定完成多少请求和多少Token计算”。
RPS、Token吞吐量和延迟并不是互相竞争的三个指标,而是观察同一个推理系统的不同窗口。RPS反映业务请求层面的处理能力,输入和输出Token吞吐量反映模型计算工作的规模与效率,TTFT和TPOT则反映用户实际等待和生成体验。只有把这些指标结合起来,才能判断一套大模型推理系统究竟哪里快、哪里慢,以及GPU、显存、KV Cache、通信还是调度系统究竟是不是当前的瓶颈。
对于准备建设本地AI服务器、企业GPU集群或者商业化大模型API的人来说,这种指标体系比单纯追求一个漂亮的TPS数字更加重要。因为真正决定服务器投资回报率的,从来不是Benchmark排行榜上的最高数字,而是在真实业务负载下,它能够以多大的稳定吞吐量、多少并发请求和多低的延迟持续运行。
大模型服务如何计算真实吞吐量,Requests Per Second 与 Tokens Per Second 有什么区别
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP