大模型中的数学(005):泊松分布在 LLM 推理系统中的作用

泊松分布在 LLM 推理系统中的作用

在 LLM Serving 系统中,用户请求的到达往往是"不守时"的。即使一台服务器平均每秒接收 10 个请求,实际情况也可能是:这一秒来了 7 个,下一秒来了 12 个,再下一秒来了 9 个。平均到达速率只是一个长期统计的结果,而真正决定系统性能的,恰恰是围绕这个平均值的随机波动——请求可能在短时间内集中到达,服务器来不及处理,于是就形成了排队。

这正是经典排队论最擅长处理的问题。泊松过程(Poisson Process)描述了请求随时间随机到达的行为,泊松分布则给出固定时间区间内到达请求数的概率分布;再结合请求的服务时间,就可以建立排队模型,分析服务器利用率、请求等待时间以及系统的延迟表现。这篇文章就来沿着这条逻辑线走一遍:从随机请求到达出发,依次推导请求排队和服务延迟,最后落到 SLO 上,顺便看看它在容量规划、尾延迟分析以及 DistServe 这类 Prefill/Decode 分离架构中的作用。

整体逻辑可以概括为一句话:

随机请求到达→请求排队→产生服务延迟→影响 SLO\text{随机请求到达} \rightarrow \text{请求排队} \rightarrow \text{产生服务延迟} \rightarrow \text{影响 SLO}

泊松分布

先从数学模型说起。设某个 LLM 推理服务器的平均请求到达速率为 λ\lambda(单位 requests/s),令 N(t)N(t) 表示时间区间 [0,t][0,t] 内到达的请求数量。如果请求按照速率为 λ\lambda 的齐次泊松过程到达,那么任意长度为 tt 的区间内到达的个数都服从泊松分布

N(t)∼Poisson(λt)N(t) \sim \mathrm{Poisson}(\lambda t)

也就是说,观察窗口 tt 内恰好到达 kk 个请求的概率为

P(N(t)=k)=(λt)ke−λtk!P(N(t)=k) = \frac{(\lambda t)^k e^{-\lambda t}}{k!}

这里 λ\lambda 是单位时间内的平均到达速率,而 λt\lambda t 才是观察区间内的期望请求数,两者容易混淆,需要注意。

举个例子的话,取 λ=10\lambda = 10 requests/s、t=1t = 1 s,则 N(1)∼Poisson(10)N(1) \sim \mathrm{Poisson}(10),1 秒内恰好到达 kk 个请求的概率就是 P(N(1)=k)=10ke−10/k!P(N(1)=k) = 10^k e^{-10}/k!。当然,这并不意味着每秒一定到达 10 个请求——它只说明长期来看平均每秒到达 10 个,实际到达数量可能是 7、9、12 或其他值。

泊松分布有一个对我们非常重要的性质:均值等于方差,即

E[N(t)]=λt,Var[N(t)]=λtE[N(t)] = \lambda t,\qquad Var[N(t)] = \lambda t

于是标准差为 σ=λt\sigma = \sqrt{\lambda t}。例如平均到达速率为 100 requests/s、观察 1 秒时,到达数的均值和方差都是 100,标准差是 10——服务器平均每秒收到 100 个请求,但实际数量存在随机波动,典型波动幅度在 10 个请求左右。

这个性质的价值在于:只要知道平均到达速率,就能直接得到泊松模型下负载的波动幅度,进而估计系统需要预留多少"余量"。当然,均值等于方差只是泊松分布的一个特征,并不能单独证明真实请求流量一定服从泊松分布,这一点的适用条件我们最后再讨论。

指数间隔

泊松分布回答的是一个计数问题:一段时间内到达了多少个请求?但对排队系统来说,另一个问题同样重要:相邻两个请求之间隔了多久?

对于齐次泊松过程,相邻请求的时间间隔服从指数分布。令 TT 表示相邻两个请求之间的间隔,则

T∼Exp(λ),fT(t)=λe−λt (t≥0),E[T]=1λT \sim \mathrm{Exp}(\lambda),\qquad f_T(t) = \lambda e^{-\lambda t}\ (t\geq 0),\qquad E[T] = \frac{1}{\lambda}

例如 λ=10\lambda = 10 requests/s 时,平均间隔 E[T]=0.1E[T] = 0.1 s,即 100ms。当然,平均间隔 100ms 并不意味着每隔 100ms 就"准时"来一个请求——实际间隔仍是随机的,可能是 10ms,也可能是 200ms。

所以泊松分布和指数分布描述的是同一个泊松到达过程的两个侧面:前者看"固定窗口里来了多少",后者看"相邻两次到达隔了多久"。两者共同构成了排队模型中的请求到达过程。

随机到达与排队

先直观地看一下,为什么"到达的随机性"就足以产生排队。假设一台服务器一次只能处理一个请求,每个请求的服务时间是 100ms,考虑两种到达方式。

均匀到达:每隔 100ms 来一个请求,当前请求处理完时下一个恰好到达,基本不需要排队。

集中到达:5 个请求几乎同时到达,服务器只能依次处理:

请求 到达时间 开始服务时间 排队等待时间
Request 1 0ms 0ms 0ms
Request 2 0ms 100ms 100ms
Request 3 0ms 200ms 200ms
Request 4 0ms 300ms 300ms
Request 5 0ms 400ms 400ms

可以看到,即使请求总数相同,到达时刻的不同也会导致排队等待时间大相径庭。这正是研究请求到达过程的意义:服务器不仅需要知道"平均有多少请求",还需要考虑"这些请求在时间轴上如何分布"。

M/D/1 排队模型。 为了定量地分析请求到达与服务能力的关系,先看一个简化的 M/D/1 排队模型。M/D/1 三个符号的含义是:M 代表 Markovian,即请求按泊松过程到达(相邻间隔服从指数分布);D 代表 Deterministic,即每个请求的服务时间固定;1 表示只有一个服务台。

令 λ\lambda 为平均请求到达速率,μ\mu 为平均服务速率(对应固定服务时间 S=1/μS = 1/\mu),ρ\rho 为服务器利用率。先算利用率

ρ=λμ\rho = \frac{\lambda}{\mu}

系统长期稳定的必要条件是 ρ<1\rho < 1——也就是请求到达速率必须小于服务器处理速率,否则队列会越积越长。对 M/D/1,平均排队等待时间为

Wq=ρ2μ(1−ρ)W_q = \frac{\rho}{2\mu(1-\rho)}

其中 WqW_q 是请求从到达到开始接受服务之间的平均等待时间,不包含实际服务时间。

举个例子:取 λ=8\lambda = 8 requests/s、μ=10\mu = 10 requests/s,则 ρ=0.8\rho = 0.8,代入上式

Wq=0.82×10×(1−0.8)=0.2 s=200 msW_q = \frac{0.8}{2 \times 10 \times (1-0.8)} = 0.2\text{ s} = 200\text{ ms}

也就是说,一个请求平均要等待 200ms 才能开始接受服务。到这里就建立了第一个重要联系:

请求到达速率+服务器处理能力→排队等待时间\text{请求到达速率} + \text{服务器处理能力} \rightarrow \text{排队等待时间}

为什么利用率越高,排队延迟增长越快。 继续观察 M/D/1 的等待时间公式,固定服务器处理速率 μ=10\mu = 10 requests/s,改变请求到达速率,可以得到:

到达速率 λ\lambda 利用率 ρ\rho 平均排队等待时间
5 requests/s 50% 50ms
8 requests/s 80% 200ms
9 requests/s 90% 450ms
9.5 requests/s 95% 950ms
9.9 requests/s 99% 4950ms

可以看到,当服务器利用率从 90% 增加到 99% 时,平均排队等待时间从 450ms 增加到 4950ms,接近 10 倍。数学上,当 ρ→1\rho \rightarrow 1 时,Wq→∞W_q \rightarrow \infty。根本原因在于:服务器几乎没有空闲时间来"消化"新到达的请求,一旦出现请求集中到达,就容易形成持续一段时间的排队。因此,系统不能只关注平均吞吐量,还需要给服务器预留一定的处理余量。

这里要说明的是,M/D/1 假设每个请求的服务时间固定,而真实 LLM 推理中的服务时间会受到输入长度、输出长度、Batch Size、KV Cache 和调度策略等因素的影响。所以它更适合作为理解排队机制的"玩具模型",而不是完整 LLM Serving 系统的精确模型。

从排队到 TTFT、TPOT 与 SLO

接下来看排队等待时间如何体现为 LLM 推理系统的性能指标。这需要从请求的实际处理流程来看。

排队与 TTFT。 TTFT(Time To First Token)表示从请求到达到生成第一个 Token 所经历的时间。在一个简化的推理模型中,可以把它写成

TTFT=Wq+Tprefill+TotherTTFT = W_q + T_{\text{prefill}} + T_{\text{other}}

其中 WqW_q 是请求排队等待时间,TprefillT_{\text{prefill}} 是 Prefill 阶段的计算时间,TotherT_{\text{other}} 是调度、传输等其他开销。可见,当请求到达速率增加、排队等待变长时,即使 Prefill 的计算性能没有变化,TTFT 也会上升。例如取 Wq=200W_q = 200 ms、Tprefill=100T_{\text{prefill}} = 100 ms,暂时忽略其他开销,则 TTFT=300TTFT = 300 ms——排队等待时间已经占据了 TTFT 的相当一部分。

排队与 TPOT、ITL。 TPOT(Time Per Output Token)表示平均每个输出 Token 的生成时间,ITL(Inter-Token Latency)表示相邻输出 Token 之间的时间间隔。它们与 TTFT 的区别在于:TTFT 主要受请求进入系统后的调度等待和 Prefill 完成时间影响,而 TPOT、ITL 主要受 Decode 阶段的计算和调度影响。请求到达的随机性也会通过 Decode 阶段的资源竞争、Batch 调整和调度等待来影响 TPOT、ITL,但这种关系不像 TTFT 与排队等待的关系那样直接,不能简单地写成 TPOT=Wq+TdecodeTPOT = W_q + T_{\text{decode}}。因此,需要结合 Prefill 和 Decode 两个阶段分别分析。

排队与 SLO。 SLO(Service Level Objective)是系统对服务质量提出的目标,例如 TTFT≤500TTFT \leq 500 ms 表示希望请求在 500ms 内生成第一个 Token。假设系统处理了 1000 个请求,其中 950 个的 TTFT 不超过 500ms,50 个超过了,那么 SLO 达成率为

SLO Achievement=满足延迟约束的请求数量总请求数量=9501000=95%\text{SLO Achievement} = \frac{\text{满足延迟约束的请求数量}}{\text{总请求数量}} = \frac{950}{1000} = 95\%

也可以写成概率 P(TTFT≤500 ms)P(TTFT \leq 500\text{ ms})。这里值得强调的是:SLO 衡量的不是平均请求延迟,而是"有多少请求能够满足指定的延迟约束"。

现在可以把整条因果链串起来了:

请求随机到达→请求排队等待→TTFT 等延迟指标变化→SLO 达成率变化\text{请求随机到达} \rightarrow \text{请求排队等待} \rightarrow \text{TTFT 等延迟指标变化} \rightarrow \text{SLO 达成率变化}

这里需要特别注意:泊松分布本身不能直接计算 TTFT、TPOT 或 P99,它只负责描述请求到达过程。要计算这些性能指标,还需要结合服务时间分布、调度策略和排队模型进一步推导延迟分布,或者通过仿真统计得到。

容量规划

除了分析排队延迟,泊松分布还可以用来估计请求负载的波动,帮助系统做容量规划。取 λ=100\lambda = 100 requests/s,观察 1 秒,则到达请求数 N(1)∼Poisson(100)N(1) \sim \mathrm{Poisson}(100),均值为 100,标准差为 10——服务器平均每秒收到 100 个请求,但实际数量存在随机波动。

如果系统只按平均请求数量设计处理能力,那么当请求数量高于平均值时,服务器就会"接不住",从而出现排队。因此可以进一步计算

P(N(t)>C)P(N(t) > C)

其中 CC 是指定时间窗口内的请求数量阈值,这个概率衡量的就是"该时间窗口内请求数量超过预设处理预算的风险"。

当然,这个概率并不等于实际的队列溢出概率。真正的排队和溢出还取决于请求到达的具体时刻、服务时间、已有队列长度以及系统的队列容量。所以泊松分布能帮上忙的是容量规划中的"负载波动"这一环,完整的容量规划仍然需要结合排队模型和系统仿真。

尾延迟

在 LLM 推理系统中,平均延迟并不能完全反映系统性能。例如两个系统的平均 TTFT 都是 200ms,但其中一个系统的大多数请求都在 200ms 左右完成,另一个系统却可能存在少量请求要等上数秒。对在线推理服务来说,后者的服务质量显然更差。因此除了平均延迟,还需要关注尾延迟(Tail Latency)。

什么是 P95 和 P99。 P95 和 P99 分别是延迟分布的第 95 和第 99 百分位数。P95(TTFT)=500P95(TTFT) = 500 ms 表示 95% 的请求 TTFT 不超过 500ms;同理 P99(TTFT)=1000P99(TTFT) = 1000 ms 表示 99% 的请求 TTFT 不超过 1000ms。它们与平均延迟的区别在于:平均延迟反映整体请求的平均表现,而 P95、P99 分别刻画"比它们更慢的请求只剩 5%、1%"时的延迟水平。所以 P95 和 P99 更适合衡量系统在请求集中到达、资源竞争和排队情况下的性能表现。

为什么随机请求到达会影响尾延迟。 考虑一台请求到达过程服从泊松过程的服务器。由于到达具有随机性,即使平均到达速率保持不变,实际到达时间仍可能出现"短时间内多个请求扎堆"的情况。当服务器无法同时处理这些请求时就会形成排队,而排在队列后面的请求需要等前面的请求处理完成,等待时间可能很大。请求到达过程带来的排队波动越大,WqW_q 的分布就越"肥尾",TTFT 分布的尾部也就被拉长:

请求到达随机性→排队等待时间波动→延迟分布变化→尾延迟变化\text{请求到达随机性} \rightarrow \text{排队等待时间波动} \rightarrow \text{延迟分布变化} \rightarrow \text{尾延迟变化}

为什么服务器利用率会影响尾延迟。 对 M/D/1 模型,当服务器利用率 ρ\rho 越来越接近 1 时,平均排队等待时间迅速增大(见前面那张利用率表)。这不仅意味着平均等待时间增加,也意味着请求等待时间的分布发生变化,长时间等待的风险随之上升。因此在高利用率状态下,系统可能同时面临:平均 TTFT 增加、P95/P99 TTFT 增加、SLO 违反的请求数增加。

这里同样要注意:M/D/1 上面的公式算的是平均排队等待时间,并不是 P95 或 P99。要得到尾延迟,需要进一步分析等待时间的完整概率分布,或者通过离散事件仿真来统计。

泊松分布在尾延迟分析中的具体作用。 泊松分布并不能直接给出 P95 或 P99,但它提供了请求到达过程的概率模型。结合服务时间分布和排队模型,可以进一步分析:

  1. 不同时间窗口内请求数量的概率分布;
  2. 请求到达的随机间隔;
  3. 请求排队等待时间的分布;
  4. 请求整体延迟的分布;
  5. P95、P99 以及 SLO 达成率。

所以,泊松分布是尾延迟分析的基础之一,而不是尾延迟的直接计算公式。

当然,泊松过程只是对外部请求到达行为的一种建模假设,并不意味着 Prefill 和 Decode 两个阶段的内部任务到达过程也是相互独立的泊松过程。实际系统中还需要考虑请求长度、批处理、阶段间传输和调度策略等因素。

文章小结

总结一下。泊松分布在 LLM 推理系统中的核心作用,是描述外部用户请求的随机到达行为,并为后续排队分析提供数学基础。它本身并不直接计算 GPU/NPU 的计算性能,也不能直接给出 TTFT、TPOT 或 P99——它主要解决的是"请求负载如何随时间随机变化"的问题。在此基础上,结合指数分布描述请求间隔,结合排队模型分析请求等待时间,再结合 Prefill、Decode 的服务时间和调度策略,才能进一步分析系统延迟、尾延迟和 SLO。

所以,理解泊松分布最重要的是掌握下面这条逻辑:

泊松分布:请求数量如何随机变化?→指数分布:请求之间间隔多久?→排队论:请求需要等待多久?→性能分析:请求需要多长时间完成?→SLO:有多少请求能够满足延迟要求?\text{泊松分布:请求数量如何随机变化?} \rightarrow \text{指数分布:请求之间间隔多久?} \rightarrow \text{排队论:请求需要等待多久?} \rightarrow \text{性能分析:请求需要多长时间完成?} \rightarrow \text{SLO:有多少请求能够满足延迟要求?}

这就是泊松分布从概率论走向 LLM Serving 性能分析的完整逻辑。

参考文献

[1] Kleinrock L. Queueing Systems, Volume 1: Theory[M]. New York: John Wiley & Sons, 1975.

[2] Zhong Y, Liu Z, Chen J, et al. DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving[C]// USENIX OSDI, 2024.

[3] Strati A, et al. Efficiently Scaling Transformer Inference[C]// MLSys, 2024.

评论