
半年前我接手公司 AllData 数据中台的算力管理模块时最头疼的不是数据同步而是大模型训练和推理任务在 GPU 集群上的资源分配。明明集群里塞满了一批 A100 和 4090业务方却还是天天找我要卡可一旦把资源权限放开CPU 和内存又经常先被占满GPU 反而空转。说白了大家习惯把“算力”等同于 GPU 数目但真实的大模型任务消耗的是四类资源GPU 算力、CPU 核数、内存容量、磁盘读写带宽。任何一环跟不上整个任务都会卡死在半路。这次 AllData 数据中台集成开源项目 Crater算是把这个老大难问题从根上梳理了一遍。Crater 把 GPU、CPU、内存、磁盘统一抽象成可调度、可监控、可计量的异构算力资源配合数据中台已有的数据开发、模型训练和推理服务链路能直接支撑 AI 训推一体化算力平台的建设。这篇文章我会把集成过程中的核心思路、资源调度配置、以及实际踩过的坑完整写出来给准备做大模型基础设施或正在选型算力管理方案的团队做个参考。1. 大模型算力管理的现实困境异构资源为何难调度1.1 资源孤岛GPU 之外的管理盲区大部分团队在搭建大模型训练平台时第一反应都是先管 GPU。一张 A100 有多少显存、谁在用、分配给了哪个任务这是最直观的需求。但真实跑一次 7B 或 13B 模型的微调你会发现瓶颈往往不在 GPU 显存上。数据预处理阶段要起多个 DataLoader 进程CPU 核数不够数据加载就是跟不上模型加载和中间激活值要占大量内存内存不足直接触发 OOM训练产生的 checkpoint、日志、数据集缓存又对磁盘容量和 IOPS 提出很高要求。以我们之前跑 Llama 系列微调为例一个 8 卡任务每张卡分配 80GB 显存看起来绰绰有余。但任务提交后节点上的 64 核 CPU 被并行数据预处理打满内存占用飙到 300GB磁盘写入 checkpoint 时 IO 也成了瓶颈。GPU 使用率反而只有 40% 左右每跑一个 step 都要等数据加载。这种资源孤岛效应是传统 GPU 调度工具很少考虑的大家只盯着卡是否空闲忽略了卡旁边还蹲着 CPU、内存、磁盘这三个随时可能卡脖子的角色。1.2 从单机编排到异构资源池关键转变Crater 给我最大的启发是把“一台机器”变成“一组资源维度”。它不再回答“这个任务跑在哪台机器上”而是回答“这个任务需要多少 GPU 算力、多少 CPU 核数、多少内存、多少磁盘带宽然后从资源池里动态切出来”。这个视角的转变非常关键。之前我们内部也试过在 Kubernetes 上用 Device Plugin 管理 GPU但 Kubernetes 原生调度器对 CPU、内存的调度是跟节点绑定的GPU 又是独立资源很难做精细化组合。比如一个推理服务只需要半张卡训练任务需要 4 张卡加 32 核 CPU不同任务对 CPU/GPU 配比差异很大原生调度器做不到这种异构资源组合的灵活分配。Crater 这样的项目等于在资源池层做了一个统一抽象层上层任务声明需求下层通过节点代理采集真实资源水位再由调度器统一决策这才能支撑起训练和推理混合部署的复杂场景。2. Crater 到底解决什么问题核心抽象与资源模型2.1 资源抽象把机器拆成可调度的“算力单元”Crater 的资源模型并不复杂核心是引入了 Resource Slot 的概念。一台物理节点上的 GPU、CPU、内存、磁盘会被划分成多个逻辑上的算力单元每个单元都可以独立分配和回收。你可以把它理解成一台虚拟机超卖机制但维度更多显存切分、CPU 配额、内存限制、磁盘吞吐都纳入了同一个模型。具体到 GPU 管理Crater 支持按卡粒度分配也支持在同一张卡上用 MPSMulti-Process Service或 MIGMulti-Instance GPU做显存切分。MIG 适合 A100、H100 这类支持硬件隔离的卡MPS 则适合消费级显卡或在驱动不支持 MIG 时做软件层面的并发切分。CPU 和内存则通过 cgroup 和任务级配额控制磁盘方面同时管容量和 IOPS避免一个任务写大量日志拖垮整节点。这样一个资源 Slot 可以描述为“2 张 A100 卡 16 核 CPU 64GB 内存 200GB 磁盘空间”任务只需要按需申领 Slot。2.2 动态分配与抢占回收机制相比静态分配Crater 更实用的能力是动态调整。训练任务在热身阶段可能只需要少量显存但到模型并行阶段显存需求会暴涨推理服务则可能出现波峰波谷白天流量大需要更多资源凌晨可以缩容。Crater 允许资源配额在任务运行中动态调整控制面会周期性地检查节点实际使用量再通过在线迁移或分配更多空闲资源来满足变化。抢占回收机制同样重要。比如两个训练任务一个是重要实验另一个是低优先级的探索性任务。当高优先级任务需要更多 GPU 显存时Crater 会先尝试回收低优先级任务占用的资源如果回收失败再把它挂起或重新排队。这种机制在混部场景下特别有用能保证关键训练和线上推理不被突发任务拖垮。3. AllData 数据中台集成 Crater 的落地路径3.1 部署 Crater 控制面与节点代理AllData 数据中台集成 Crater首先要做的不是写代码而是把 Crater 的控制面服务部署起来。控制面包含资源调度器、API Server 和 Web UI负责接收资源申请、维护集群资源拓扑、下发调度决策。每个计算节点需要安装 Crater Agent它负责采集 GPU 状态、CPU/内存使用率、磁盘容量和 IO 指标并把数据上报给控制面。我们当时的部署方式是直接用 Docker Compose 起控制面节点 Agent 用 systemd 托管因为现场很多节点没有 Kubernetes 环境。需要联网下载的依赖不多镜像也比较轻量。有一点要注意Agent 采集 GPU 状态依赖 NVIDIA 驱动和 NVML 库部署前必须确认每台节点的 nvidia-smi 能正常输出否则 Agent 会一直在“GPU 不可用”状态打转。装好之后在控制面执行 agent status 能看到所有节点的资源总览这一步是整个集成的基础。3.2 在中台任务调度层做资源感知AllData 数据中台本身有任务调度模块负责把数据集成、数据开发、模型训练等任务下发到计算引擎。集成 Crater 后我们改造了任务提交入口任务在提交时除了声明执行引擎还要填写资源需求包括 GPU 数量/显存大小、CPU 核数、内存大小、磁盘空间。中台调度模块会把这份资源需求转成 Crater 的资源申请请求等 Crater 返回算力单元分配成功后再真正拉起任务进程。为了让这个过程不打断用户原有操作习惯我们在数据中台的任务配置页里加了一个“算力资源”Tab内置了几个模板单卡微调、多卡 SFT、推理服务、数据预处理等。用户只需要选模板具体参数由系统根据集群水位自动填充也能手工调整。这个改动看似简单但实际避免了用户去理解 Crater 那套资源模型的成本团队在落地时更容易接受。3.3 对接数据开发与模型训练链路集成 Crater 不只是调度层的联动还要把数据开发链路上的产物串起来。模型训练前通常需要做数据清洗、样本切分、特征工程这些任务消耗的是 CPU 和内存资源在 AllData 数据中台里属于数据开发任务。我们把这类任务统一标记为“CPU 密集型”Crater 会优先把它们调度到 GPU 压力较小的节点上避免 CPU 任务抢占训练节点的 CPU 配额。训练任务跑完后生成的模型文件会存到分布式存储或对象存储Crater 在这里只负责磁盘空间和 IO 带宽的分配。我们实践下来建议把训练过程中临时产生的 checkpoint 写到本地高速盘并在任务结束后自动清理避免占满节点磁盘。Crater 在回收算力单元时也会顺带触发清理钩子这一点在配置里要提前写好。4. GPU/CPU/内存/磁盘四类资源的调度配置实战4.1 GPU 显存切分与卡分配策略GPU 调度是需要最谨慎设计的部分。我们内部把 GPU 分配分成两步先切卡再分显存。切卡是决定任务用哪几张物理卡分显存是决定任务在这张卡上能申请多少显存和算力份额。对于训练任务尽量分配整卡因为模型并行和梯度同步对显存稳定性要求高共享显存容易导致显存溢出对于推理任务则优先用 MPS 切分比如一张 80GB 的 A100 可以切成 4 个 20GB 的推理实例部署 4 个小模型。切分时的关键参数是算力配额。MPS 模式下要设置 CUDA_MPS_PINNED_DEVICE_MEM 和 CUDA_MPS_ACTIVE_THREAD_PERCENTAGE分别限制显存和 GPU 算力百分比。如果只限显存不限算力多个推理服务同时跑满 GPU 时会导致核心频率抖动延迟明显上升。Crater 的 GPU 配置支持这两个参数建议在创建算力单元时一并指定不要依赖默认值。4.2 CPU/内存配比训练和推理的差异化需求CPU 和内存配比是另一个容易踩坑的点。训练任务在数据加载阶段需要大量 CPU 做解码、增强、tokenize。我们统计过8 卡 A100 训练任务建议至少配 32 核 CPU 和 256GB 内存否则 DataLoader 会成为瓶颈。如果用的是 PyTorch 的多进程 DataLoadernum_workers 的数量通常需要设置为 CPU 核数的四分之一到二分之一这个值在 Crater 资源申请时可以按需声明。推理任务则相反CPU 需求主要来自持续的 token 生成和大并发请求。特别是跑 vLLM 这类推理引擎虽然计算集中在 GPU 上但 CPU 要处理请求排队、token 采样、KV Cache 管理等逻辑。我们建议每个推理实例至少配 4 核 CPU 和 8GB 内存如果并发请求量高还要额外预留 CPU 用于请求分发。Crater 在调度时会参考请求量和响应时间指标做弹性伸缩但初始配比一定要合理否则后端的弹性调整也救不回来。4.3 磁盘配额与数据缓存设计磁盘是四类资源里最容易被忽略的。大模型训练和推理都会产生大量中间数据比如 HuggingFace 的模型缓存、tokenizer 缓存、训练日志、checkpoint、数据集缓存。Crater 对磁盘同时设了容量和 IOPS 两个维度。容量好理解IOPS 限制却容易漏掉。如果两个任务同时频繁写 checkpoint磁盘 IO 会被瞬间打满影响所有节点上的数据读取。我们的实践是在 Crater 创建算力单元时为每个任务分配独立的本地目录并设置磁盘容量上限。大文件比如模型权重尽量放到共享的模型仓库目录用只读方式挂载避免每个任务都复制一份模型副本。Dataset 缓存也要做分层设计热数据放本地高速盘冷数据放分布式存储。Crater 支持定义不同的磁盘存储类型调度时根据任务的缓存命中需求选择相应节点。5. 训推一体化场景下的混合负载排布与踩坑记录5.1 训练任务和推理服务如何避免互相干扰训推一体化算力平台最核心的挑战是如何让训练任务和推理服务共享同一批资源而不互相拖累。训练任务的特点是阶段性强前向反向计算时 GPU 打满数据加载间隙又有明显空档推理服务则要求低延迟任何一秒的抖动都可能导致线上请求超时。如果混部配置不当训练任务频繁抢占 CPU 或磁盘 IO推理服务延迟就会飙升。我们通过 Crater 的优先级队列做了硬隔离和软抢占的组合。推理服务固定在最高优先级资源配额不可被抢训练任务分两档重要实验可以抢占普通训练任务但永远不能抢占推理服务。GPU 层面上推理服务所在卡不启用 MPS 共享训练任务则调度到另外的卡上。CPU 和内存层面通过 cgroup 限制训练任务最大使用量避免它把节点内存吃光。这套组合实测下来推理服务的 P99 延迟稳定在目标值以内。5.2 排查链路某次 CPU 资源不足导致的推理延迟飙升有个案例很典型某天线上推理服务突然大面积超时推理服务本身的 GPU 利用率只有 30%显存也远没占满表面上看起来完全健康。我们起初怀疑是网络问题排查了半天没有结果。后来看到 Crater 的资源水位监控发现同一节点上多个训练任务的 CPU 使用率已经超过节点总核数的 90%内存剩余不到 10GB。推理服务虽然声明了 4 核 CPU 配额但底层的 token 采样线程和请求调度线程都需要 CPUCPU 不足时它们被 cgroup 限流导致每个请求的处理时长增加了好几倍。这个问题最终通过给 Crater 配置“按节点资源水位动态驱逐”解决当节点 CPU 使用率超过 85% 且推理服务出现 SLO 违约时自动挂起一批低优先级训练任务把 CPU 让出来。同时给所有推理服务增加 CPU 自动扩展的配置动态申请更多核数。排查这类问题单看 GPU 指标一定是找不到方向的必须把四类资源指标放在同一个时间线里对照。5.3 数据缓存命中率低下的根因分析另一个坑出在磁盘缓存设计上。我们一开始把训练数据集集中放在一个分布式存储目录任务启动时先拉取数据到本地磁盘再开始训练。理论上是冷启动数据同步但实际操作中发现很多任务训练到一半又会重新读取同一个数据文件每次都要从远端拉取磁盘容量白白占着缓存命中率却不到 30%。后来我们发现问题是 Crater 的磁盘配额和节点数据目录绑定得太紧任务结束后目录被清理缓存也就没了。改成用共享的热数据盘目录存放常用数据集并让 Crater 在算力单元回收时跳过该目录后命中率才升到 80% 以上。这也算是一个教训资源调度平台只负责分配资源缓存策略还是要结合业务数据访问特点单独设计。6. 性能观测、成本治理与后续扩展思路6.1 观测指标与告警阈值AllData 中台集成 Crater 后我们搭建了一套资源观测大盘核心指标包括每类资源的分配率、利用率、等待队列长度、节点资源碎片率。分配率反映的是资源被占用的比例利用率反映的是实际跑任务时用到的比例。很多平台分配率很高但利用率很低本质是资源碎片化严重比如一个任务申请了 2 张卡却只用了一张卡的 60% 算力。我们设置的告警阈值是GPU 利用率低于 30% 持续 15 分钟触发警告CPU 使用率超过节点 85% 持续 5 分钟触发“可能影响推理”告警内存使用率超过 90% 触发紧急告警磁盘 IOPS 达到配额上限的 80% 时提醒调整缓存策略。这套告警规则跑了一个多月最有价值的是提前发现了多个节点因日志文件增长导致的磁盘容量告警避免了真实故障。6.2 成本视角算力碎片化和配额治理算力碎片化是异构资源池必须面对的成本问题。举例来说一张 A100 可以切成 4 个推理实例但如果每个实例申请的是 22GB 显存那这张卡的剩余显存就只剩 12GB既不够再开一个实例也浪费了有效算力。Crater 的 Web UI 会展示每张卡的“碎片余量”我们调整了很多任务的显存申请规格尽量向 20GB、40GB 这种整除数靠拢碎片率下降了接近一半。配额治理方面我们给每个业务线设定了月度资源预算Crater 支持按租户统计 GPU/CPU/内存/磁盘的总消耗量和时间分摊费用。这一步对内部成本核算特别有用业务方自己也能看到消耗最高的任务是什么。每个月我们都会根据资源利用率报表把闲置超过 7 天的训练任务配额回收清零避免资源被“占着不用”。6.3 后续可以扩展的方向Crater 目前解决了异构算力的统一调度和生命周期管理但还有几个方向值得继续深挖。第一个是推理服务的自动扩缩容策略目前的弹性伸缩还比较粗放后续可以根据请求量、GPU 利用率、响应延迟等指标做更细粒度的自动伸缩。第二个是对国产 GPU 和加速卡的支持大模型部署不一定全用 NVIDIA 卡Crater 如果能通过统一的资源抽象兼容更多硬件适用范围会大得多。第三个方向是把算力调度和数据调度打通。现在 AllData 数据中台的任务调度和 Crater 算力调度是两层配合但还没有做到数据本地性和算力调度联合优化。比如任务需要处理的数据只存在某个节点的本地磁盘上Crater 如果能优先把这个任务调度到对应节点会显著减少数据迁移开销。这个功能我们正在做原型验证等稳定后再找机会分享。回到开头那个问题算力不等于 GPU 卡数而是 GPU、CPU、内存、磁盘的综合组合。AllData 数据中台集成 Crater 之后我们总算能在一个平台上把这些资源统一管起来训练任务和推理服务也不用再像以前那样抢地盘了。如果你也在做类似的大模型基础设施我的建议是先别急着上多复杂的调度算法先把你现有的任务按资源需求摸清楚再逐步把四类资源的配额模型建立起来这会比直接引一整套新系统稳妥得多。