推理基础

在大规模上服务模型,受排队论数学与键值缓存物理共同支配。本附录建立了本书推理与运行章节所依赖的分析性服务模型,阐明排队动态与注意力缓存内存算术如何在严格的延迟服务水平目标(SLO)下合并为单一的服务约束。以 C³ 术语而言,推理将计算能力、与内存及客户端的通信,以及跨队列的协同,汇聚为一条服务约束。

如何使用本附录

本附录是服务系统的定量参考。利用排队模型来选择批大小,或在给定到达率下预测尾部延迟;利用键值缓存算术来 sizing 内存,或判断是缓存而非计算限制了吞吐量。

从推理与运行章节中引用本附录:当这些章节引用服务结果时,推导过程位于此处。可以线性通读以获取完整论证,也可以查阅 GPT-3 的算例与批大小决策框架,直接作为适用于生产系统的模板。

服务性能分析

服务性能分析包含两个耦合的层次。队列决定请求在随机到达下如何等待、批处理与丢弃;键值缓存决定加速器在满足延迟预算的同时能够承载多少活跃状态。以下小节先推导排队模型,再将其与内存容量限制连接起来,用于worked serving examples。

批处理推理的排队论

批处理效率曲线提供了吞吐—延迟权衡的直觉,但生产系统需要严格的分析,以确定随机到达模式下的最优批大小。排队论提供了推导这些最优运行点、并理解为何某些批大小在特定条件下优于其他批大小的数学框架。

队列记号与 M/G/1 批处理代理模型

M/G/c/K 记号 命名了生产 GPU 服务模型可能需要表示的四个特征:

  • M(马尔可夫到达):请求按照速率为 \(\lambda_{\text{arr}}\) 的泊松过程到达。这刻画了用户请求的无记忆性,即一个请求的到达并不预示下一个请求的到达时刻。
  • G(一般服务分布):服务时间服从一般分布,不限于指数分布。GPU 推理时间取决于批大小,并呈现确定性成分(计算)与随机波动(内存争用、内核调度)的混合。
  • c(服务器数量):系统拥有 \(c\) 个并行 GPU 工作器,每个工作器都能独立地服务请求。
  • K(队列容量):系统维护容量为 \(K\) 个请求的有限队列。到达满队列的请求会被拒绝(负载丢弃)。

该记号源自同一套系统性能谱系,它在被应用于 GPU 集群之前,曾用于 sizing 电话网络。

Systems Perspective 0.1: 排队论与性能
排队论由 Agner Krarup Erlang 于 1909 年为电话网络分析而创立,至今仍是系统性能工程的基础 (Erlang 1909年)。当年用于 sizing 电话交换机的同一套数学框架,如今正指导 GPU 集群容量规划。标准系统学教材会展开本记号所依赖的组件排队模型与近似方法 Kleinrock (1975年)。

Kleinrock, L. 1975年. Queueing Systems, Volume 1: Theory. Wiley-Interscience.
Erlang, Agner Krarup. 1909年. 《The Theory of Probabilities and Telephone Conversations》. Nyt Tidsskrift for Matematik B 20: 33~39.

对于批大小为 \(B\) 的批处理推理系统,服务时间成为批大小的函数。令 \(T_{\text{svc}}(B)\) 表示处理 \(B\) 个请求的批处理所需时间。根据批处理的物理机制(大规模批处理策略),公式 1 将其建模为:

\[T_{\text{svc}}(B) = T_{\text{fixed}} + t_{\text{req}} \cdot B \tag{1}\]

其中 \(T_{\text{fixed}}\) 表示固定的服务开销(内核启动、从高带宽内存(HBM)加载权重),\(t_{\text{req}}\) 表示每个请求的边际计算时间。该线性模型捕捉了生产系统中观察到的一阶行为,尽管在大批大小下,服务时间可能因内存带宽饱和而呈现轻微的次线性。

批处理的有效服务速率Effective Service Rate 为:

\[\mu_{\text{eff}}(B) = \frac{B}{T_{\text{svc}}(B)} = \frac{B}{T_{\text{fixed}} + t_{\text{req}} \cdot B}\]

有效吞吐率随批大小增加而提升,逼近渐近极限 \(1/t_{\text{req}}\),此时 \(B \to \infty\)。

响应时间分析

单个请求的总响应时间 \(T\) 由三个部分组成:

\[E[T] = E[W] + E[T_{\text{batch}}] + E[T_{\text{svc}}]\]

其中:

  • \(E[W]\) 表示加入批次前在队列中的预期等待时间
  • \(E[T_{\text{batch}}]\) 表示调度前每请求的批次累积延迟
  • \(E[T_{\text{svc}}]\) 表示批次执行后的预期推理时间

对于最大等待时间 \(T_{\text{max}}\)、最大批大小 \(B_{\text{max}}\) 的动态批处理,首个请求触发批处理窗口。设 \(N \sim \operatorname{Poisson}(\lambda_{\text{arr}}T_{\text{max}})\) 为窗口内后续到达的请求数,并设 \(k=B_{\text{max}}-1\)。对于 \(B_{\text{max}}>1\),实际批大小为 \(B=\min(B_{\text{max}},1+N)\),包含触发请求,因此:

\[E[B] = \sum_{n=0}^{k-1}(n+1)\Pr(N=n) + B_{\text{max}}\Pr(N\geq k)\]

设 \(\tau_k\) 为第 \(k\) 个后续到达的 Erlang 分布时间。当 \(\tau_k \leq T_{\text{max}}\) 时批次满员,而超时批次在 \(T_{\text{max}}\) 关闭,此时 \(N=n<k\)。每个实际批次内的每请求累积延迟均值为:

\[E[T_{\text{batch}} \mid \text{full}] = \frac{1}{2}E[\tau_k \mid \tau_k \leq T_{\text{max}}]\]

\[E[T_{\text{batch}} \mid N=n,\ \text{timeout}] = \frac{T_{\text{max}}}{2}\left(1+\frac{1}{n+1}\right), \qquad 0 \leq n < k\]

以各批次的实际请求数加权,得到随机选取请求的平均延迟:

\[E[T_{\text{batch}}] = \frac{B_{\text{max}}\Pr(N\geq k)E[\tau_k/2 \mid \tau_k\leq T_{\text{max}}] + \sum_{n=0}^{k-1}(n+1)\Pr(N=n)E[T_{\text{batch}} \mid N=n,\ \text{timeout}]}{E[B]}\]

当批次在超时前可靠满员时,该表达式趋近于 \(E[\tau_k]/2=(B_{\text{max}}-1)/(2\lambda_{\text{arr}})\)。对于 \(B_{\text{max}}=1\),批次仅包含其触发请求,累积延迟为零。

最优批大小推导

最优批大小 \(B\) 在满足吞吐率要求的前提下最小化预期响应时间:

\[B = \operatorname{arg\,min}_{B} E[T(B)] \quad \text{subject to} \quad \mu_{\text{eff}}(B) \geq \lambda_{\text{arr}}\]

该约束确保系统稳定性(服务率高于到达率)。

对于批大小为 \(B\) 的高流量形态,批次在超时前可靠满员,代入响应时间分量可得:

\[E[T(B)] = E[W(B)] + \frac{B-1}{2\lambda_{\text{arr}}} + T_{\text{svc}}(B)\]

为便于求解等待时间估计,可采用 M/G/1 代理模型,将批次视为 Poisson“超级请求”。若请求到达率为 \(\lambda_{\text{arr}}\)、平均批大小为 \(B\),则该代理使用批到达率 \(\lambda_{\text{batch}}=\lambda_{\text{arr}}/B\)。这并非由分组 Poisson 请求到达所精确产生的过程,因为固定大小分组会给出 Erlang 型批间时间;当 \(K\) 或 \(c>1\) 为有限值时,需要采用批量服务模型或仿真。在显式代理模型中,Pollaczek-Khinchine 公式给出:

\[E[W] = \frac{\lambda_{\text{batch}} \cdot E[T_{\text{svc}}^2]}{2(1 - \rho_{\text{serv}})}\]

其中 \(\rho_{\text{serv}} = \lambda_{\text{batch}} \cdot E[T_{\text{svc}}] = \lambda_{\text{arr}} \cdot E[T_{\text{svc}}]/B\) 为服务器利用率。二阶矩 \(E[T_{\text{svc}}^2]\) 刻画服务时间的波动性。

对于该代理模型中服务时间为线性的确定性服务模型:

\[E[W(B)] = \frac{\lambda_{\text{arr}} \cdot T_{\text{svc}}(B)^2}{2B(1 - \lambda_{\text{arr}} \cdot T_{\text{svc}}(B)/B)}\]

对于生产规模设定,团队通常先强制设定利用率余量目标,而非求解完整的延迟最小化问题。给定 \(T_{\text{svc}}(B)=T_{\text{fixed}}+t_{\text{req}} B\),约束 \(\rho_{\text{serv}}=\lambda_{\text{arr}} T_{\text{svc}}(B)/B \leq \rho_{\text{target}}\) 给出目标利用率批大小上界(公式 2):

\[B_{\min}(\rho_{\text{target}}) = \frac{\lambda_{\text{arr}} T_{\text{fixed}}}{\rho_{\text{target}} - \lambda_{\text{arr}} t_{\text{req}}} \tag{2}\]

其中 \(\rho_{\text{target}}\) 为目标利用率(生产系统通常取 0.7–0.8,以维持延迟余量),而 \(\rho_{\text{target}} > \lambda_{\text{arr}} t_{\text{req}}\)。

Systems Perspective 0.2: 目标利用率批大小设定
目标利用率批大小上界(公式 2)揭示了一个基本结论:最小稳定批大小随固定开销和到达率增长。这意味着:

  1. 更高流量 \((\lambda_{\text{arr}})\):所需批大小增加。
  2. 更高固定开销 \((T_{\text{fixed}})\):所需批大小增加,以摊薄开销。
  3. 更高目标利用率 \((\rho_{\text{target}})\):所需批大小减小,但延迟余量更少。

这种受利用率约束的规模设定解释了为何大语言模型(LLMs)(权重加载带来高 \(T_{\text{fixed}}\))比视觉模型(低 \(T_{\text{fixed}}\))在相同到达率下更受益于更大的批大小。

工作示例:GPT-3 在 100 QPS 下的服务

考虑在以下系统参数下服务一个 GPT-3 类模型(175B 参数):

  • 到达率:\(\lambda_{\text{arr}} = 100\) 请求/秒
  • 硬件:8\(\times\) A100 GPU,采用张量并行
  • 权重加载开销:\(T_{\text{fixed}} = 50\) ms(每个前向传播加载注意力矩阵所需时间)
  • 每 token 计算量:\(t_{\text{req}} = 0.5\) ms/请求(在批次内摊薄)
  • 平均输出长度:每请求 100 个 token
  • 目标利用率:\(\rho_{\text{target}} = 0.75\)

对于预填充阶段(处理输入提示),服务时间服从 公式 1:

\[T_{\text{svc}}(B) = 50 + 0.5 \cdot B \text{ ms}\]

应用 公式 2 计算满足 75% 目标利用率(保留 25% 余量)的最小批大小:

\[B_{\min} \approx \frac{100 \times 0.05}{0.75 - 100 \times 0.0005} = \frac{5}{0.70} \approx 7.14\]

向上取整后,\(B=8\) 为满足目标利用率余量的最小批大小。在满批假设下评估代理响应时间表达式,可以看出更大的批大小会降低利用率,但会增加批次累积延迟:

评估 GPT-3 服务性能随批大小(批大小对 GPT-3 服务性能的影响)的变化,揭示了排队延迟与服务器利用率之间的权衡:

批大小对 GPT-3 服务性能的影响:批大小低于 8 时无法维持 100 QPS(利用率超过 100%)。计入批次累积延迟后,该简单模型中的延迟最小值出现在 \(B=8\) 附近;\(B=16\) 的平均延迟几乎相同但利用率更低,而 \(B=32\) 保留了更多余量,却付出了较大的累积延迟代价。
批大小 \(B\) \(T_{\text{svc}}(B)\)(ms) req/s \(\rho_{\text{serv}}\) E[W](ms) \((B-1)/(2\lambda_{\text{arr}})\)(ms) E[T](ms)
1 50.5 19.8 505%(不稳定) \(\infty\) 0.0 \(\infty\)
4 52.0 76.9 130%(不稳定) \(\infty\) 15.0 \(\infty\)
8 54.0 148.1 67.5% 56.1 35.0 145.1
16 58.0 275.9 36.3% 16.5 75.0 149.5
32 66.0 484.8 20.6% 8.6 155.0 229.6

在这些批处理规模下,出现了四种运行形态:

  1. 不稳定形态(批处理规模 1–4): 利用率超过 100 个百分点,意味着系统无法跟上请求到达速率。队列持续增长且无界。
  2. 稳定性阈值(批处理规模 8): 在 67.5 percent 的利用率下,系统是稳定的,但排队延迟对延迟(56.1 ms)有显著贡献,导致接近饱和时排队延迟急剧上升(图 1)。
  3. 延迟拐点(批处理规模 8–16): 在本模型中,批处理规模 8 给出最低的均值延迟。批处理规模 16 以多几毫秒的额外总延迟为代价,换取更低的利用率和更短的排队等待时间(16.5 ms 与 56.1 ms 相比),而 \(B=32\) 虽然保留了更多的利用率余量,却付出了过多的批处理累积延迟。
  4. 收益递减(批处理规模超过 32): 进一步增加批处理规模会降低利用率,但受内存约束,无法继续探索。
图 1: 排队 hockey stick 曲线:对于 M/M/1 排队系统,\(\rho_{\text{serv}}/(1-\rho_{\text{serv}})\) 表示系统中请求数的期望值,包括正在被服务的请求。其接近饱和时的双曲式上升解释了生产系统为何保留利用率余量;图中着色的运行区间仅为示意,而非普适阈值。

应用 Little 定律可为这些结果提供内部一致性检查。

Napkin Math 0.1: 应用 Little 定律进行验证
验证:根据 Little 定律 (Little 1961年),\(Q_{\text{req}} = \lambda_{\text{arr}} \cdot T_{\text{lat}}\):

在 \(B=16\) 时,请求速率为 \(\lambda_{\text{arr}} = 100\) req/s,且 \(E[T] =\) 149.5 ms:

\(Q_{\text{req}} = 100 \times\) 0.1495 s = 14.95 个系统内请求

当批处理规模为 16、利用率为 36.3 percent 时:

  • 正在接受服务的期望请求数:16 \(\times\) 0.363 = 5.8
  • 队列中的期望请求数:14.95 - 5.8 = 9.14

这与响应时间分解一致:平均约有 6 个请求正在接受服务,约有 9 个请求正在等待或累积成批。

Little, John D. C. 1961年. 《A Proof for the Queuing Formula: \(L = \lambda W\)》. Operations Research 9 (3): 383~87. https://doi.org/10.1287/opre.9.3.383.

决策框架:给定 SLA 时的批处理规模选择

生产系统必须选择合适的批处理规模,以满足服务级别目标(SLO);这些目标通常以延迟百分位数表示(例如,P99 延迟 < 200 ms)。以下框架将这一决策过程系统化:

步骤 1:刻画服务时间

通过对批处理规模为 1、8 和 32 时的推理进行性能剖析,实测 \(T_{\text{fixed}}\) 和 \(t_{\text{req}}\)。拟合线性模型 \(T_{\text{svc}}(B) = T_{\text{fixed}} + t_{\text{req}} B\)。

步骤 2:计算稳定性阈值

求最小批处理规模 \(B_{\text{min}}\),使其满足 \(\mu_{\text{eff}}(B_{\text{min}}) > \lambda_{\text{arr}}\):

\[B_{\text{min}} = \frac{T_{\text{fixed}} \lambda_{\text{arr}}}{1 - t_{\text{req}} \lambda_{\text{arr}}}\]

任何低于 \(B_{\text{min}}\) 的批处理规模都会导致系统不稳定。

步骤 3:计算候选批处理规模下的延迟

在相同的泊松超请求替代模型和满批次假设下,对每个候选 \(B \in \{B_{\text{min}}, 2B_{\text{min}}, ..., B_{\text{max}}\}\),计算:

\[E[T(B)] = \frac{\lambda_{\text{arr}} \cdot T_{\text{svc}}(B)^2}{2B(1 - \lambda_{\text{arr}} T_{\text{svc}}(B)/B)} + \frac{B-1}{2\lambda_{\text{arr}}} + T_{\text{svc}}(B)\]

步骤 4:考虑尾部延迟

如果实测响应时间近似服从高斯分布,其 P99 可估计为:

\[T_{\text{P99}} \approx E[T] + 2.33 \cdot \sigma_T\]

其中,\(\sigma_T\) 是响应时间的标准差。这一高斯规则并非通用的重负载近似,因为排队系统的响应时间通常呈偏态分布。对于服从指数分布的响应时间,P99 为 \(-\ln(0.01)E[T] \approx 4.6 \cdot E[T]\);在确定生产系统规模时,应使用实测百分位数。

步骤 5:选择最优批处理规模

选择最大的 \(B\),使其满足 \(T_{\text{P99}}(B) \leq \text{SLO}\):

\[B = \max\{B : T_{\text{P99}}(B) \leq \text{SLO}\}\]

批处理规模选择的运行规则(表 1)在稳定性、延迟 SLO 和成本效率之间取得平衡:

表 1: 批处理规模决策框架:基于稳定性、延迟 SLO 和利用率目标,系统性地选择批处理规模的方法。
条件 建议操作 理由
\(B < B_{\min}\) 增大批处理规模或增加副本 系统不稳定
\(T_{\text{P99}} > \text{SLO}\) 减小批处理规模或增加副本 延迟超出目标
\(\rho_{\text{serv}} < 0.5\) 考虑减少副本以节省成本 系统资源配置过量
\(\rho_{\text{serv}} > 0.85\) 增加副本以预留容量余量 接近不稳定状态

应用这些运行规则,可确保服务部署在负载下保持及时响应,同时在低流量时段保持成本效率。

权衡曲线:可视化运行区域

吞吐量与延迟的权衡曲线(图 2)界定了可行的运行范围:

图 2: 批处理规模权衡曲线:随着横轴上的批处理规模增大,吞吐量(左纵轴,蓝色)呈次线性增长,而 P50 延迟(右纵轴,红色)呈近似线性增长。图中在 B=16 处标记了最优点;着色的内存不足(OOM)容量区域标示了超出设备内存容量的批处理规模。基准测试:Llama-2 70B 采用 FP16,在四张 A100 80 GB GPU 上进行张量并行。

权衡曲线揭示了几个关键结论:

  1. 帕累托前沿:当不存在另一个候选点,其吞吐量至少与当前运行点相同、延迟不高于当前运行点,且至少一个目标严格改善时,该运行点即具有帕累托效率。前沿是这些非支配点的集合。
  2. 曲线拐点:最优批大小通常位于“拐点”,即吞吐量增益逐渐减小、而延迟继续线性增长的位置。
  3. SLO 约束下的最优点:当 SLO 限定最大延迟时,最优点位于曲线与 SLO 边界的交点。
  4. 收益递减:超过拐点后,批大小翻倍可能仅使吞吐量提高 10–20%,同时使延迟翻倍。

排队论框架为 大规模批处理策略 中介绍的批处理策略提供了数学基础。尽管直觉可能认为“批越大,越有利于提高吞吐量”,但稳定性约束、延迟目标和收益递减共同界定了一个明确的最优运行区域,该区域随模型类型和部署需求而变化。

KV 缓存基础

KV 缓存的正式定义见正文的推理内存管理章节(如 内存管理:从预分配走向分页 中所介绍)。本附录进一步阐述该定义背后的容量计算原理:缓存为何能减少每个词元的计算量,其内存占用为何随序列长度和批大小增长,以及未经管理的内存分配为何会导致 HBM 碎片化 (Kwon 等 2023年)。

Kwon, Woosuk, Zhuohan Li, Siyuan Zhuang, Ying Sheng, Lianmin Zheng, Cody Hao Yu, Joseph Gonzalez, Hao Zhang, 和 Ion Stoica. 2023年. 《Efficient Memory Management for Large Language Model Serving With PagedAttention》. Proceedings of the 29th Symposium on Operating Systems Principles, 611~26. https://doi.org/10.1145/3600006.3613165.

不使用缓存的自回归生成,每个词元需要 \(\mathcal{O}(t^2)\) 的计算量,因为每个 Transformer 层都必须重新计算所有先前词元的注意力键和值。KV 缓存存储这些已计算的键向量和值向量,将生成过程中每个词元的计算量降至 \(\mathcal{O}(t)\)。对于大规模模型服务,这种计算量的节省带来了关键的内存管理挑战,因为在长上下文下,KV 缓存的内存占用可能超过模型权重的内存占用。

缓存大小随上下文长度增长,其计算方式见 公式 3:

\[M_{\text{KV}} = 2 \times N_L \times d \times S \times B \times s_{\text{elem}} \tag{3}\]

其中,\(N_L\) 为层数,\(d\) 为隐藏维度,\(S\) 为序列长度,\(B\) 为批大小,\(s_{\text{elem}}\) 为每个元素的存储大小(以字节为单位),系数 2 表示需要同时存储键和值。

对于 175B GPT-3 模型(\(N_L=96\),\(d=12288\),FP16 \(s_{\text{elem}}=2\) 字节)在序列长度 \(S=2048\) 下,每个请求需要:

\[ M_{\text{KV/req}} = 2 \times 96 \times 12288 \times 2048 \times 2 \text{ B} \approx 9.66 \text{ GB/request} \]

在 8\(\times\) 块 A100 80-GB GPU(640 GB 总 HBM)上,以 FP16 存储模型权重需要 350 GB,剩余 290 GB 用于激活与 KV 缓存内存。未管理的连续分配将最大并发批大小限制为 \(B_{\text{max}} \le 290/9.66 \approx\) 30 个请求,直到内存耗尽(OOM),这展示了 KV 缓存容量如何约束服务吞吐量。

摘要

生产推理服务需要在排队动态与硬件内存容量之间取得平衡。本附录推导出的定量关系适用于各种服务部署中的批大小选择、延迟预算和加速器内存上限:

Key Takeaways: 服务性能受队列与内存约束
  • 利用率存在硬性上限:当利用率 \(\rho_{\text{serv}}\) 趋近于 1 时,队列深度与延迟将无限增长。生产服务以 \(\rho_{\text{serv}} \leq 0.7\) 为目标,以保留延迟余量;其余 30% 并非浪费,而是使尾部延迟保持有限的缓冲。
  • 批大小存在最优值,而非最大值:更大的批大小可提高吞吐量,但会增加批内累积延迟,从而产生延迟拐点,而非单调改善。超过拐点后,批大小翻倍仅能带来 10–20% 的额外吞吐量,代价是延迟翻倍。
  • Little 定律将系统串联起来:\(Q_{\text{req}} = \lambda_{\text{arr}} T_{\text{lat}}\) 将飞行中请求数与到达率及系统内停留时间联系起来,为任何服务测量提供一行一致性校验。
  • KV 缓存是约束性瓶颈:缓存内存随序列长度和批大小线性增长,并且通常超过模型权重,从而限制并发容量(自回归瓶颈,原则 14)。朴素分配会因碎片浪费 60–80% 的容量,因此生产系统采用虚拟内存方案对其进行管理。
回到顶部
← 三卷书架