云端AI集群架构:典型架构、组件与资源抽象
核心原理:从物理GPU到可调度资源的三层抽象
云端AI集群的调度瓶颈,往往不是GPU硬件本身失效,而是资源抽象层的设计缺陷。理解集群架构,首先要抓住一条主线:物理资源 → 集群资源 → 工作负载资源的三层映射关系。
- 物理层:GPU(如A100/H800)、NVLink/NVSwitch互联、RDMA网卡、GPU显存、CPU与内存。
- 集群资源层:由Slurm或Kubernetes(K8s)将物理GPU抽象为可分配的单位——Slurm中的
GRES(通用资源)或K8s中的nvidia.com/gpu设备插件资源。 - 工作负载层:训练任务(PyTorch/MPI作业)或推理服务(KServe/Triton)实际申请到的“虚拟GPU视图”,包括显存大小、算力份额、拓扑亲和性约束。
调度器本质上是在第三层做决策,但决策的约束条件来自前两层。如果资源抽象粒度太粗(例如整卡分配),会导致碎片化;太细(例如显存切片)又会引入额外的隔离开销。这是所有调度瓶颈的根源。
关键认知:K8s与Slurm的抽象哲学不同。Slurm面向批量作业,以“节点+任务槽”为调度单位;K8s面向容器化微服务,以“Pod+资源请求”为调度单位。云端AI集群常混合使用两者,形成双层调度架构。
典型架构模式:双层调度与资源池化
生产级云端AI集群普遍采用“K8s在上、Slurm在下”或“K8s统一纳管”两种模式。前者适合传统HPC团队,后者更适合云原生AI平台。
| 架构模式 | 调度单位 | GPU抽象粒度 | 典型瓶颈 |
|---|---|---|---|
| Slurm独立调度 | 作业(Job) | 整卡/GRES | 分区资源碎片化、无抢占 |
| K8s + Device Plugin | Pod | 整卡/显存切片 | 拓扑感知弱、调度延迟高 |
| K8s + Slurm混合 | Pod / Job | 双层映射 | 资源状态同步延迟 |
| K8s + 自定义调度器 | PodGroup | 细粒度(MIG/显存) | 调度器扩展点复杂 |
方法流程:诊断资源抽象层的四步定位法
- 查看资源注册状态:在K8s中执行
kubectl describe node <node-name>,检查nvidia.com/gpu的Allocatable与Capacity是否一致。若不一致,说明设备插件异常或GPU卡被占用未释放。 - 检查调度器视角:使用
kubectl get pods -o wide观察Pending状态的Pod,结合kubectl describe pod查看调度事件中的Insufficient nvidia.com/gpu或NodeAffinity冲突。 - 分析资源碎片:执行
nvidia-smi查看各节点显存使用率。若大量节点剩余显存不足40GB(无法容纳新任务),但总空闲显存充足,则属于碎片化问题。 - 验证拓扑约束:对于需要多卡通信的任务,检查调度器是否感知NVLink拓扑。使用
nvidia-smi topo -m查看GPU间互联类型,确认调度结果是否将任务分配在同一NUMA节点或同一NVSwitch域内。
常见误区:不要只关注GPU使用率而忽略“可调度性”。一个节点即使GPU利用率只有30%,如果显存被碎片化占用(例如多个Pod各占20GB),新的大显存任务依然无法调度。资源抽象层的健康度指标应该是“可调度GPU卡数”而非“GPU利用率”。
案例复盘:某自动驾驶训练集群的调度卡死
现象:团队使用K8s管理32台A100节点,某日提交一个需要64卡(8节点×8卡)的Megatron训练任务,任务一直Pending。
排查过程:
- 第一步:
kubectl describe pod显示0/32 nodes available: 16 Insufficient nvidia.com/gpu, 16 node(s) didn't match topology key。 - 第二步:检查节点状态,发现16个节点各有4~6卡被“僵尸Pod”占用(容器已退出但GPU未释放)。
- 第三步:进一步发现这些僵尸Pod来自上一次失败的MPI作业,由于
device-plugin的清理逻辑缺陷,GPU资源未正确回收。 - 第四步:手动删除残留Pod并重启
nvidia-device-pluginDaemonSet后,资源恢复,任务成功调度。
根因:资源抽象层的“状态同步”机制不完善——K8s的 Device Plugin API 在容器退出时依赖 kubelet 调用 StopContainer 来释放设备,但异常退出(如OOMKill)时该流程可能中断。
优化建议:为GPU资源抽象层增加“定期对账”机制。例如每5分钟扫描一次
nvidia-smi 的进程列表,与K8s的Pod状态进行比对,自动清理孤儿GPU进程。同时为关键训练任务配置 PodDisruptionBudget 和 PriorityClass,避免被低优先级任务阻塞。
资源抽象粒度对比与选型清单
选择何种抽象粒度,直接决定调度瓶颈的表现形式。以下清单可作为架构设计参考:
- 整卡分配:适合大模型预训练,隔离性最好,但碎片化严重。若集群平均任务申请卡数小于节点卡数,浪费率可能超过30%。
- MIG(多实例GPU):适合A100/H100的推理场景,可将物理GPU切分为1/7、1/4等实例。注意MIG不支持显存动态超卖,且切分后无法再合并。
- 显存虚拟化(如vGPU):适合开发测试环境,可超卖显存,但计算性能隔离弱,不适合生产训练。
- 时间片共享:适合推理服务,多个模型共享同一GPU,但需要显存足够容纳所有模型权重,否则会频繁换入换出。
在云端AI集群中,最容易被忽视的是“拓扑感知”这一维度。即使资源数量充足,如果调度器不感知NVLink域、NUMA节点或RDMA网卡亲和性,多卡训练性能可能下降30%~50%。因此,资源抽象不仅要描述“有多少GPU”,还要描述“GPU之间的连接关系”。
最后需要强调:资源抽象层是调度器的“视力”。如果抽象模型不能准确反映物理GPU的实时状态(包括健康状态、拓扑关系、显存分配、算力份额),再优秀的调度算法也无法做出正确决策。在诊断调度瓶颈时,应优先验证抽象层的数据准确性,再深入分析调度策略本身。