大模型应用的性能指标体系——从基础设施到业务指标的层层拆解

发布时间:2026/7/19 17:17:03
大模型应用的性能指标体系——从基础设施到业务指标的层层拆解 大模型应用的性能指标体系——从基础设施到业务指标的层层拆解一、为什么传统性能指标在大模型应用中水土不服传统 Web 服务有一套成熟的性能指标体系QPS、P99 延迟、错误率、CPU/内存使用率。把这套指标直接平移到大模型应用上你会发现一个尴尬的现象所有指标都是绿的但用户体验就是差。原因在于大模型应用引入了一个传统架构中不存在的变量——Token。一个对话请求的处理时间不再由请求数决定而是由输入 Token 数 输出 Token 数决定。同样的 QPS如果用户的 Prompt 从 500 Token 增长到 2000 Token底层 GPU 的实际负载已经翻了数倍但 QPS 这个指标完全感知不到。因此大模型应用的性能指标体系必须从 Token 维度重新构建。本文提出一套从基础设施层到业务层的四层指标体系帮助团队建立对 LLM 推理服务的可观测性。二、四层指标体系的架构全景该体系自下而上划分为四个层级各层级关注的核心指标如下基础设施层监控硬件资源状态包括 GPU 利用率与显存使用率、GPU 功耗与温度、PCIe 与 NVLink 带宽以及内存使用与磁盘 I/O。推理引擎层衡量模型计算效率涵盖 TTFT首 Token 延迟、TPOT每输出 Token 延迟、Token 吞吐量、KV Cache 命中率与使用率以及队列深度与排队延迟。服务网关层保障服务稳定性与成本可控包括端到端延迟P50/P95/P99、请求成功率与错误码分布、并发连接数与活跃会话数、Token 消耗速率与成本统计以及限流触发次数与降级比例。业务效果层评估最终用户体验指标包括用户任务完成率、平均对话轮次、生成内容质量评分、单次对话成本以及用户满意度 NPS。这四层之间是层层推导的关系基础设施层的 GPU 利用率决定了推理引擎的吞吐上限推理引擎的 TTFT/TPOT 直接决定了服务网关层的端到端延迟而前三层的综合效果最终体现在业务效果层。三、推理引擎层的核心指标TTFT、TPOT 与 Token 吞吐推理引擎层是四层体系中最关键的一层因为它是性能瓶颈的策源地。三个核心指标的准确定义和监控方法如下TTFTTime To First Token从请求到达推理引擎到第一个 Token 生成完毕的时间。TTFT 主要由 Prefill 阶段的计算时间决定——输入 Tokens 越多Prefill 时间越长。对于对话式应用TTFT 决定了用户感知的响应速度。如果 TTFT 超过 2 秒用户就会开始感到明显的等待。优化方向包括减小最大输入长度、启用分块预填充Chunked Prefill、使用更激进的前缀缓存策略。TPOTTime Per Output Token每生成一个输出 Token 的平均时间等于 Decode 阶段的耗时除以输出 Token 数。TPOT 是衡量模型生成速度的指标直接决定了打字机效果的流畅度。TPOT 在 50ms 以内时用户几乎感觉不到延迟超过 100ms 时会感到卡顿超过 200ms 时体验显著恶化。Token 吞吐量tokens/s单位时间内推理引擎处理的总 Token 数输入 输出。这是 GPU 利用率的直接反映。计算公式为吞吐 并发请求数 × 平均输出 Token 数 / 平均端到端延迟三者的关系可以用一条铁律概括提高并发数能提升吞吐但会增加 TTFT排队效应和 TPOTKV Cache 竞争降低最大序列长度能改善 TTFT 和 TPOT但会限制模型的上下文能力。性能调优的本质就是在这三个指标之间寻找平衡。四、服务网关层和业务效果层的指标设计服务网关层的指标设计需要引入用户视角的端到端延迟。与推理引擎的 TTFT 不同端到端延迟还包括了网络往返、网关处理、流式传输等开销。一个实用的经验是用户感知延迟 ≈ TTFT (输出 Token 数 × TPOT) 网络 RTT × 2对于流式输出Server-Sent Events用户感知的首屏延迟基本等于 TTFT 一次 RTT而全响应时间则是上述完整公式。因此对于实时对话场景优化 TTFT 比优化 TPOT 更具用户价值。业务效果层的指标往往被技术团队忽视但它们才是性能优化的终极目标。以下是建议纳入监控的业务指标任务完成率用户发起的对话是否在指定轮次内完成了预期任务。这是衡量模型有效性的核心指标。平均对话轮次完成任务需要的平均交互次数。如果性能问题导致用户需要反复重试或澄清轮次会增加。单次对话成本每次对话消耗的 Token 数 × 模型单价。这是连接技术优化和商业价值的桥梁。/** * 大模型应用性能指标的采集与计算服务 * 同时采集推理引擎层和服务网关层的核心指标 */ Service public class LlmMetricsCollector { private final MeterRegistry meterRegistry; // TTFT 直方图区分模型和场景 private final MapString, Timer ttftTimers new ConcurrentHashMap(); // TPOT 直方图 private final MapString, Timer tpotTimers new ConcurrentHashMap(); // Token 消耗计数器 private final Counter totalInputTokens; private final Counter totalOutputTokens; private final Counter totalFailedRequests; public LlmMetricsCollector(MeterRegistry meterRegistry) { this.meterRegistry meterRegistry; this.totalInputTokens Counter.builder(llm.input.tokens) .description(累计输入 Token 数) .tag(env, production) .register(meterRegistry); this.totalOutputTokens Counter.builder(llm.output.tokens) .description(累计输出 Token 数) .tag(env, production) .register(meterRegistry); this.totalFailedRequests Counter.builder(llm.request.failed) .description(失败请求数) .register(meterRegistry); } /** * 记录一次完整的推理请求的性能指标 * * param modelId 模型标识 * param inputTokens 输入 Token 数 * param outputTokens 输出 Token 数 * param ttftMs 首 Token 延迟毫秒 * param totalMs 端到端延迟毫秒 * param success 是否成功 */ public void recordInferenceMetrics(String modelId, int inputTokens, int outputTokens, long ttftMs, long totalMs, boolean success) { // 参数校验 if (modelId null || modelId.isBlank()) { throw new IllegalArgumentException(模型标识不能为空); } if (inputTokens 0 || outputTokens 0) { throw new IllegalArgumentException(Token 数不能为负数); } // 记录 Token 消耗 totalInputTokens.increment(inputTokens); totalOutputTokens.increment(outputTokens); if (!success) { totalFailedRequests.increment(); return; } // 记录 TTFT Timer ttftTimer ttftTimers.computeIfAbsent(modelId, id - Timer.builder(llm.ttft) .tag(model, id) .description(首 Token 延迟) .publishPercentiles(0.5, 0.95, 0.99) .register(meterRegistry)); ttftTimer.record(ttftMs, TimeUnit.MILLISECONDS); // 计算并记录 TPOT每输出 Token 延迟 if (outputTokens 0 totalMs ttftMs) { long decodeTimeMs totalMs - ttftMs; double tpotMs (double) decodeTimeMs / outputTokens; Timer tpotTimer tpotTimers.computeIfAbsent(modelId, id - Timer.builder(llm.tpot) .tag(model, id) .description(每输出 Token 延迟) .publishPercentiles(0.5, 0.95, 0.99) .register(meterRegistry)); tpotTimer.record((long) tpotMs, TimeUnit.MILLISECONDS); } // 记录 Token 吞吐由 Prometheus rate 函数从 Counter 计算 // 不需要额外打点因为 Counter 已经记录了累计 Token 数 } /** * 获取当前指标摘要用于告警和 Dashboard */ public MetricsSummary getSummary() { return new MetricsSummary( totalInputTokens.count(), totalOutputTokens.count(), totalFailedRequests.count() ); } public record MetricsSummary(double inputTokens, double outputTokens, double failedRequests) {} }五、指标体系落地的关键实践与避坑指南在指标体系落地过程中有几个常见的坑需要特别关注P99 延迟的陷阱LLM 推理的延迟分布通常不是正态分布而是长尾分布。少量的长上下文请求会极大地拉高 P99。因此应该按 Token 数分段统计 P99 延迟而不是计算一个笼统的全局 P99。GPU 利用率的错觉GPU 利用率 100% 不代表推理效率最高。如果 100% 利用率下 TTFT 已经超过了业务 SLA那么满负荷反而是需要告警的信号。更合理的指标是有效 Token 吞吐 / GPU 利用率即每单位 GPU 时间产生的有用 Token 数。告警阈值的动态调整不同时间段白天 vs 夜间、不同场景客服 vs 内容生成的流量模式差异巨大。固定阈值告警会产生大量误报。建议基于历史数据的滑动窗口如过去 7 天同时段的均值 ± 2 倍标准差设定动态阈值。指标的最终价值不是展示而是驱动决策——在性能劣化时快速定位根因在容量不足时提前预警在架构演进时提供量化依据。