想象你是一家即将开业的餐厅老板。别人看到的是一张菜单,而你焦心的是一组数字:每天会有多少客人走进来?午市和晚市会不会挤爆?后厨的灶台和厨师够不够用?多雇了厨师怕闲,少雇了又怕客人排队骂娘。这份厨房规划,本质上就是一次「容量规划」——而推理服务的容量规划,和开餐厅惊人地相似。 一个 AI 推理服务,就是一座数字餐厅:请求是客人,GPU 是灶台,模型是菜谱,QPS 是每秒进门的客流。容量规划要回答的问题只有两个:高峰期需要多少灶台(容量),以及如何让灶台在空闲时不浪费(弹性)。回答错了,要么服务超时被用户投诉,要么 GPU 空转烧钱。本文用「厨房经营手记」这条线索,带你从客流量预测、厨师出菜速度、灶台配置,一路走到排班表和月末复盘,完整掌握推理服务容量规划的六步方法。

岗位关联

学会推理服务容量规划,你就能在性能与成本之间精准拿捏,成为一个既能扛住流量洪峰、又不让 GPU 空转的云架构师。

目录
  1. 可视化演示
  2. 需求分析预测
  3. 性能基线测试
  4. GPU资源度量
  5. QPS容量模型
  6. 弹性伸缩策略
  7. 运维调优实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示最大池化与平均池化的运算过程,观察池化窗口如何对输入特征图进行下采样以减少空间维度。

本节配有交互动效(进入视口后自动加载,约 3KB)。

最大池化操作 池化窗口在输入特征图上滑动,选取每个窗口内的最大值作为输出 下采样减少空间维度,保留最显著的特征信息,降低计算量 out = max(I[2i:2i+2, 2j:2j+2])

需求分析预测

开餐厅之前,老板会在门口蹲一个星期,把每天的客流记下来:周一到周五几点有人、周末比平时多几成、对面写字楼入驻后中午会不会翻倍。没有这些数字,后厨的灶台要么不够用,要么闲着吃灰。推理服务的容量规划,第一步同样不是买 GPU,而是画出「客流天气预报图」。

推理服务里的「客流」就是每秒到达的请求数,业界叫 QPS(Queries Per Second)。线上网关和负载均衡器会记录所有历史请求,打开监控大盘,你能看到一条像心电图一样的流量曲线:白天高、凌晨低、大促时突然窜出尖峰。这些历史数据加上产品侧的预期,是容量规划的第一份输入。

实际操作中,我们会把历史 QPS 按天聚合,算出日均值,再乘以两个系数:业务增长系数来自季度目标或新客户接入计划,比如月增 8%、6 个月后就是 (1+0.08)^6≈1.59;高峰波动系数来自历史观测,比如一年中最忙的一天达到日常的 3 倍。两者相乘,就得到未来峰值 QPS 的预估值。

Qpeak=Qavg×(1+r)m×fspike\displaystyle Q_{peak} = Q_{avg} \times (1 + r)^m \times f_{spike}

1. Q_avg 历史日均基线:取过去 30 天线上请求量的平均值,作为预测的起点

Qavg\displaystyle Q_{avg}

2. r 月增长率:业务侧给出的预期月增长,如 8%,代表需求的长期趋势

r\displaystyle r

3. m 预测月数:本次容量规划面向的未来时间跨度,单位是月

m\displaystyle m

4. f_spike 高峰波动系数:历史最高峰与日均值的比值,代表需求的尖刺程度

fspike\displaystyle f_{spike}

有了这张「流量天气预报图」,你才知道下个月的午市要不要加灶。记住,预测不是算命,而是用历史规律和业务信号把不确定性框在一个区间里——后面所有扩容策略,都建立在这个起点上。

性能基线测试

客流摸清了,再看自家的手艺。厨师一小时能颠多少道菜、蒸锅一次能出几笼,决定了同一时刻能接待多少桌。餐厅老板会在试菜日让厨师火力全开,记下每道菜的单位时间产量,这就是「性能基线」。

推理服务的性能基线来自压测。把写好的推理服务部署到一台 GPU 上,用压测工具(wrk、k6、locust)按不同并发数发请求,观测两个数字:吞吐量(QPS)和延迟(P50/P99)。P99 的意思是 99% 的请求都能在这个时间内返回,它代表最差的那批客人的体验。

压测结果通常呈现「先升后平」的曲线:并发太低,GPU 闲着,吞吐上不去;并发升高,吞吐跟着涨;到了某个临界点,吞吐不再增加,延迟却快速飙升——因为请求开始排队了。这个拐点的数值,就是单副本的容量锚点。吞吐、延迟、并发三者之间有一个经典关系式,叫 Little 定律:

T=CLavg\displaystyle T = \frac{C}{L_{avg}}

1. C 并发请求数:同一时刻正在被 GPU 处理或排队等待的请求数量

C\displaystyle C

2. L_avg 平均响应时间:单个请求从进入服务到返回结果的平均耗时,单位是秒

Lavg\displaystyle L_{avg}

3. T 吞吐量:系统每秒能处理完的请求数,也就是 QPS

T\displaystyle T

就像试菜日记录「一口灶一小时出 30 道菜」,压测记录的是「一张卡在目标延迟内能扛多少 QPS」。这份成绩单直接决定后面要买几块 GPU——压测数据不准,一切容量计算都是空中楼阁。

GPU资源度量

后厨的灶台有两个指标:能放几口锅,是容量;火有多旺,是功率。GPU 也有两个对应维度:显存容量和算力。菜谱再高级,锅放不下也白搭;锅放得下,火不够旺,客人还是得等。

先看显存。部署一个大模型时,显存占用主要来自三块:模型权重、激活值、KV Cache。权重占用的计算很简单:参数量乘以每个参数占的字节数。以 70 亿参数的模型为例,用 FP16 存储,2 字节一个参数,权重就要约 14GB。激活值随批大小变化,而 KV Cache 随并发请求数和序列长度线性增长,是推理场景特有的「隐形吃货」。如果模型大到一张卡放不下,还需要模型分片(张量并行、流水线并行),把权重切到多张卡上协同计算。

算力方面,单次前向推理的算力消耗约为 2×参数量×生成的 token 数(FLOPs 量级)。用 GPU 的峰值算力除以单请求消耗,再乘一个 0.3~0.5 的效率系数(因为内存带宽、算子调度都不完美),就能估算出理论吞吐上限。显存和算力,一个决定装不装得下,一个决定转不转得快,必须同时满足。

Mmem=Mweight+Mact+Mkv,Mweight=P×b10243 GB\displaystyle M_{mem} = M_{weight} + M_{act} + M_{kv}, \quad M_{weight} = \frac{P \times b}{1024^3}\ \text{GB}

1. P 模型参数量:模型拥有的参数总数,如 70 亿

P\displaystyle P

2. b 每参数字节数:权重存储精度,FP16 为 2 字节

b\displaystyle b

3. M_act 激活值开销:前向计算过程中的中间结果,随批处理大小增长

Mact\displaystyle M_{act}

4. M_kv KV缓存开销:缓存历史 token 的键值对,随并发数与序列长度线性增长

Mkv=2×L×C×d\displaystyle M_{kv} = 2 \times L \times C \times d

把灶台的「锅位」和「火力」都量清楚,才能回答「一块 GPU 能不能接住预期的客流」这个根本问题。很多容量事故,都始于只算了权重、漏了 KV Cache 这笔账。

QPS容量模型

餐厅的接待能力 = 座位数 × 翻台率。客流来了没有座位,只能门口排队;排队太长,客人扭头就走。推理服务也一样:请求到达后,要么立即被 GPU 处理,要么在队列里等待,等待超过客户端超时时间就直接失败。这个排队现象,正是容量模型的底层逻辑。

把需求侧和供给侧合到一起,就得到最核心的容量公式:所需副本数 = 峰值 QPS 除以单副本吞吐量,再乘上 (1+冗余率)。冗余率用来吸收流量抖动、单点故障和扩容期间的性能缺口,一般留 20%~30%。

排队论里更严谨的视角是 Little 定律:系统中的并发请求数 = 到达率 × 平均停留时间。反过来,当 P99 延迟目标定为 200ms、单副本能承受 32 个并发时,这个副本最多承载 32/0.2=160 QPS。这就是为什么压测基线和延迟目标共同决定了容量——你答应客人的上菜时间越短,需要的灶台就越多。

N=⌈QpeakTsingle×(1+r)⌉\displaystyle N = \left\lceil \frac{Q_{peak}}{T_{single}} \times (1 + r) \right\rceil

1. Q_peak 预测峰值QPS:来自需求分析预测的峰值流量

Qpeak\displaystyle Q_{peak}

2. T_single 单副本吞吐量:来自性能基线测试的单卡容量锚点

Tsingle\displaystyle T_{single}

3. r 冗余率:为抖动、故障、扩容延迟预留的富余量,如 0.3

r\displaystyle r

4. 向上取整:副本数必须是整数,且宁多勿少,避免容量差一口气

⌈⋅⌉\displaystyle \lceil \cdot \rceil

这就像餐厅既按高峰客流配足餐位,又额外留两张应急桌应对突发。算出来的 N 不是最终答案,而是一个「有弹性的底线」——它告诉你常态下要准备多少灶台,也告诉你极端情况下扩容的边界在哪。

弹性伸缩策略

聪明的老板不会让所有厨师从早站到晚:午市前两小时叫钟点工,晚市结束让多余的人下班。推理服务的流量同样有潮汐,弹性伸缩就是那套自动排班系统:流量涨了自动加灶,流量跌了自动撤灶,让 GPU 利用率始终维持在一个健康区间。

最常用的实现是 Kubernetes 的 HPA(Horizontal Pod Autoscaler)。它周期性地读取自定义指标,比如 QPS、P99 延迟或 GPU 利用率,当指标连续超过目标值一段时间,就创建新副本;持续低于目标,则回收副本。为了避免指标抖动导致来回震荡,每次伸缩后都要进入一个冷却窗口,在窗口内不触发相反方向的伸缩。

HPA 的计算公式非常朴素:期望副本数 = 当前副本数 × 当前指标 / 目标指标。指标超过目标越多,扩容倍数越大。但弹性伸缩最大的坑是冷启动:新 Pod 要从镜像仓库拉取模型权重,加载到显存可能耗时几十秒甚至几分钟,就像钟点工要换衣服、找工位才能上手。等指标报警再扩容,客人早就排无可排。所以生产级方案都要加「提前扩容」——根据流量趋势预测 QPS 将达峰时先扩容,再配合模型预热和就绪探针,让新副本真正「接得住单」。

Rnew=⌈Rcur×McurMtarget⌉\displaystyle R_{new} = \left\lceil R_{cur} \times \frac{M_{cur}}{M_{target}} \right\rceil

1. R_cur 当前副本数:上一时刻实际运行的 GPU 副本数量

Rcur\displaystyle R_{cur}

2. M_cur 当前指标值:最近一个评估窗口内的实际指标,如当前 QPS

Mcur\displaystyle M_{cur}

3. M_target 目标指标值:期望维持的指标水平,如单副本 70% 利用率对应的 QPS

Mtarget\displaystyle M_{target}

4. 向上取整:多扩一个也比少扩一个安全,避免扩容后仍不够用

⌈⋅⌉\displaystyle \lceil \cdot \rceil

排班表要「提前看天气预报」,不能等客人排长队才打电话叫钟点工——冷启动的几十秒,就像钟点工换衣服进厨房的时间,客人已经等不及走了。

运维调优实践

餐厅开了半年,老板每周都会翻三张表:翻台率、排队时长、食材损耗。哪道菜翻台慢就改良,哪个时段人手紧就加人。容量规划从来不是开业前算一次就完事,而是「监控-压测-调优」的持续循环。

监控看板是容量规划的仪表盘,至少盯四类指标:入口 QPS、P99 延迟、GPU 利用率、扩容事件。每次发布新模型、升级框架,都要重新压测并回填基线,因为模型结构一变,性能基线可能就变了。成本优化则要定期核算 GPU 投入与有效请求量的比值,比如利用量化(INT8/FP8)降低显存、用 Spot 实例跑可中断任务。

其中 GPU 利用率是最关键的经营指标。利用率过低,说明灶台大多空闲,钱花得冤枉;利用率过高,说明风险在积累,峰值一到就会超时。实践中一般按利用率分档管理:低于 30% 缩容或与其他任务共享 GPU,30%~70% 是健康区间,超过 70% 就要检查扩容是否及时。用公式表达,利用率就是实际消耗算力与总供给算力之比:

Ugpu=Qavg×tinferNgpu×1 秒×100%\displaystyle U_{gpu} = \frac{Q_{avg} \times t_{infer}}{N_{gpu} \times 1\ \text{秒}} \times 100\%

1. Q_avg 平均QPS:一段时间内的平均请求速率,单位是请求/秒

Qavg\displaystyle Q_{avg}

2. t_infer 单请求GPU耗时:每个请求实际占用 GPU 的时间,单位是秒

tinfer\displaystyle t_{infer}

3. N_gpu GPU总卡数:当前可供调度的 GPU 数量

Ngpu\displaystyle N_{gpu}

月末复盘时,老板会调整下周的排班表;运营同学也会根据监控数据调整伸缩阈值、优化模型量化。容量规划是一场没有终点的精进——每一次调优,都是为了让 GPU 这块「灶台」烧得更旺、更省。

AI 应用场景

大模型API平台的弹性扩容

阶段:容量规划与弹性伸缩

解决的问题:传统方式固定部署 N 台 GPU,流量低谷时闲置浪费、高峰时集体超时;AI 方式通过 QPS 容量模型确定基线副本数,再叠加 HPA 自动伸缩,像餐厅按客流自动增减钟点工一样,实现性能与成本平衡。

具体案例:某 SaaS 公司提供 7B 模型的对话 API,白天企业调用高峰 QPS 5000,夜间跌到 300。容量规划算出基线 40 卡,HPA 在 QPS 超过阈值时自动加卡到 60,夜间缩回 25,GPU 整体利用率从 25% 提升到 55%。

电商大促前的容量预估

阶段:需求分析预测

解决的问题:大促流量无法凭经验拍脑袋,AI 方式用历史 QPS + 增长系数 + 高峰系数预测峰值,提前两周备好 GPU 实例,相当于餐厅提前预定周末的食材和钟点工。

具体案例:双 11 前,团队统计去年大促的 QPS 尖峰是日均的 6 倍,叠加会员增长 20%,预估值 = 日均 × 1.2 × 6。据此预订抢购时段的高性能 GPU 实例,活动期间 P99 延迟稳定在 180ms,无一次扩容事故。

GPU成本治理与FinOps

阶段:运维调优与成本优化

解决的问题:多团队共享 GPU 集群利用率参差不齐,AI 方式通过利用率分档和弹性伸缩回收空闲资源,就像餐厅根据翻台率调整每张桌子的使用效率。

具体案例:某 AI 中台团队给三个业务线分配 GPU,通过监控发现 A 线利用率只有 15%,B 线晚高峰超 80%。优化后,A 线缩容并共享 Spot 实例,B 线配置自动扩容,整体 GPU 预算下降 40%。

Python 演示

python42 行
"""推理服务容量规划工具:预测峰值QPS,计算副本数,模拟HPA伸缩决策."""import math  def predict_peak_qps(qps_avg, growth_rate, months, spike_factor):    """峰值 = 日均基线 x 增长系数 x 高峰波动系数."""    growth = (1 + growth_rate) ** months    return qps_avg * growth * spike_factor  def single_replica_capacity(concurrency, avg_latency_ms):    """Little定律:吞吐量 = 并发数 / 平均响应时间."""    return concurrency / (avg_latency_ms / 1000.0)  def required_replicas(peak_qps, single_capacity, redundant_ratio):    """容量模型:副本数 = 峰值QPS / 单副本吞吐,再乘(1+冗余率)."""    return math.ceil(peak_qps / single_capacity * (1 + redundant_ratio))  def hpa_desired_replicas(current_replicas, current_metric, desired_metric):    """HPA:期望副本 = 当前副本数 x 当前指标 / 目标指标."""    return math.ceil(current_replicas * current_metric / desired_metric)  if __name__ == "__main__":    avg_qps = 1200.0    peak = predict_peak_qps(avg_qps, growth_rate=0.08, months=6, spike_factor=3.0)    print("预估峰值QPS:", round(peak, 1))     per_replica = single_replica_capacity(concurrency=32, avg_latency_ms=200)    replicas = required_replicas(peak, per_replica, redundant_ratio=0.3)    print("单副本吞吐量:", round(per_replica, 1), "QPS")    print("建议GPU副本数:", replicas)     surge_qps = peak * 1.25    desired = hpa_desired_replicas(        current_replicas=replicas,        current_metric=surge_qps,        desired_metric=per_replica * replicas * 0.8,    )    print("流量超预期25%时,HPA期望副本数:", desired)
目的:把容量规划的四个公式串成一个小工具——先预测峰值 QPS,再算单副本吞吐、所需副本数,最后模拟流量超预期时 HPA 的扩容结果。
  1. growth = (1 + growth_rate) ** months把月增长率按幂运算换算成 m 个月后的总增速,相当于 6 个月每月涨 8% 的复利效果。
  2. return concurrency / (avg_latency_ms / 1000.0)Little 定律的代码形态:先把毫秒转成秒,再用并发数除以平均延迟得到单副本吞吐量。
  3. math.ceil(peak_qps / single_capacity * (1 + redundant_ratio))容量模型落地:向上取整保证副本数充足,冗余率给运营留出缓冲。
  4. return math.ceil(current_replicas * current_metric / desired_metric)HPA 公式:指标超目标时按比例放大副本数,是自动伸缩的核心引擎。
  5. surge_qps = peak * 1.25人为模拟「流量比预期多 25%」的突发场景,验证这套容量规划是否还有余量应对意外。

常见误区

误区我统计了线上一天的平均 QPS 是 800,按这个数字买了两块 GPU,结果一到大促全部超时,用户一直在转圈。

正解平均数是容量规划的头号陷阱。流量是波动的,平均 QPS 会掩盖 10 倍的高峰尖刺。正确做法是用峰值和 P99 延迟来规划,即在日均基础上乘高峰波动系数。就像餐厅按午市峰值客流备灶,而不是按一天 24 小时的平均客流,否则饭点一定挤爆。

为何常见:平均值最容易获取和计算,监控大盘默认展示的也是平均值,人们自然用它做决策,却忽略了流量的分布形态。

误区模型能加载到 GPU 上就说明跑得动,我只关心显存够不够装模型权重。

正解推理是显存和算力的双重约束。连续生成时 KV Cache 会随并发快速增长,同时算力打满时延迟会飙升。评估时要同时验证明存峰值占用和 GPU 利用率,两者都在安全区间才算通过,就像灶台既要放得下锅,也要火够旺。

为何常见:模型加载是部署的第一道门槛,跨过它给人「已经成功」的错觉;而 KV Cache 是运行时才显现的成本,静态检查根本看不到。

误区反正有 HPA 自动扩容,QPS 涨了它自己会加副本,我不需要预留 buffer。

正解HPA 的扩容有天然的滞后性:指标采集、评估窗口、新 Pod 调度、模型加载都耗时,从流量突增到新副本真正服役往往要好几分钟。事前容量规划负责保证「常规峰值能扛住」,弹性伸缩只负责应对「计划外的波动」,两者是配合关系,不是替代关系。

为何常见:云厂商宣传「自动伸缩」让很多人误以为是即时反应,低估了冷启动的延迟,就像以为钟点工一个电话就能立刻出现在厨房里。

误区流量一降下来,我立刻把副本数缩到最少,这样可以最大程度省钱。

正解缩容太快会导致副本数在阈值附近来回震荡:扩两个、缩一个、再扩三个,每次伸缩都有额外调度开销,还可能把正在排队的请求掐断。正确做法是设置冷却窗口和最小副本数,让伸缩动作稳定下来,就像餐厅不会因为午市一过就把所有厨师赶回家,还要为晚市留人。

为何常见:成本焦虑让人倾向于「最省」策略,却忽略了频繁伸缩本身的稳定性开销,反而浪费更多资源。

面试题

Q1. 推理服务容量规划的第一步最应该做什么?

单选题 · easy

  • A.直接采购最强GPU硬件
  • B.分析历史流量与增长← 正确答案
  • C.立即开启全自动伸缩
  • D.部署模型并灰度上线

答案:B。容量规划的第一步是摸清需求,就像餐厅先观察客流再定灶台。采购 GPU、开启伸缩、部署模型都是后续动作,没有需求预测,它们都无从谈起。

Q2. 根据Little定律,吞吐量QPS的计算方式是?

单选题 · easy

  • A.并发请求数乘以平均延迟
  • B.并发请求数除以平均延迟← 正确答案
  • C.平均延迟除以并发请求数
  • D.并发请求数加上平均延迟

答案:B。Little 定律 T=C/L,吞吐量等于并发数除以平均延迟。乘、除反、加都是错误的运算关系,相当于把翻台率算成了上菜速度的乘积。

Q3. 70亿参数模型以FP16存储,模型权重约占多少显存?

单选题 · mid

  • A.约3.5GB显存容量
  • B.约7GB显存容量
  • C.约14GB显存容量← 正确答案
  • D.约28GB显存容量

答案:C。70 亿参数 × 2 字节 = 140 亿字节 ≈ 14GB。3.5GB 是 INT4 量化后的量级,7GB 是误把参数量当 GB 数,28GB 是把每个参数按 4 字节计算得出。

Q4. 推理服务中随并发数和序列长度增长最明显的显存开销是?

单选题 · mid

  • A.模型权重参数
  • B.前向激活值
  • C.KV缓存区← 正确答案
  • D.框架运行日志

答案:C。模型权重加载后是固定占用,激活值随批大小变化较小,KV Cache 随并发数和序列长度线性增长,是推理场景的「隐形吃货」。日志与显存无关。

Q5. HPA计算期望副本数时使用的公式是?

单选题 · mid

  • A.当前副本乘以目标除以当前指标
  • B.当前副本乘以当前指标除以目标← 正确答案
  • C.目标指标乘以当前副本除以冗余
  • D.当前指标除以目标再乘以冗余率

答案:B。HPA 公式是期望副本 = 当前副本 × 当前指标 / 目标指标。把当前指标除以目标指标,就是「超了多少就扩多少倍」,对应排班表上客流翻倍就加一倍人手。

Q6. 压测时吞吐量随并发升高出现「先升后平」的拐点,此时最准确的理解是?

单选题 · hard

  • A.系统已达最大吞吐,再加压延迟会飙升← 正确答案
  • B.系统出现死锁,需要重启恢复服务
  • C.GPU显存不足,需要更换更大显存
  • D.压测工具失效,需要更换压测工具

答案:A。拐点意味着系统已经满负荷,请求开始排队,P99 延迟即将飙升。这个拐点正是容量模型中单副本吞吐量的取值点,不是故障信号,也不是显存或工具问题。

Q7. 容量公式中冗余率(如30%)的主要作用是什么?

单选题 · easy

  • A.提高GPU硬件采购预算
  • B.抵御流量抖动与故障波动← 正确答案
  • C.提升GPU平均利用率
  • D.让监控图表更加美观

答案:B。冗余率是为流量抖动、实例故障和扩容延迟预留的缓冲,相当于餐厅的应急桌位。它不是为了提升利用率,反而会稍微降低利用率。

Q8. 以下哪些是推理服务容量规划的输入数据?

多选题 · mid

  • A.历史QPS流量画像← 正确答案
  • B.单副本压测基线← 正确答案
  • C.代码仓库提交记录
  • D.业务增长预期数据← 正确答案

答案:ABD。容量规划输入包括历史流量画像、压测基线和业务增长预期。代码仓库提交记录反映开发进度,与线上请求容量没有直接关系。

Q9. 缓解弹性伸缩冷启动问题的合理手段有哪些?

多选题 · hard

  • A.基于流量趋势提前扩容← 正确答案
  • B.将评估窗口缩短到几秒
  • C.模型预热与就绪探针← 正确答案
  • D.完全关闭自动缩容策略

答案:AC。提前扩容和模型预热能缩短新副本「上菜」的时间;缩短评估窗口会让伸缩抖动加剧,完全关闭缩容则持续浪费成本,两者都不合理。

Q10. GPU利用率长期高于70%,可能预示哪些问题?

多选题 · mid

  • A.GPU算力得到了充分使用
  • B.高峰来临时存在超时风险← 正确答案
  • C.容量规划制定得过于保守
  • D.需要检查扩容是否及时← 正确答案

答案:BD。利用率长期偏高说明资源紧绷,高峰来临时容易超时,需要检查扩容是否及时。充分利用本身不是问题,但「长期」偏高意味着风险积累;规划保守恰恰会导致利用率偏低,而非偏高。