0%

大模型推理服务,为什么不一样

大白话

大模型推理,本质上是一个批处理计算。

因为读取的权重参数非常多,显存带宽不够用了,希望每次读取的参数,可以多进行几次计算,以提高计算强度。

再加上自回归计算特征,每次计算只产生一个 token(算上投机采样,通常也只有几个 token),因此,提升请求的并发度就很有必要了。

显存带宽

以 GLM 5.2 为例:753B 参数、40B 激活;FP8 精度;hidden size 6144;一共 78 层、前三层 Dense;256 个 routed 专家、激活 8 专家、共享专家一个;稀疏注意力取 top 2048,IndexShare 每 4 层共享 1 indexer。

单个请求,Decode 产生一个 token,至少需要读取 40B 参数量,FP8 下一个参数一个字节,也就是 ~40GB。

其中:

Attention(78 层合计): 12.872B

DSA Indexer(21 个合计): 0.197B

前 3 层 Dense FFN: 0.679B

75 层 MoE: (8×37.749 + 37.749 + 1.573) × 75 = 25.598B

这里单个专家 37.749M = 3 × 6144 × 2048(gate/up/down 三个矩阵,专家中间层 2048),1.573M 是 router = 256 × 6144。

LM Head: 0.952B

合计:12.872+0.197+0.679+25.598+0.952 = 40.298B

当 Batch 增大时,假设 routing 是均匀的,被激活的 routed 专家数量是:Expert(B) = 256 * (1 - (31/32)^B)

激活参数量(即单 token 的显存读取量)是:Active(B) = 17.649 + 2.831 * Expert(B)

画成走势图,就是:

batch 与显存带宽开销

除了权重,Decode 还要读 KV cache;好在稀疏注意力只读 top 2048 的 KV:576×2048×2 × 78 ≈ 0.18GB/token,相比 40GB 的权重读取是小头。

不过,DSA Indexer 为了选出 top 2048,还要扫描全量 Context:21×128×2 × L × B

平均 context 128k,10 batch,也有 6.9GB,也是不小的开销。

计算

还是先从单 batch 开始,计算量分为三个部分:

线性计算,包括:Dense / MoE / Projection 计算,40B 激活 => 80 GFlops

DSA Indexer 计算量:按照 128k context 计算:2×32×128×131072×21 = 22.5 GFlops

Sparse MLA 的计算量:(2×64×2048×576 + 2×64×2048×512) × 78 = 22.2 GFlops

合计:125 GFlops

也就是说,单 batch 下计算强度只有 125 GFlops / 40 GB ≈ 3 FLOP/Byte,远低于主流 GPU 的拐点(数百 FLOP/Byte),是纯粹的带宽 bound。

但是,当 Batch 增大时,计算量是几乎线性增长的(每个 token 的计算互相独立),而显存读取量却像上面的走势图一样逐渐饱和。

所以,计算强度可以随着 batch-size 的增加,持续增大。不过即使 B=128,计算强度也只有 ~22 FLOP/Byte,仍然没有脱离带宽 bound 的区间。

GPU Tensor Core

以上是大模型计算的理论分析,实际上在真实 GPU 硬件也是大 batch-size 友好的。

Tensor Core 的矩阵乘法,是有固定的一些 shape 的。

比如 m64n8k32,一条指令处理 M=64 行;batch-size 不足 64(或不是 64 的整数倍)时,多余的 lane 在空转,等效 MFU 就被拉低了。

对 MoE 层来说更苛刻:平均每个 routed 专家只分到 B×8/256 = B/32 个 token,要让每个专家都喂满 m64,batch-size 得到 2048 才行,这也是推理引擎喜欢超大 batch 的一个原因(当然,实际上是远不会跑到这么大的)。

当然,针对 Prefill 阶段,因为可以有很长的 context,可以切分到 M,所以单 batch-size 也是 Tensor Core 友好的。

对于网关的影响

对于通算的在线服务,通算网关通常按照流量(请求量)做好均衡,每个服务实例的负载就是均衡的了。

本质上,推理网关承担的,不再是请求流量的分配,而是推理任务的调度。

从全局来看,推理网关的全局调度,与推理引擎上的本地调度器,共同完成了集群级推理请求(计算任务)到 token 粒度 GPU 执行的调度。

作为全局调度器,推理网关,核心价值主要是两个:

  1. 降低时延(通过负载均衡)
  2. 降低成本(满足 SLO 的前提下)

对于单个推理服务实例而言,batch-size 是影响服务时延、吞吐的重要因素。

对于推理网关而言,控制好每个推理服务实例的 batch-size 就很重要了。

除了 batch-size,当然还有其他的因素也是需要综合考虑的,留着下篇再写了。