拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Tokens per Second:大模型推理速度的测量与优化全解析

看到 Celeris-1 以 2158 tokens/s 的生成速度登顶 AI 推理速度排行榜时很多开发者的第一反应是这个数字到底意味着什么在真实项目中能不能复现我自己部署模型之后怎样测量并优化这个指标本篇文章不打算只停留在“谁跑得快”这个新闻层面而是围绕 tokens per second 这个核心指标从概念理解、评测方法、本地实测、影响因子、优化手段、常见误区与最佳实践几个维度展开。内容偏向工程落地适合正在做模型推理部署、性能调优、技术选型的开发同学阅读。如果你只是刚接触大模型也不要紧我会从最基础的概念讲起。1. 什么是 tokens per second为什么 AI 速度排行榜都在用它1.1 先理解 Token 的概念要理解 tokens per second首先要弄清楚 Token 是什么。大语言模型并不是按“字”或“单词”来理解文本的而是把文本切分成更小的单元这个单元就叫 Token。Tokenizer分词器会把一句话拆成若干个 Token再把 Token 映射成数字 ID 输入给模型。Token 的切分规则和语言、分词器训练方式有关。英文场景下一个常见单词可能对应 1 到 2 个 Token生僻词可能被拆成多个子词。中文场景下一个汉字在不少 Tokenizer 中会对应 1 到 2 个 Token。所以题目里说的 2158 tokens/s如果你换算成“每秒输出多少汉字”并不是直接等于 2158 个字需要结合具体 Tokenizer 的切分比例来估算。1.2 tokens per second 指标的具体含义tokens per second 描述的是模型每秒生成的 Token 数量单位写作 tokens/s。它衡量的是模型的生成速度。生成速度越快用户在对话中的等待时间就越短批量处理任务的吞吐也会越高。不过在性能评测里还需要区分两个概念单请求生成速度一个请求从开始生成到结束模型每秒生成的 Token 数。系统吞吐量在并发场景下所有请求合计每秒生成的 Token 数。排行榜中的数字既可能是单请求的速度也可能是并发压力下的吞吐要看评测方的定义。比如当 batch size 为 1 时模型每秒生成的 Token 数就是单请求速度当 batch size 很大时系统每秒生成的总 Token 数会远高于单个请求的速度因为 GPU 在同时处理多个请求。1.3 为什么速度排行榜都在用这个指标原因很简单大模型生成文本是逐个 Token 输出的Tokens per second 直接反映了“模型产出文本的速度”。无论是聊天机器人、内容生成、代码补全还是文档总结最终用户体验都和这个数字强相关。另外它也能反映推理系统的整体效率。同样的模型在不同的推理框架、不同的 GPU、不同精度下tokens/s 可能相差数倍。排行榜的意义在于给开发者一个横向参考当前硬件和优化技术下模型推理速度能够达到什么水平。但这里要提醒一句单一数字无法体现延迟分布、显存占用、成本、并发稳定性等因素。排行榜更多是“上限参考”不是“生产环境保证值”。2. 2158 tokens/s 是怎么测出来的推理性能基准的关键变量2.1 单请求测试与并发测试评测方法直接决定最终数字。如果评测方式是单请求、batch size 为 1那么测到的是模型在理想状态下的单流生成速度。这种方式实现简单适合对比模型本身和单卡推理能力。但如果评测加入了并发请求比如同时发送多个 prompt并且推理框架支持 continuous batching连续批处理那么系统吞吐量会明显提升因为 GPU 可以同时服务多条请求把空闲算力利用起来。因此当看到“2158 tokens/s”这个数字时应该先问自己几个问题是单流速度还是总吞吐并发数是多少输入 token 长度是多少输出 token 长度是多少使用的是什么 GPU、精度、推理框架这些变量只要改一个数字就可能有明显变化。2.2 硬件、精度与框架的影响硬件差异是最直观的。高端 GPU 的显存带宽更高、算力更强单 token 的计算速度更快。低端 GPU 或 CPU 推理时tokens/s 可能只有个位数甚至更低。精度设置同样重要。FP16/BF16 是常见的半精度推理格式INT8/INT4 量化可以进一步减少显存占用和计算量但也会带来一定的精度损失。评测时采用哪种精度要写清楚否则很难复现。推理框架的影响也很大。同一个模型用 Hugging Face Transformers 直接用比用 vLLM、TensorRT-LLM 等优化框架慢不少。这些框架通过算子融合、Continuous Batching、PagedAttentionvLLM 提出的显存管理技术等手段提升了 GPU 利用率吞吐量和延迟都会更好。2.3 评测工具与评测口径常见的评测方法有两种固定 prompt、固定生成长度统计生成耗时。用离线批量脚本发送一批请求统计总体吞吐。固定提示词可以排除输入长度差异带来的影响。固定生成长度可以避免模型提前结束导致 token 数不稳定。一次评测通常需要重复多轮取稳定值或平均值避免偶然波动。如果你要做对比实验建议把评测条件写成一个标准清单由几个维度组成模型名称与版本、量化精度、GPU 型号与数量、输入长度、输出长度、并发数、推理框架与版本、CUDA 版本、解码参数。这些信息一起记录跑出来的数值才有参考价值。3. 在本地环境测量模型的 tokens per second3.1 环境准备要在本地实测生成速度首先准备 Python 环境建议 Python 3.10 及以上。主要依赖包括 PyTorch、Transformers、vLLM 等。依赖安装命令如下pip install torch transformers vllm这里说明一下具体安装命令和版本会随 PyTorch、CUDA 版本变化需要根据你的机器实际情况调整。如果你的项目已经用到了 virtualenv 或 conda建议在独立环境里安装避免包冲突。硬件方面如果使用 GPU推荐显存 16GB 以上的 NVIDIA GPU可以流畅运行 7B 到 14B 级别的模型。如果是纯 CPU 环境也能跑通流程但速度会慢很多更建议换小模型测试。3.2 使用 Transformers 测量单请求生成速度下面用 Hugging Face Transformers 写一个简单的脚本测量单请求的生成速度。# 文件路径benchmark_transformers.py import time import torch from transformers import AutoModelForCausalLM, AutoTokenizer model_path your-model-path # 替换为实际模型路径例如 Qwen/Qwen2.5-7B-Instruct tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) prompt 请用三句话介绍人工智能的发展历史。 inputs tokenizer(prompt, return_tensorspt).to(model.device) max_new_tokens 512 start time.perf_counter() with torch.no_grad(): output model.generate( **inputs, max_new_tokensmax_new_tokens, do_sampleFalse, use_cacheTrue ) end time.perf_counter() generated_tokens output[0][inputs[input_ids].shape[1]:] generated_count len(generated_tokens) elapsed end - start print(f生成 token 数: {generated_count}) print(f耗时: {elapsed:.2f}s) print(f生成速度: {generated_count / elapsed:.2f} tokens/s)这段代码的思路是加载模型和分词器。torch_dtypetorch.float16表示以半精度加载能减少显存占用。构造 prompt编码成 input_ids。计算生成前后时间差时间差除以生成的新 token 数量得到每秒生成 token 数。output[0][inputs[input_ids].shape[1]:]是切片出新增生成的 token去掉输入的前缀部分。运行结果类似这样生成 token 数: 512 耗时: 8.42s 生成速度: 60.81 tokens/s如果你的机器性能不错或者模型比较小数字会更高反之会更低。这个脚本反映的是“单请求、无并发、Transformers 原生推理”下的速度通常不是最高性能的表现。3.3 使用 vLLM 测量批量吞吐vLLM 是目前比较主流的开源推理框架它通过 Continuous Batching、PagedAttention 等机制显著提升吞吐量。我们用 vLLM 测一下并发场景下的吞吐。# 文件路径benchmark_vllm.py import time from vllm import LLM, SamplingParams model_path your-model-path # 替换为实际模型路径 llm LLM( modelmodel_path, dtypefloat16, tensor_parallel_size1, gpu_memory_utilization0.9, trust_remote_codeTrue ) prompts [ 请解释什么是大语言模型。, 请写一段 Python 代码实现冒泡排序。, 请总结一篇文章的核心观点。, 请列出三种常见的模型量化方法。, ] * 20 # 构造 80 个请求 sampling_params SamplingParams( max_tokens512, temperature0.7, top_p0.9 ) start time.perf_counter() outputs llm.generate(prompts, sampling_params) end time.perf_counter() total_tokens sum(len(output.outputs[0].token_ids) for output in outputs) elapsed end - start print(f并发请求数: {len(prompts)}) print(f总生成 tokens: {total_tokens}) print(f总耗时: {elapsed:.2f}s) print(f平均吞吐: {total_tokens / elapsed:.2f} tokens/s)这段脚本里LLM负责加载模型SamplingParams负责配置解码参数。llm.generate(prompts, sampling_params)会一次性处理多个 prompt框架内部自己管理 batch。注意vLLM 不同版本的 API 可能会有差异。如果你的 vLLM 版本比较新参数名或导入方式可能有变化建议先查看对应版本的文档。vLLM 的吞吐通常比原生 Transformers 高出很多尤其在并发请求较多的情况下。这不是模型变强了而是同一块 GPU 被更充分地利用了。3.4 结果解读与对比如果你在两套脚本里跑同一个模型会发现 vLLM 的吞吐明显更高。这里要追问一句哪个数字才是“真实性能”答案是两个都真实只是评测口径不同。Transformers 脚本测的是最朴素的单请求生成能力适合调试和理解模型行为。vLLM 脚本更接近生产环境适合评估系统吞吐。实际做性能报告时要注明测试条件不要只说“我的模型每秒能生成多少 token”。另外生成的 token 数量统计需要以 tokenizer 的实际输出为准而不是简单地用“输出字符数”来推算。有些 Tokenizer 会把标点、空格也切成独立 Token直接数汉字会低估或高估结果。4. 影响 tokens per second 的关键因素4.1 模型参数量与精度模型的参数量决定了单次前向计算的计算量。7B 模型和 70B 模型在同样的 GPU 上单位时间能生成的 token 数差距会很大。参数越多每次生成一个 token 需要做的矩阵运算越多耗时自然越长。精度也会影响速度。FP16/BF16 是常见的半精度推理格式比 FP32 计算更快、显存占用更少。INT8/INT4 量化虽然会带来一定精度损失但显存占用进一步下降部分硬件上计算速度也会提升。对于显存带宽受限的解码阶段量化后的模型往往能跑出更高的 tokens/s。4.2 硬件算力与显存带宽大模型生成 token 时有一个很有意思的特点解码阶段很多算子并不完全受计算峰值限制而是受显存带宽限制。模型权重和 KV Cache 要从显存中反复读取显存带宽越高每秒能完成的 token 生成次数就越多。这也是为什么高端 GPU 在推理任务中优势明显不仅因为算力强还因为显存带宽高。如果你的 GPU 显存带宽较低即使算力数字看起来不错解码速度也可能不理想。4.3 Prefill 和 Decode 两个阶段要分开看大模型推理通常分成两个阶段Prefill预填充阶段处理输入 prompt生成 KV Cache这个阶段计算量较大耗时主要取决于输入长度。Decode解码阶段逐 token 生成输出每个 token 依赖前一个 token无法完全并行耗时主要取决于输出长度和显存带宽。如果评测时把 Prefill 时间和 Decode 时间混在一起最终 tokens/s 会被输入长度影响。比如两个请求输出长度相同一个输入 100 token一个输入 1000 token后者的 Prefill 时间更长整体速度数值就会更低。更科学的做法是把两个阶段分开统计TTFTTime To First Token首 token 延迟反映用户等待“第一个字”的时间。TPOTTime Per Output Token每输出一个 token 的耗时反映生成流畅度。4.4 批量大小与 KV Cache批量大小对吞吐影响非常大。单条请求时GPU 的算力通常没有被完全使用。把多条请求组合成一个 batch 后矩阵计算的规模更大GPU 利用率上升整体吞吐也上来了。但批量变大不是没有代价。每条请求都有自己的 KV Cachebatch 越大KV Cache 占用显存越多。显存装不下时要么降低批量要么用更小的模型要么使用类似 PagedAttention 的技术按需分配显存。4.5 解码策略的影响解码策略也会影响速度。贪心解码do_sampleFalse每次选择概率最大的 token速度快且结果确定。随机采样temperature、top_p需要做随机采样计算速度略慢。Beam Search同时维护多条候选路径生成时要多次前向计算速度明显下降。性能测试时应固定解码参数。否则不同参数下测出的 tokens/s 没有可比性。4.6 推理框架的优化能力同一个模型在原生 Transformers、vLLM、TensorRT-LLM 等框架上测试速度可能差数倍。vLLM 的核心优化包括Continuous Batching请求到达后不等待当前 batch 全部结束而是动态加入新的请求持续让 GPU 保持高利用率。PagedAttention把 KV Cache 按块管理减少显存碎片提高显存利用率。算子融合把多个小算子合并成一个大算子减少 Kernel 启动开销。TensorRT-LLM 则通过图优化、算子选择、模型编译等静态优化方式在 NVIDIA GPU 上做到较高性能。这类框架是否适合你的项目取决于部署环境、模型兼容性和工程成本。5. 提升模型推理速度的常用优化手段5.1 模型量化量化是把模型权重从 FP16 压缩到 INT8、INT4 等低精度格式从而减少显存占用和计算量。常用的量化方法有 GPTQ、AWQ、GGUF 等。量化后模型文件变小KV Cache 释放出更多显存因此可以支持更大的 batch。在显存带宽受限的场景下低精度权重读取更快tokens/s 往往会有提升。不过要注意量化带来的精度损失尤其是代码生成、数学推理等对精度敏感的任务需要先做评估再决定是否量化。5.2 使用连续批处理如果你是自建服务而不是只用离线批量脚本建议使用支持 Continuous Batching 的推理框架。传统批处理模式下一个 batch 里的请求必须全部完成后再处理下一批空闲时 GPU 算力被浪费。Continuous Batching 可以在生成间隙插入新请求进一步提高 GPU 吞吐。这个优化对在线推理服务效果最明显。如果一个请求已经生成完毕新请求可以立刻补位不需要等待整批结束。5.3 投机解码投机解码Speculative Decoding是一种“以小博大”的思路先用一个更小、更快的草稿模型生成多个候选 token再用大模型一次性验证这些 token 是否正确。如果草稿模型猜得准大模型一次前向计算就能确认多个 token从而提升单流生成速度。投机解码对硬件和任务分布有一定要求不是所有场景都能得到明显加速。但在某些模型和输入分布下可以在不损失输出质量的前提下提升 tokens/s。5.4 KV Cache 优化解码阶段需要读取历史 token 的 KV Cache。如果 KV Cache 管理不当会出现显存碎片、浪费、重复申请等问题。优化方向包括使用 PagedAttention 按块管理 KV Cache。对 KV Cache 做低精度量化减少显存占用。合理设置 max_model_len避免预留过大显存。这些优化通常集成在 vLLM 等框架中普通开发者不需要手动实现但了解原理有助于定位显存不足和速度下降问题。5.5 多卡并行与部署策略当单卡显存放不下模型或单卡算力不够时可以使用多卡并行。常见并行方式包括张量并行Tensor Parallelism把单个算子的计算拆分到多张卡上适合单模型很大但需要低延迟的场景。数据并行Data Parallelism每张卡跑一个完整模型副本适合吞吐优先的场景。流水线并行Pipeline Parallelism把模型按层拆成多段适合超大模型。并行方案会增加通信开销需要根据模型规模和硬件环境权衡。小模型强行上多卡反而可能因为通信开销导致速度下降。5.6 权衡速度不是唯一目标优化 tokens/s 的时候还要关注精度、显存、成本和稳定性。一个推理系统如果只追求峰值速度可能导致显存占用过高、并发能力下降、生成质量受损。生产环境中的性能优化本质是在多个约束条件下找平衡点。6. 常见问题与排查思路6.1 常见问题速查表问题现象常见原因解决思路实测速度远低于排行榜数字评测环境、并发数、精度、框架不同记录完整配置用同一套脚本复现不同框架测出的速度差异很大框架的批处理、KV Cache、算子优化不同根据生产场景选择框架不要跨框架比绝对值首 token 很慢Prefill 阶段输入 prompt 过长分开统计 TTFT 和 TPOT优化输入长度显存不足系统报 OOMKV Cache 或 batch 占用过多降低并发、减少 max_token、开启量化速度波动明显环境温度、GPU 频率、其他进程干扰重复多次取中位数关闭干扰服务中文输出统计不准Tokenizer 对中文切分规则不同用 token_ids 数量统计而不是字符数量化后速度不升反降部分硬件对低精度算子支持不佳用 profiling 工具定位耗时算子选择合适的量化格式6.2 排查 checklist如果你复现不出排行榜的数字我建议按以下顺序排查确认模型版本是否一致Tokenizer 是否一致。确认输入 prompt 长度、输出长度是否一致。确认 batch size、并发数是否一致。确认推理框架和版本是否一致。确认 GPU 型号、显存、精度是否一致。确认是否使用了相同的解码参数。多次测试取平均值或稳定值不要用单次峰值来对比。排行榜上的数字通常在特定的软硬件组合下才能复现。你的目标不一定是追平它而是理解自己的系统在什么条件下能达到最优性能。7. 最佳实践如何正确看待和复现速度排行榜7.1 建立自己的评测基准与其纠结排行榜的绝对数字不如搭建一套适合自己业务的评测基准。具体做法是选择 10 到 20 条有代表性的 prompt覆盖短文本、长文本、代码、中文、英文等场景固定输出长度比如 256、512、1024 token固定并发数和 batch 策略在同样的 GPU 和框架下重复运行多轮记录平均速度和 P95 延迟。这套基准可以用于对比不同模型的速度。对比不同推理框架的速度。对比不同量化方案的速度和精度。在升级硬件时评估收益。评测脚本最好纳入版本管理和代码一起维护。这样每次优化后都能快速得出可对比的数据。7.2 关注延迟分布而不是只看平均值平均 tokens/s 只能反映整体水平不能反映请求之间的波动。一个系统可能平均速度不错但部分请求因为显存不足、调度排队等原因出现明显卡顿。生产环境更应该关注P50 和 P95 的 TTFT。P50 和 P95 的 TPOT。并发请求下的吞吐稳定性。OOM 和超时次数。如果只优化平均值可能把系统推向极端状态损害大多数用户体验。7.3 速度评测之外还要关注模型合规与安全部署模型时除了性能指标还需要确认模型的使用协议、数据隐私要求和内容安全策略。不要使用来源不明、许可不明的模型和权重。推理服务上线前应做好输入输出的内容过滤和访问控制避免生成内容给业务带来风险。涉及用户数据时要遵守数据最小化原则记录日志时避免保存敏感原文。7.4 生产环境的调优顺序建议从我做过的一些推理服务优化经验来看推荐的调优顺序是先选一个合适的推理框架优先考虑 vLLM、TensorRT-LLM 等有批处理和显存优化的框架。再根据显存情况决定是否量化优先尝试 AWQ 或 GPTQ。配置合理的并发和 batch 策略观察吞吐和延迟变化。如果单卡性能不足再考虑张量并行或多卡部署。最后用完整的评测基准验收尤其关注尾延迟和错误率。这套顺序可以避免一上来就做复杂优化最后发现瓶颈根本不在模型推理而在数据加载或网络传输上。如果你也想复现类似 Celeris-1 这样的速度榜单结果建议先搭好基准测试脚本把硬件、框架、精度、prompt、并发这些变量固定下来再从单卡、单请求开始逐步加压。这样跑出来的数据无论是写技术报告还是做方案选型都会更有说服力。最后想说的是2158 tokens/s 这个数字本身会随着榜单更新被打破但“如何正确测速、如何分析瓶颈、如何优化吞吐”这套方法不会过时。手里有一套自己的基准脚本比记住任何排行榜数字都更实用。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门