3. 资源碎片化定义:碎片化类型与成因分析
3.1 资源碎片化的本质定义
在GPU集群管理中,资源碎片化是指集群中可分配的GPU资源(显存、计算单元、网络带宽)因分配与释放的不均匀,形成大量总量充足但无法被有效组合利用的零散空闲资源。其核心矛盾在于:单个资源维度上仍有空闲容量,但多维资源组合后无法满足任何作业的完整需求,导致集群整体利用率下降。
与CPU集群不同,GPU作业通常以整卡或卡上切片(MIG/时间切片)为调度单位,且作业对显存、算力、网络三者有强耦合需求。因此,GPU碎片化往往表现为“显存够但卡数不够”“卡数够但显存不足”“算力空闲但显存被占”等错配状态。衡量碎片化程度的关键指标包括:碎片率(不可分配空闲资源 / 总空闲资源)、可分配率(满足某类作业需求的空闲资源比例)以及装箱效率(实际分配资源 / 理论可分配资源)。
3.2 三大碎片化类型详解
根据GPU资源的不同维度,碎片化可分为以下三类,它们往往相互交织、互为因果。
3.2.1 显存碎片(Memory Fragmentation)
显存碎片是最直观、最常见的碎片化形式,指GPU卡上的显存空间被分割为多个不连续的小块,无法满足大显存作业的需求。它包含两种子类型:
- 内部碎片:作业申请显存时按固定粒度(如MIG的1g/2g/4g切片)分配,作业实际使用量小于分配量,造成“分配了但没用上”的空间浪费。例如,一个需要3.5GB显存的作业,若只能分配4GB切片,则产生0.5GB内部碎片。
- 外部碎片:多作业在不同时间申请和释放显存后,空闲显存被分割成多个不连续区域。例如,某卡总显存80GB,作业A释放了前40GB,作业B仍占用后40GB,此时虽有40GB空闲,但若新作业需要50GB连续显存,则无法分配。
3.2.2 计算碎片(Compute Fragmentation)
计算碎片指GPU的计算单元(SM/CUDA Core)利用率不均衡,导致算力资源无法被充分利用。常见场景包括:
- 算力与显存不匹配:作业占用了大量显存但仅使用少量计算单元(如数据预处理型作业),或反之(如纯计算密集型作业显存占用低)。调度器若只按单一维度分配,就会造成另一维度空闲。
- 时间维度碎片:作业在运行过程中计算负载波动(如训练中周期性评估、数据加载阶段),导致GPU在部分时间段算力闲置,但显存仍被占用,无法被其他作业抢占。
- MIG切片粒度限制:当MIG切片类型(如1g.5gb、2g.10gb)与作业需求不完全匹配时,即使总算力充足,也可能因切片组合方式受限而产生计算碎片。
3.2.3 网络碎片(Network Fragmentation)
网络碎片是分布式训练场景下特有的碎片化类型,指集群中GPU间的高速网络(NVLink、InfiniBand、RoCE)带宽或拓扑连接资源被分割,导致无法为作业提供所需的集合通信拓扑。其典型表现包括:
- 拓扑碎片:多租户共享集群时,作业A占用了部分节点的GPU,作业B的GPU虽空闲但分布在非连续节点上,无法形成高带宽的NVLink域或胖树拓扑,导致作业B无法获得预期的通信性能。
- 带宽碎片:作业占用了部分网络端口或交换机上行链路,但实际通信量低;而其他作业需要高带宽通信时,却发现可用带宽已被“预留但未使用”的连接占用。
- 通信域碎片:在RDMA或集合通信库(NCCL)初始化时,需要一组GPU构成通信域。若空闲GPU分散在不同交换机下,跨交换机通信延迟增加,作业可能因性能不达标而拒绝调度。
3.3 碎片化成因的系统性分析
碎片化的产生并非单一因素所致,而是作业特征、调度策略、硬件架构、集群运营四方面因素共同作用的结果。下表归纳了主要成因及其作用机制:
| 成因类别 | 具体因素 | 影响机制 | 典型表现 |
|---|---|---|---|
| 作业特征 | 需求多样性 | 不同作业对显存/算力/网络比例需求差异大,难以完全匹配 | 推理作业显存高算力低,训练作业反之 |
| 生命周期差异 | 长时训练与短时推理混布,释放时间不协调 | 短作业释放后留下“空洞” | |
| 调度策略 | 分配粒度粗放 | 整卡分配或固定MIG切片,无法按需精细切分 | 8卡作业占用后剩余7卡无法利用 |
| 缺乏多维协同 | 调度器仅考虑单一维度(如显存),忽略算力/网络 | 显存满足但算力不足,作业排队 | |
| 硬件架构 | MIG切片固定 | 切片类型有限(1g/2g/4g),无法覆盖所有需求 | 3.5GB作业只能分配4GB切片 |
| 拓扑约束 | NVLink域、交换机层级限制作业放置位置 | 跨节点作业通信性能下降 | |
| 集群运营 | 预留策略保守 | 为保障高优作业SLA,预留大量空闲资源 | 预留池资源利用率长期低于30% |
| 缺乏碎片整理 | 未定期执行资源 compaction 或作业迁移 | 碎片持续累积,利用率逐步下降 |
3.4 典型场景复盘:一次碎片化引发的调度失败
某集群共有32张A100-80GB GPU,分布在4台8卡服务器上(每台服务器内部NVLink全互联,服务器间通过InfiniBand连接)。某时刻集群状态如下:
- 服务器1:作业X占用6卡(每卡显存40GB),空闲2卡
- 服务器2:作业Y占用4卡(每卡显存60GB),空闲4卡
- 服务器3:作业Z占用8卡(每卡显存20GB),空闲0卡
- 服务器4:完全空闲8卡
此时新到达一个分布式训练作业W,需求为8卡 × 每卡70GB显存,且要求8卡在同一NVLink域内(即同一台服务器)。调度器分析发现:
- 服务器1空闲2卡,显存80GB/卡,但卡数不足8张;
- 服务器2空闲4卡,显存80GB/卡,但卡数不足8张;
- 服务器4空闲8卡,显存80GB/卡,完全满足需求。
作业W最终被调度到服务器4,看似没有问题。但若服务器4已被其他作业预留(例如作业V将在10分钟后到达,需要8卡×80GB),则调度器面临两难:分配给W则V无法运行,预留则W等待。这种时间维度上的碎片化在真实集群中极为常见。
3.5 碎片化程度的量化评估方法
为有效管理碎片化,需要建立量化指标。推荐采用以下评估流程:
- 定义作业模板:将集群中的作业按资源需求特征聚类为若干典型模板(如“训练-大显存”“推理-小显存”“数据并行-高网络”等),每个模板包含显存、算力、网络需求及拓扑约束。
- 计算可分配性:对每个模板,扫描集群当前空闲资源,判断是否存在满足该模板全部约束的分配方案。若存在,则该模板对应的空闲资源为“可分配”;否则为“碎片化”。
- 计算碎片率:碎片率 = 1 - (所有模板可分配资源量之和 / 总空闲资源量)。碎片率越高,说明资源浪费越严重。
- 持续监控:将碎片率作为集群健康度指标,按小时/天粒度记录,观察趋势变化。
# 伪代码示例:碎片率计算逻辑
def compute_fragmentation(cluster_state, job_templates):
total_free = sum(cluster_state.free_resources())
allocatable = 0
for template in job_templates:
# 尝试为模板分配资源(模拟调度)
placement = try_schedule(cluster_state, template)
if placement.success:
allocatable += template.total_resource_demand()
fragmentation_rate = 1 - (allocatable / total_free)
return fragmentation_rate
3.6 碎片化与调度策略的关联
碎片化程度直接受调度策略影响,二者形成反馈循环:调度策略不当会加剧碎片化,而碎片化又会限制后续调度的灵活性。常见的策略影响包括:
- 贪心调度(First-Fit):优先将作业放在最早可用的资源上,容易在集群中形成“先来先占、零散分布”的局面,加剧拓扑碎片。
- 最佳适配(Best-Fit):将作业放在最接近其需求大小的空闲块上,可减少外部碎片,但可能增加作业排队时间。
- 预留策略:为高优先级作业预留资源,若预留过多或时间过长,会人为制造碎片化。
- 迁移与整理(Compaction):定期将作业迁移到连续资源上,合并空闲块,但迁移本身有成本和风险。
因此,碎片化治理不能仅靠事后整理,更需要在调度器设计阶段就引入多维资源协同分配和拓扑感知机制,从源头减少碎片产生。