4. 负载不均的成因分析
多卡推理系统中的负载不均并非单一因素导致,而是并行策略的静态划分与运行时请求的动态变化相互叠加的结果。要定位瓶颈,首先需要建立一张“成因地图”:哪些不均来自模型本身的切分方式,哪些来自数据流的调度方式,哪些来自外部请求的波动,哪些来自硬件资源的隐性争抢。本章从这四个维度逐一拆解。
4.1 模型并行:静态切分带来的固有偏差
模型并行(包括张量并行与流水线并行)在部署时就将网络层或张量维度固定分配到各卡上,这种静态切分天然会产生计算量与显存占用的不均衡。
- 张量并行(TP):按注意力头或权重矩阵列切分。若头数不能被卡数整除,或某些层(如MoE中的专家层)路由不均匀,会导致部分卡承担更多矩阵乘法。
- 流水线并行(PP):按层切分。首尾层(embedding、lm_head)计算量小但显存占用高,中间层计算密集;微批次(micro-batch)在流水线填充和排空阶段会产生“气泡”,靠近流水线末端的卡在稳态时负载更高。
- 专家并行(EP):MoE模型中,不同专家被路由到的数量差异极大,热门专家所在卡的计算量可能是冷门专家的数倍。
典型现象:在8卡A100上部署70B模型,采用TP=8时,若注意力头数为64,每卡分8头,负载均衡;但若头数为80,则前两张卡需多处理8个头,产生约12%的计算偏差。这种偏差在长序列场景下被放大。
4.2 数据并行:动态请求下的分配失衡
数据并行(DP)将不同请求分配到不同卡上,理论上负载均衡,但实际推理中请求的到达间隔、序列长度、生成步数均高度动态,导致各卡实际处理的总量差异巨大。
以典型的动态批处理(continuous batching)为例,调度器按“有可用显存即插入新请求”的策略分配,但各卡显存余量不同、已有请求的剩余生成长度不同,最终可能出现:
- 卡A正在处理一批长序列生成任务(每个请求需解码512 ),而卡B刚完成一批短请求,处于空闲等待状态。
- 若采用轮询(round-robin)分配,未考虑请求的实际计算量,则短请求卡频繁空闲,长请求卡持续满载。
- KV Cache占用不均:长序列请求的KV Cache增长快,导致显存碎片化,后续新请求无法被调度到该卡。
关键指标:观察各卡的“有效计算时间占比”(GPU利用率)与“KV Cache占用率”,两者共同决定数据并行维度的均衡度。仅看GPU利用率会忽略显存瓶颈导致的隐性等待。
4.3 动态请求:突发流量与长尾效应
真实推理场景中,请求到达率服从泊松分布,且存在突发峰值。动态请求对负载均衡的冲击体现在三个层面:
- 突发到达:秒级内涌入大量请求,调度器若来不及分散,会优先填满显存余量最大的卡,造成短时热点。
- 长尾生成:少数请求需要生成极长序列(如文档摘要、代码补全),这些请求长时间占用计算资源和KV Cache,阻塞后续短请求。
- 优先级反转:若启用了优先级队列,高优先级请求会抢占资源,导致低优先级请求所在卡的计算节奏被打乱,产生“饥饿”型不均。
下图展示了动态请求下四卡系统的负载演化过程,可以看到即使初始分配均匀,随着时间推移各卡的计算量差异逐渐扩大:
4.4 资源竞争:隐性瓶颈与干扰
即使并行策略和请求调度都看似均衡,硬件层面的资源竞争仍会造成实际吞吐差异。这类问题最隐蔽,也最容易被忽视。
| 资源类型 | 竞争表现 | 典型场景 | 检测手段 |
|---|---|---|---|
| PCIe / NVLink带宽 | 张量并行通信时,all-reduce操作占用总线;多卡共享同一PCIe switch时,带宽被瓜分 | TP=8的模型在8卡PCIe 4.0 x16上,通信占比超30% | nvidia-smi dmon查看带宽利用率 |
| L2 Cache / 显存带宽 | 相邻SM访问同一显存控制器,产生bank conflict;KV Cache读取频繁时加剧 | 长序列推理时,显存带宽成为瓶颈,计算单元空转等待数据 | Nsight Compute分析memory throughput |
| CPU侧调度 | 数据预处理、tokenizer、采样在CPU执行,CPU核数不足时成为流水线瓶颈 | 高并发短请求场景,CPU占用率100%,GPU等待数据 | top / htop观察CPU占用 |
| 共享电源/散热 | 多卡同时高负载触发功耗墙,部分卡降频运行 | 8卡满载推理,机柜散热不足,GPU时钟从1.4GHz降至1.1GHz | nvidia-smi -q -d CLOCK |
易混淆点:GPU利用率(utilization)高并不代表负载均衡。某卡utilization 95%可能是在等待显存数据(memory-bound),而另一卡utilization 60%却在满负荷计算(compute-bound)。必须结合计算核心活跃度与显存吞吐两个维度综合判断。
4.5 案例复盘:一次“假均衡”的排查过程
某团队部署LLM服务,4卡A100,采用DP=4。监控面板显示四卡GPU利用率均在85%左右,看似均衡,但整体吞吐只有预期的60%。排查过程如下:
- 初步观察:nvidia-smi显示四卡利用率85%~90%,显存占用接近上限。
- 深入分析:使用Nsight Systems抓取时间线,发现每卡的计算间隙(gap)占比高达35%,且间隙出现时间错开。
- 定位根因:CPU侧tokenizer和采样逻辑使用Python多进程,GIL导致CPU处理能力不足。请求在CPU排队,GPU等待数据到达。
- 验证:将tokenizer改为C++实现并增加CPU核数分配后,GPU间隙从35%降至8%,吞吐提升至预期的92%。
复盘要点:负载均衡不能只看GPU维度。CPU预处理、数据加载、通信调度等“外围”环节的瓶颈,会以“GPU利用率虚高但吞吐不足”的假象呈现。排查时应从端到端流水线视角分析,而非孤立观察单卡指标。
4.6 误区与应对清单
- 误区一:只关注GPU利用率。应同时监控显存带宽利用率、NVLink吞吐、CPU占用率。
- 误区二:认为DP天然均衡。动态请求下,必须配合饥饿检测和抢占机制。
- 误区三:忽略通信拓扑。TP通信量与序列长度成正比,长序列时通信占比急剧上升。
- 误区四:静态切分后不再调整。MoE模型的专家热度会随数据分布漂移,需周期性重新分配。
理解上述四类成因后,下一步才能针对性地设计拓扑感知的部署方案——将通信量大的并行组绑定在同一NVSwitch域内,将动态请求调度与硬件拓扑结合,从而在根源上缓解负载不均。