推理延迟与吞吐的数学权衡Pareto 边界上的最优 Batch Size 搜索一、在延迟和吞吐之间——不存在又快又多的可能推理系统中存在一条无形的性能边界延迟与吞吐的 Pareto 前沿。你可以在前沿上的任何点运行慢但吞吐高或快但吞吐低但无法同时突破这两个维度。这条边界的形状由三个物理因素决定GPU SM 利用率曲线、显存带宽的饱和点、以及 KV Cache Block 的并发容量。理解 Pareto 边界的意义不是去打破它而是根据业务的延迟 SLA 在边界上找到最优运行点——即在满足 P99 延迟约束的前提下最大化吞吐。这本质上是一个约束优化问题max(Throughput) subject to TPOT P99 40ms。二、延迟-吞吐 Pareto 边界的物理根源flowchart LR subgraph Single_Request[单请求 Forward Pass] A1[KV Cache Pre-fillbr/GPU 利用率: 80~95%br/(计算密集型)] A2[Auto-regressive Decodebr/GPU 利用率: 5~15%br/(显存带宽密集型)] end subgraph Batched[Batched 推理] B1[Batch1br/Decode 阶段 SM 空转br/等待 HBM 数据] B2[Batch8br/多请求交织计算br/SM 利用率提升至 30%] B3[Batch32br/SM 利用率 ~60%br/但每请求 TPOT 同步增长] B4[Batch128br/SM 利用率 ~85%br/接近计算上限br/但单请求 TPOT 劣化显著] end B1 -- D1[延迟最低 (TPOT15ms)br/吞吐最低 (800 Token/s)] B2 -- D2[均衡点 (TPOT18ms)br/吞吐 (5200 Token/s)] B3 -- D3[高吞吐 (TPOT25ms)br/吞吐 (12000 Token/s)] B4 -- D4[吞吐极限 (TPOT45ms)br/吞吐 (18000 Token/s)] D1 D2 D3 D4 -- E[Pareto 前沿br/• 每个点都是最优不可同时改进两个维度br/• 选点取决于业务的延迟 SLA]三、在延迟 SLO 约束下搜索最优配置import numpy as np from dataclasses import dataclass dataclass class InferenceConfig: batch_size: int max_num_seqs: int tensor_para_size: int def search_optimal_config( target_qps: float, max_tpot_p99_ms: float 40.0, max_ttft_p99_ms: float 2000.0 ) - InferenceConfig: 在给定的延迟 SLO 约束下搜索最大化吞吐的推理配置。 基于实测数据拟合的性能曲线——而非基于解析公式的理论值。 # 实测性能曲线H100 × 8, LLaMA-3.1-70B, BF16 # 数据来源于基准测试数据库此处为函数拟合值 batch_sizes [1, 2, 4, 8, 16, 32, 64, 128] tpot_p50 [15.2, 15.8, 16.5, 18.1, 21.3, 26.8, 35.2, 48.6] # ms tpot_p99 [22.1, 23.4, 25.1, 28.7, 34.5, 44.2, 58.3, 82.1] # ms throughput [0.8, 1.5, 2.9, 5.2, 9.1, 14.3, 19.8, 24.1] # K Token/s # 找到满足 P99 延迟约束的最大 Batch Size valid_configs [] for i, bs in enumerate(batch_sizes): if tpot_p99[i] max_tpot_p99_ms: valid_configs.append({ batch_size: bs, tpot_p99: tpot_p99[i], throughput: throughput[i], can_meet_qps: throughput[i] target_qps / 1000, # 转换为 K/s }) if not valid_configs: raise ValueError(无配置满足 P99 %dms 的 SLO 约束 % max_tpot_p99_ms) # 在满足 SLO 的配置中选择吞吐量最高的 best max(valid_configs, keylambda c: c[throughput]) # 根据 Batch Size 推导 vLLM 的 max-num-seqs max_seqs best[batch_size] * 2 # headroom 系数 return InferenceConfig( batch_sizebest[batch_size], max_num_seqsmax_seqs, tensor_para_size8 # 70B on H100 × 8 ) # 示例: 交互式聊天的典型约束 cfg search_optimal_config( target_qps15.0, # 15 请求/秒 max_tpot_p99_ms40.0, # Token 延迟 P99 40ms ) # 输出: batch_size16, max_num_seqs32四、Pareto 前沿移动的技术手段投机解码Speculative Decoding在不改变主模型 Forward Pass 延迟的情况下将有效 TPOT 降低 40%~60%原 25ms → 实际感知 12ms。这意味着相同的延迟 SLO 下可以增大 Batch Size从 16 → 32吞吐提升 60%~80%。Prefill-Decode 分离Disaggregated Serving将 Pre-fill 和 Decode 部署在不同的 GPU 组上。Prefill 节点使用大 Batch Size 加速 TTFT计算密集型受益于大 BatchDecode 节点使用小 Batch Size 降低 TPOT带宽密集型大 Batch 无益。这一架构将两个阶段的 Pareto 边界解耦整体延迟-吞吐前沿向外推移。FP8 量化H100 的 FP8 Tensor Core 吞吐是 BF16 的 2 倍624 vs 312 TFLOPS。将权重和 KV Cache 量化到 FP8 后相同延迟下的有效吞吐翻倍——这相当于整条 Pareto 边界向右移动了 2 倍。五、总结推理延迟与吞吐的 Pareto 前沿是由 GPU 架构的物理参数决定的不可违背的约束。核心公式Batch Size 增大 → SM 利用率升吞吐升→ 每请求计算量稀释TPOT 升→ TPOT 超过延迟 SLO 时即为可行性边界。最优 Batch Size 是在延迟 SLO 约束下的最大吞吐点——而非纯粹的最大吞吐或最小延迟点。生产优化策略基准测试绘制完整的 Pareto 前沿batch_size: 1~128在 SLO 约束下选择最优 Batch Size通过投机解码和 FP8 量化将整体边界向外移动。最关键的一点延迟 SLO 必须是由用户体验研究定义的而非工程师武断设定的——25ms 和 40ms 的 TPOT 在用户感知中的差异需要通过 A/B 测试验证而非通过直觉判断。