
在接触大语言模型LLM推理优化、模型选型或服务化部署时很多人会遇到一个问题模型在单卡上看起来跑得很快但一旦上线给多个用户并发使用响应就变得很慢换一个推理框架后同样的模型性能差异却很大。要解释清楚这些现象不能靠“感觉”必须依赖一套统一的测试方法和量化指标这就是 LLM Inference Benchmarking。本文将梳理推理基准测试的核心概念、常用指标、主流工具和完整测试思路帮助你在模型部署前后能用数据做决策。这篇文章适合两类读者一类是刚开始接触 LLM 服务化部署想知道怎么评测推理性能的新手另一类是在实际项目里被响应延时、吞吐量、显存占用等问题困扰希望建立一套可复用评测流程的开发者。读完你会理解推理基准测试到底要测什么、怎么设计测试场景、如何用脚本压测服务以及如何避免只盯着某个单一指标而陷入优化陷阱。1. 为什么要单独讨论“LLM 推理基准测试”1.1 训练与推理的性能评估是两回事大模型领域经常提到 “Benchmark”比如模型排行榜上常见的 MMLU、GSM8K、HumanEval。很多人会把它们和推理性能测试混在一起但实际上它们解决的问题完全不同。模型能力评测Evaluation关心模型“回答得对不对”比如做数学题的正确率、代码生成能不能通过单测。这种评测需要固定权重用一批标准化测试集来打分结果体现的是模型的知识储备和泛化能力。推理性能评测Inference Benchmarking关心模型“回答得快不快、占不占资源、能不能支撑业务量”比如首字延迟多长、每秒能生成多少 Token、能支持多少并发请求、显存占用是否在可控范围内。这两种评估在模型选型阶段缺一不可。一个准确率很高的模型如果推理速度慢到无法接受即使放上生产环境也可能需要额外付出大量工程成本反过来一个推理速度很快但能力很弱的模型同样无法满足业务要求。1.2 推理基准测试要解决的典型业务问题在实际项目中推理基准测试通常在几个环节发挥作用模型选型对比同样参数量、不同架构的模型哪一个更适合部署在现有 GPU 上。推理框架选型vLLM、TensorRT-LLM、SGLang、Ollama 等框架对同一模型的加速效果差异很大只有通过测试才能做选择。硬件容量规划预计日请求量较大时需要估算单卡 QPS 能到多少、平均响应时间是否满足服务质量要求从而决定买几张 GPU。服务端参数调优比如 batch size、max-token 限制、并行度、量化精度这些参数的变化会让性能出现明显波动。线上问题排查当用户反馈模型“转圈很久”时需要区分是模型推理慢、网络开销大还是检索流程、外部 API 占用了太多时间。归根结底推理基准测试不是一项活动而是一个工程化手段用数据告诉你模型在特定软硬件条件下、特定负载形态下的真实表现。1.3 性能结果不可直接复用的原因很多人在别的博客或仓库里看到一个测速数据以为自己部署后也能同样达到结果往往达不到预期。原因在于大模型推理性能与以下变量强相关GPU 型号与显存带宽对生成式模型来说显存带宽严重影响 Token 生成速度。模型量化方式FP16、INT8、INT4 的速度和显存占用完全不同。输入和输出长度输入越长首字延迟越高输出越长单次请求总耗时越高。并发请求数并发增加时吞吐量会上升但响应延迟也可能变长。推理框架和调度策略是否有 Continuous Batching、PagedAttention 等优化直接影响吞吐量。因此推理基准测试的第一步不是寻找一个“普适数字”而是先定义清楚测试条件再在同等条件下做横向对比。2. 核心性能指标从首字延迟到吞吐量2.1 首 Token 延迟Time To First TokenTTFT首 Token 延迟指的是客户端发起请求到收到第一个生成 Token 的时间。它直接影响用户的“体感等待时间”。在交互式聊天场景中TTFT 尤其重要如果用户发送一句话后超过几秒还没有任何反馈体验会明显变差。TTFT 为什么和总延迟不同因为 LLM 解码过程分为两个阶段Prefill预填充阶段处理用户输入的 Prompt得到中间状态。输入越长这个阶段计算量越大。Decode解码阶段逐个 Token 生成输出。第一个 Token 在 Prefill 完成后才产生因此 TTFT 主要由 Prefill 耗时和调度排队时间决定。2.2 Token 生成延迟与每个输出 Token 时间Time Per Output TokenTPOTTPOT 表示生成一个输出 Token 的平均耗时。它和模型参数量、显存带宽、量化方式、Batch 大小密切相关。假设模型正在处理一个 BatchBatch 越大平均每个请求分到的算力比重就会下降TPOT 可能上升。用户侧看到的“打字机速度”通常由 TPOT 决定。如果 TPOT 是 50ms那么模型大约每秒输出 20 个 Token已经比较流畅如果 TPOT 是 200ms每秒只输出 5 个 Token用户就会感觉生成非常慢。2.3 端到端总延迟End-to-End Latency端到端总延迟 TTFT 后续生成所有 Token 的时间 网络传输时间。在测试时需要注意区分只测推理服务的指标通常以模型服务内部日志为准。测完整业务链路则包括网关、鉴权、外部工具调用、网络等。两者都值得测但解读时要分开。若完整链路慢了先排查哪个环节时间占比最高再决定优化方向。2.4 吞吐量Throughput通常用 tokens/s 表示吞吐量大体验证的指标。常见两种口径单请求吞吐量一个请求内模型每秒生成的 Token 数量等于 1000 / TPOT单位 ms 时。系统吞吐量在一段时间内模型服务处理的所有输出 Token 总量除以时间。系统吞吐量更能反映 GPU 的利用效率因为它把并发请求合在一起计算。用公式表示系统吞吐量tokens/s 总生成 Token 数 / 总耗时s如果增加并发请求单请求生成速度可能会变慢但系统吞吐量往往先上升到达饱和点后趋于平缓甚至下降。因此压测时要画出“并发数-吞吐量”曲线而不只是记录最大吞吐量。2.5 每秒请求数QPS / RPS与成功率在业务侧大家更习惯用 QPS 来描述系统能承受多高的请求量。例如某客服机器人服务需要支持 20 QPS如果模型处理一个请求平均需要 5 秒那么 20 QPS 意味着同时约有 100 个请求在排队或被处理。这个简单的换算关系经常被忽略。成功率同样重要。高并发下很容易出现请求超时、连接失败、显存溢出退出。压测时要把 99% 响应时间、超时率、错误率都记录下来单纯看平均延迟会掩盖极端情况。2.6 显存占用与设备利用率显存占用决定模型能否在一张卡上跑起来。同一个模型使用不同的推理框架、不同量化方式显存占用可能差距很大。除了模型权重本身KV Cache、中间计算图、框架运行时也会占显存。高并发下 KV Cache 增长很快如果超过显存上限会出现 OOM 或请求排队。设备利用率主要看 GPU 算力利用率和显存带宽利用率。通过nvidia-smi、nvtop或 NVIDIA DCGM 可以观测。2.7 成本指标每 Token 成本在云上部署时成本是一个不可回避的指标。成本可以表示为单位时间 GPU 租用成本 / 系统吞吐量得到“每个 Token 的成本”。如果是按 GPU 实例小时计费先估算处理一百万 Token 需要多少小时。这样你就能用一个可量化的方式回答“换一个更大的模型是否划算”这类问题。3. 评测对象与测试工具选型3.1 评测对象模型、框架、硬件如何拆解一次推理基准测试可以只测“模型 框架”的表现也可以测“模型 框架 硬件”的整体方案。建议先把变量拆开模型权重版本含量化方式 推理框架vLLM / TensorRT-LLM / SGLang / llama.cpp / Ollama 框架参数max batch、并发、KV Cache策略、调度策略 硬件环境GPU型号、驱动、CUDA版本 负载模型Prompt长度、输出长度、并发模式 → 性能指标做横向对比时至少保证硬件一致、负载一致然后只改一个变量例如框架或量化精度。否则得到的结果很难说明问题是出在框架、模型还是硬件。3.2 主流推理框架概览开源社区里常见的推理框架各有侧重点vLLM使用 PagedAttention 和 Continuous Batching吞吐量高提供 OpenAI 兼容 API部署方便是目前最流行的自托管推理服务之一。TensorRT-LLMNVIDIA 推出的推理优化框架把模型编译成 TensorRT Engine能达到很强的延迟和吞吐优化但构建流程相对复杂需要处理 Graph 优化、算子融合、KV Cache 参数配置等。SGLang主打复杂结构化输出和高效调度在多轮对话、并行采样方面有优化。llama.cpp以 CPU/GPU 混合推理和量化支持为特色适合本地运行、边缘设备或在显存受限环境测试。Ollama把模型运行封装成非常简单的命令适合个人开发环境快速试玩但要做深度性能调优时参数灵活性不如 vLLM 这类专业推理框架。框架选择要看部署目标。如果是做企业内部高并发服务一般会选 vLLM、TensorRT-LLM 或云厂商托管推理服务如果是个人电脑上搭建知识库、跑完演示Ollama、llama.cpp 更轻量。不同框架的适合场景不同因此基准测试的脚本也应当尽量贴合部署方式。3.3 自动评测工具从生成式指标到稳定性记录除了自己写脚本模拟请求也可以借助已有工具lm-evaluation-harness更多是做模型能力评测如跑 MMLU、GSM8K 等数据集但它也要求模型服务具备很高的吞吐能力能间接反映框架的稳定程度。vLLM 自带的 Benchmark 脚本benchmark_serving.py等脚本已经封装了常用拍平过程支持固定的请求数量和并发模式适合快速摸底。负载压测工具如 Locust、k6、wrk 等用于模拟 HTTP 并发。如果模型服务提供 OpenAI 兼容接口也可以用这些通用工具直接打请求。自建压测脚本最灵活可以根据业务日志构造请求分布并对结果做详细统计。需要提醒的是不要只依赖某一类工具。工具给的是理想场景下的测试结果并不能替代基于真实业务请求形态的压测。4. 环境准备与测试设计4.1 基础设施准备在进行推理基准测试前建议先搭建一套干净的测试环境准备一台 GPU 服务器记录 GPU 型号、驱动版本、CUDA 版本。安装 Python 虚拟环境避免依赖冲突。准备自己的模型权重或使用 Hugging Face 上可下载的开源模型。安装目标推理框架按照官方文档部署。示例环境说明如下具体版本需要根据自己的环境调整操作系统LinuxUbuntu 22.04 GPUNVIDIA A100 / RTX 4090 等按实际环境为准 驱动NVIDIA Driver 最新稳定版与 CUDA 工具包 Python3.10 模型示例Qwen/Qwen2.5-7B-Instruct开源权重 推理框架vLLM 压测工具Python requests concurrent.futures版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。4.2 用 vLLM 启动一个模型服务如果已经安装好 vLLM可以执行下面的命令启动一个 OpenAI 兼容的服务# 需要注意模型名称需要替换成你实际准备使用的模型权重路径或模型 ID vllm serve Qwen/Qwen2.5-7B-Instruct \ --served-model-name qwen-demo \ --tensor-parallel-size 1 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9常用参数含义--served-model-name对外暴露的模型名称后续请求时用到。--tensor-parallel-size使用几张 GPU 做张量并行单卡场景通常设置 1。--max-model-len模型最大上下文长度包含输入和输出。超过这个限制的请求会被拒绝。--gpu-memory-utilization允许框架使用的显存比例。剩余显存一般预留给 KV Cache设太高可能因显存不足而启动失败。启动后服务默认监听http://localhost:8000可以用 curl 做一次简单验证curl http://localhost:8000/v1/models如果返回模型列表说明服务启动成功。4.3 明确测试边界单包测试还是服务压测基准测试可以先从两个层级进行单请求性能摸底发一个请求记录 TTFT、TPOT、总延迟和生成 Token 数。这适合验证模型服务是否正常工作也适合对比不同量化方式带来的速度差异。并发压测同时发送多个请求观察吞吐量和延迟变化。这更贴近生产环境。建议先做单请求摸底再逐步增加并发防止一上来就因为并发导致框架配置问题和服务崩溃交织在一起难以排查。5. 自建并发压测脚本从零记录关键指标下面给出一套可以运行的最小压测脚本。它不依赖复杂测试库只依赖 Python 标准库与requests。5.1 安装依赖pip install requests5.2 Python 压测脚本# 文件路径benchmark_inference.py import json import time import requests import statistics from concurrent.futures import ThreadPoolExecutor, as_completed API_URL http://localhost:8000/v1/chat/completions MODEL_NAME qwen-demo requests_payload { model: MODEL_NAME, messages: [ {role: user, content: 请用 200 字介绍大语言模型推理优化的基本思路。} ], max_tokens: 200, temperature: 0.0 } CONCURRENCY 10 TOTAL_REQUESTS 50 def send_one_request(_): ttft None first_token_time None # 记录请求级指标 payload json.loads(json.dumps(requests_payload)) start time.time() response requests.post(API_URL, jsonpayload, timeout180) # 在这里通过 SSE 解析首字延迟比较复杂 # 我们先记录端到端延迟与返回 Token 数量。 # 若要精确测量 TTFT需要使用 streamTrue 并逐行处理响应内容。 end time.time() if response.status_code ! 200: return { ok: False, latency: end - start, error: response.text[:200], } data response.json() output_text data[choices][0][message][content] usage data.get(usage, {}) completion_tokens usage.get(completion_tokens, len(output_text)) total_latency end - start return { ok: True, latency: total_latency, completion_tokens: completion_tokens, tps: completion_tokens / total_latency if total_latency 0 else 0, } def run_benchmark(): success_cases [] error_cases [] with ThreadPoolExecutor(max_workersCONCURRENCY) as executor: future_map {executor.submit(send_one_request, i): i for i in range(TOTAL_REQUESTS)} for future in as_completed(future_map): try: result future.result() except Exception as exc: error_cases.append(str(exc)) continue if result[ok]: success_cases.append(result) else: error_cases.append(result[error]) if success_cases: latencies [item[latency] for item in success_cases] tps_list [item[tps] for item in success_cases] total_tokens sum(item[completion_tokens] for item in success_cases) total_time sum(latencies) # 这里需要区分如果所有请求是并行发出的系统吞吐量更合理的算法是 # total_tokens / wall_time但由于 ThreadPoolExecutor 的调度 # 更精确做法是记录全局开始和结束时间。为了演示采用请求耗时之和估算。 print( Benchmark Result ) print(f总请求数: {TOTAL_REQUESTS}) print(f成功请求数: {len(success_cases)}) print(f失败请求数: {len(error_cases)}) print(f平均端到端延迟: {statistics.mean(latencies):.2f}s) print(fP95 端到端延迟: {sorted(latencies)[int(len(latencies) * 0.95) - 1]:.2f}s) print(f平均单请求 Token 生成速度: {statistics.mean(tps_list):.2f} tokens/s) print(f估算系统吞吐量: {total_tokens / total_time if total_time else 0:.2f} tokens/s) else: print(没有成功请求请检查服务状态。) if __name__ __main__: run_benchmark()这段脚本只是一个起点它有几个明显的简化没有精确测量 TTFT。精确测量 TTFT 需要把请求设为流式响应逐行读取 SSE 数据记录第一个 token 出现的时间。系统吞吐量的计算方式不够严谨。并发请求并不是从同一时刻开始严谨做法需要记录全局开始时间与结束时间。没有对输入不同长度进行细分。所以实际做基准测试时你需要把这段脚本继续升级。5.3 带全局时间统计的改进版我们可以用更严谨的方式统计全局耗时并加上流式模式下的 TTFT 测量片段# 文件路径benchmark_streaming.py import json import time import requests import statistics from concurrent.futures import ThreadPoolExecutor, as_completed API_URL http://localhost:8000/v1/chat/completions MODEL_NAME qwen-demo STREAM_PAYLOAD { model: MODEL_NAME, messages: [ {role: user, content: 请列出 5 条提高后端服务稳定性的建议每条一句话。} ], max_tokens: 300, temperature: 0.0, stream: True, } def measure_single_stream(_): start time.time() ttft None first_token_time None streamed_text with requests.post(API_URL, jsonSTREAM_PAYLOAD, streamTrue, timeout180) as resp: if resp.status_code ! 200: return {ok: False} for line in resp.iter_lines(): if not line: continue line line.decode(utf-8) if not line.startswith(data:): continue data_str line[len(data:):].strip() if data_str [DONE]: break try: chunk json.loads(data_str) delta chunk[choices][0].get(delta, {}) token_content delta.get(content, ) if token_content: if ttft is None: ttft time.time() - start streamed_text token_content except json.JSONDecodeError: continue end_total time.time() total_latency end_total - start completion_tokens_estimate len(streamed_text) return { ok: True, ttft: ttft, total_latency: total_latency, completion_tokens: completion_tokens_estimate, } def main(): wall_start time.time() results [] with ThreadPoolExecutor(max_workers5) as executor: futures [executor.submit(measure_single_stream, i) for i in range(20)] for future in as_completed(futures): r future.result() if r[ok]: results.append(r) wall_end time.time() if results: ttfts [r[ttft] for r in results if r[ttft] is not None] latencies [r[total_latency] for r in results] total_tokens sum(r[completion_tokens] for r in results) print(f成功: {len(results)}) print(f平均 TTFT: {statistics.mean(ttfts):.2f}s) print(f平均总延迟: {statistics.mean(latencies):.2f}s) print(f墙钟耗时: {wall_end - wall_start:.2f}s) print(f实际系统吞吐量估算: {total_tokens / (wall_end - wall_start):.2f} tokens/s) else: print(没有成功结果。) if __name__ __main__: main()这里有一个需要留意的地方用len(streamed_text)来估算 Token 数并不准确因为一个 Token 可能对应多个字符。更稳妥的做法的让服务端返回 usage 信息或者在离线脚本里用分词器计算实际 token 数。如果要得到精确指标建议从服务端日志中获取真实 token 数或者把流式响应的usage字段捕获下来。6. 准确率评测与推理速度评测要分开6.1 推理性能测试不关注回答质量在压测阶段我们不关心模型回答得是否合理只关心在规定时间内能不能返回内容。为了让压测更稳定可以把模型的temperature设为 0并固定一个较长的max_tokens以避免因输出太长导致测试过程不可控。但如果要做模型选型还需要单独跑一轮“能力评测”。目前开源社区使用较广的是lm-evaluation-harness它支持 MMLU、GSM8K、BBH、HumanEval 等数据集。运行方式类似# 这是示意命令实际参数和数据集名称请以官方文档为准 lm_eval --model hf \ --model_args pretrainedQwen/Qwen2.5-7B-Instruct \ --tasks mmlu \ --num_fewshot 5 \ --batch_size auto注意lm-evaluation-harness在跑复杂任务时会给模型服务带来很大的计算压力也可以把它看作一种特殊的压力测试但它返回的核心指标还是准确率而不是性能指标。6.2 业务评测集需要按场景自建公开数据集只能反映通用能力。实际业务建议构造一套私有评测集包含真实用户问题、边界情况、长文本输入、指令干扰等。比如客服场景需要整理典型问法、相似问法、超长上下文、空输入等。只有用贴近线上请求的输入文本测试吞吐和延迟才有参考价值。7. 结果解读与常见误区7.1 不要只盯着“每秒生成 Token 数”在很多框架的 README 中你会看到类似“比 XX 框架快 2 倍”的宣传。但这些数字是在特定并发、特定输入输出长度、特定硬件上测出来的。实际业务中如果输入长度很长Prefill 耗时可能成为瓶颈如果输出长度很短Decode 阶段的优化效果又不明显。因此要读懂数据背后的测试条件。7.2 TTFT 与 TPOT 之间存在折中增加并发能提高 GPU 利用率和系统吞吐量但请求排队时间增加TTFT 会明显上升同时由于 Batch 变大TPOT 也可能变长。这就是延迟和吞吐量的经典折中。在生产系统设计中需要通过压测找到“最大可接受 TTFT”对应的并发上限而不是无限追求吞吐量。7.3 平均延迟会掩盖长尾问题压测结果要重点关注 P95、P99 延迟。平均值平滑了异常情况。如果 P99 延迟远大于 P95说明系统在极端并发或长文本请求下可能不稳定需要进一步观察是否发生了 CPU 调度抖动、显存峰值、垃圾回收或模型服务排队。7.4 长时间运行与短时间突发的差异有些问题只有在持续压测半小时以上才会出现例如内存泄漏、显存碎片化、连接句柄耗尽。因此建议把短时间压测和长时间稳定性测试结合起来。测试类型建议时长观察重点冒烟测试1-2 分钟服务是否能处理请求基本指标是否正常常规压测10-30 分钟不同并发下的吞吐、延迟、错误率稳定性测试数小时显存趋势、错误率、是否出现 OOM、响应延迟是否逐渐劣化8. 常见问题与排查思路下表总结了推理基准测试过程中最常遇到的问题。问题现象常见原因解决思路请求返回 429 或超时并发超过推理服务能承受的上限查看服务日志降低并发如果确认硬件充足调整 batch 策略或 max-num-seqs 等参数CUDA Out Of Memory显存不足以容纳模型权重 KV Cache 并发请求减小并发、降低 max-model-len、启用更低的量化精度、调整 gpu-memory-utilization首次请求很慢后续变快模型权重尚未完全加载到显存或经历了首次算子编译测试前先进行 warm-up 请求通常建议先发 2-3 个请求后再记录指标压测结果不稳定波动很大输入输出 token 长度不一致固定输入模板和 max_tokens测量时要记录实际输入/输出 token 数单请求速度正常并发后吞吐不升反降可能触达显存/CPU 瓶颈或调度开销过大绘制并发与吞吐量曲线观察 GPU 利用率、显存带宽利用率和 CPU 占用流式返回首 token 很慢但总耗时可接受Prefill 阶段过长或请求排队检查输入文本长度尝试使用前缀缓存或减少无关 system 提示词测试结果在不同轮次有差异环境存在共享资源、热温差异固定 GPU 频率、关闭其他任务多次重复取中位数或最小值8.1 解决“输出内容长度不一致导致指标失真”最直接的方式是在请求中固定max_tokens并设置temperature0同时用一个稳定的输入文本。但即使这样模型输出的实际 Token 数也可能不同因为它可能在达到max_tokens之前就遇到了结束标记。更规范的指标计算方式是记录服务端usage中的prompt_tokens和completion_tokens再结合耗时计算速度。如果使用流式输出SSE 事件最后一般会带usage字段如果没有可以通过后端日志或者用分词器对输入输出文本做精确统计。8.2 解决“框架参数不知道从何调起”不同推理框架的可调参数差异较大。以 vLLM 为例常见的参数包括--max-num-seqs最大并发序列数。增大它通常可以提升吞吐量但会增加显存压力。--max-num-batched-tokens每次前向计算最多处理的 Token 数。--enable-prefix-caching如果系统有大量相似前缀可以开启前缀缓存来降低 TTFT。--quantization指定量化方式例如 awq、gptq、fp8。调整参数时建议每次只调一个参数并重新执行完整压测用表格记录参数与结果之间的关系避免变量混杂。9. 最佳实践搭一套可持续运行的基准测试流程9.1 把你的测试场景做成固定资产把压测脚本、模型权重版本、框架版本、参数、请求负载、测试结果都记录在同一个目录或 Git 仓库中形成一套可回归的测试资产。比如llm-benchmark-project/ ├── configs/ │ ├── model-a.yaml │ └── model-b.yaml ├── datasets/ │ ├── real_query_sample.jsonl │ └── synthetic_query_sample.jsonl ├── scripts/ │ ├── start_server.sh │ ├── run_benchmark.py │ └── analyze_results.py ├── results/ │ ├── 2025-01-01_vllm_qwen-7b.json │ └── 2025-01-02_tensorrt-llm_qwen-7b.json └── README.md这样做的好处是当框架升级、模型升级或硬件更换时可以重新运行同一套测试对比版本间的性能变化。9.2 测试数据尽量贴近真实负载真实负载不只是请求内容还包括Prompt 长度分布短问题与长文档可能混合出现。输出长度分布客服答复通常较短代码生成或长文写作通常较长。并发到达曲线存在高峰期和低峰期。线上没有积累日志时可以先构造一个初始数据集上线后再用真实访问日志迭代。9.3 记录环境信息保证可复现在每次运行压测前建议把以下信息写入结果文件的元数据{ gpu: NVIDIA A100 80G, cuda: 12.2, framework: vllm, framework_version: 0.x.x, model: Qwen/Qwen2.5-7B-Instruct, quantization: None, tensor_parallel_size: 1, max_model_len: 8192, concurrency: 20, dataset: real_query_sample.jsonl }没有这些信息后人可能无法理解为什么同一份报告里的数字在别的环境复现不出来。9.4 权限与生产变更安全如果你需要在一个已经服务于线上流量的 GPU 服务器上做压测务必先确认这台机器的资源是否可用最好在独立环境执行测试。如果必须复用线上环境建议在测试前通过监控系统记录基准 GPU 利用率、显存使用率、网络延迟。压测从低并发开始逐步提升不要直接使用过高并发。不要在业务高峰期做占用型压测。压测结束后确认显存释放、服务恢复稳定避免影响线上业务。9.5 不要忽略峰值显存监控压测过程中要持续监控显存变化。使用nvidia-smi的间隔采样可以简单做到nvidia-smi --query-gputimestamp,memory.used,utilization.gpu,power.draw --formatcsv -l 1 gpu_monitor.csv压测结束后查看显存是否在请求结束后回落到基线。如果显存持续增长说明可能存在 KV Cache 释放不及时或内存泄漏。9.6 理性看待“最快框架”的结论技术发展很快推理框架每几个月就可能发布明显优化。不建议在没有做实测的情况下长期绑定某个框架。每次引入新框架或新版本前用同一套基准测试跑一遍量化性能提升是否值得迁移成本。10. 总结与后续学习方向通过本文你应该已经掌握了一套完整的 LLM 推理基准测试框架理解了核心性能指标的含义知道了为什么 TTFT 和 TPOT 会被业务对延迟的感知影响也清楚了测试结果与模型、框架、硬件、负载模型之间的强耦合关系。从实操角度你也学会了如何用 vLLM 启动一个模型服务并用 Python 脚本发起单请求与并发压测同时记录了延迟、吞吐量和显存监控方法。接下来可以按照下面的顺序继续深入完善自己的压测脚本在流式模式下精确统计 TTFT、TPOT。使用lm-evaluation-harness跑一轮能力评测和能力型结果一起形成选型报告。尝试换不同量化方式对比 FP16、AWQ、GPTQ、FP8 的性能变化。对框架参数做 Grid Search比如max-num-seqs从 16 调到 256观察吞吐量和延迟的拐点。进一步学习 Continuous Batching、PagedAttention、Prefix Caching、投机采样这些推理优化概念从而解释你在压测中观察到的现象。推理性能优化最忌讳拍脑袋。把测试脚本、负载数据和结果分析沉淀成一套持续运行的基准测试流程后续每次模型升级、框架切换或硬件扩容都会有一份客观依据这比临时手忙脚乱地调参要可靠得多。建议现在就从一个简单的模型服务开始跑通最小压测脚本再逐步丰富你的测试数据集和并发模式。