在 AI for Science 平台落地异构调度:从「数据搬运工」到「算力调度器」的架构重构实录
在 AI for Science 平台落地异构调度从「数据搬运工」到「算力调度器」的架构重构实录上周有个需求砸下来院里新建的 AI for Science 协作平台要上线对外开放支撑分子动力学MD长周期模拟与大模型预训练混部。测试环境跑通的流程一到生产环境就炸——不是 OOM 就是存储 IO 打满研究员提个任务排队 6 小时起步跑俩小时挂了还得从头来过。项目背景简单交代上海某研究院自建算力集群约 200 张 H800 500 张 A800存储端挂着 3PB CephFSCeph 18.2.2 Quincy和 200TB Alluxio 缓存层。技术栈锁定在 Kubernetes 1.29.4、Slurm 23.11.8、KubeRay 1.1.0、Spring Boot 3.3.2JDK 21.0.3、Fluid 0.9.0Alluxio Runtime 2.9.3。核心痛点不在模型算法而在异构负载下的数据亲和性调度与有状态长任务的生存保障。背景混部场景下的「三高」噩梦先说业务画像。分子动力学典型作业单任务跑 7×24 小时甚至数周MPI 进程间通信极其敏感中断一次等于白跑Checkpoint 文件动辄 2TB大模型预训练则是 Gang Scheduling 启动PyTorch DDP NCCL对带宽抖动零容忍但支持 Tensor Parallel 切分、支持频繁torch.save。这俩负载混在同一套 K8s 集群里还要套一层多租户配额研究组级别Slurm 管着裸金属 MPI 任务K8s 管着容器化训练任务中间隔着一层自研的统一提交网关。测试阶段没暴露问题因为测试数据集小、并发低、无抢占。真实上线第一周三个指标扎眼跨节点数据拉取占任务总耗时 68%Alluxio 缓存命中率仅 12%万兆网卡跑满却喂不饱 GPU。Slurm 抢占 K8s 任务导致 PyTorchJob 重启率 43%无法恢复研究员直接在群里骂娘。配额失效A 组提交 50 张卡的 RayJobB 组 8 张卡的 MD 任务排队饿死Kueue 的 ClusterQueue 配置在 Gang Scheduling 面前形同虚设。过程把「数据搬到算力」改成「算力贴着数据转」1. 调度层拆解别让 K8s 调度器干不擅长的事最早想用 K8s 原生kube-schedulerSchedulerPlugin解决数据亲和性写了个PreFilter插件去查 FluidDatasetCR 的status.nodes字段再给 Pod 打nodeAffinity。压测发现调度延迟 P99 从 200ms 飙到 3.4s因为每个 Pod 创建都要 List 所有 Dataset CR、计算拓扑距离、打分排序调度器主线程被卡死。换路子了。引入Scheduler ExtenderHTTP 扩展器做「粗筛」只在Filter阶段调用逻辑下沉到独立 Go 服务scheduler-extender-v0.3.1缓存 Dataset 节点分布在本地 RedisValkey 7.2.5单次请求 15ms 以内。K8s 原生插件只保留Score阶段做微调。java// Spring Boot 网关侧任务提交时自动注入数据亲和性标签不依赖用户手填 YAMLRestControllerRequestMapping(/api/v1/jobs)RequiredArgsConstructorpublic class JobSubmitController {private final FluidDatasetClient fluidClient; // Feign 调用 Fluid Controllerprivate final SchedulerExtenderClient extenderClient;private final KubernetesClient k8sClient;PostMappingpublic ResponseEntity submit(Valid RequestBody JobSubmitRequest req) {// 1. 解析数据集引用查询 Fluid 缓存分布List datasetNames req.getDatasetRefs();Map datasetNodeMap fluidClient.getCachedNodes(datasetNames);if (datasetNodeMap.isEmpty()) {throw new BusinessException(DATASET_NOT_CACHED, 目标数据集未预热至任何节点请先提交预热任务);}// 2. 计算最优节点集合交集优先并集兜底Set candidateNodes computeOptimalNodes(datasetNodeMap, req.getGpuCount());// 3. 构建 PodSpec注入 nodeAffinity tolerations专用节点池污点Pod jobPod buildPodSpec(req, candidateNodes);// 4. 根据负载画像分发MPI - Slurm OperatorDDP/Ray - Kueue K8s JobSetif (req.getWorkloadType() WorkloadType.MPI_MD) {return submitToSlurm(jobPod, req);}return submitToKueue(jobPod, req);}private Set computeOptimalNodes(Map datasetNodeMap, int gpuCount) {// 简单启发式求交集不足则按缓存完整度评分取 Top-Nreturn datasetNodeMap.values().stream().reduce((a, b) - a.stream().filter(b::contains).collect(Collectors.toList())).orElseGet(() - datasetNodeMap.values().stream().flatMap(List::stream).collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().sorted(Map.Entry.comparingByValue().reversed()).limit(gpuCount / 8 2) // 每节点 8 卡冗余 2 个节点.map(Map.Entry::getKey).collect(Collectors.toSet()));}} 这个方案虽然官方文档不推荐 Extender维护成本高但在我们「数据集固定、节点拓扑变化慢」的场景下比插件模式稳得多。插件模式适合通用调度器开发我们是业务侧深度定制别被「最佳实践」绑架。2. 抢占与生存CRIU 在 GPU 场景是个坑应用层 Checkpoint 才是正解Slurm 抢占 K8s 任务最初想用 CRIU (3.17.1) 做容器级热迁移/检查点。实测发现CRIU 根本 Dump 不下来显存状态cuda-checkpoint只能存 host 侧内存恢复时 NCCL Communicator 直接炸报ncclInternalError。折腾两周放弃。转而强制要求业务侧实现应用层 Checkpoint 接口平台侧只负责「发信号、存制品、拉起新实例」。yamlKueue JobSet 模板定义 PreStop Hook 共享 PVC 挂载 Checkpoint 目录apiVersion: jobset.x-k8s.io/v1alpha2kind: JobSetmetadata:name: ${{JOB_NAME}}spec:replicatedJobs:name: workerreplicas: ${{GPU_COUNT}}template:spec:serviceAccountName: jobset-sarestartPolicy: OnFailurevolumes:name: ckpt-volumepersistentVolumeClaim:claimName: ${{PVC_NAME}}containers:name: trainerimage: ${{IMAGE}}command: [bash, -c, torchrun --standalone --nnodes1 --nproc_per_node8 train.py --ckpt-dir /ckpt]volumeMounts:mountPath: /ckptname: ckpt-volumelifecycle:preStop:exec:command: [/bin/sh, -c, touch /ckpt/SIG_CHECKPOINT sleep 120] # 留 2 分钟刷盘env:name: PLATFORM_CHECKPOINT_SIGNALvalue: SIGUSR1 # 应用层监听信号触发 torch.save平台侧控制器job-lifecycle-controller v0.4.0监听PodDeletionTimestamp发现被抢占立即Patch PodterminationGracePeriodSeconds180防止默认 30s 截断。向容器发SIGUSR1业务代码捕获后执行torch.save({model: ..., optimizer: ..., rng: ...}, f/ckpt/ckpt_rank{dist.get_rank()}_step{step}.pt)。等待SIG_CHECKPOINT文件出现或超时再允许 Pod 彻底终止。重建 JobSet 时initContainer自动探测/ckpt最新 step传入--resume-step启动。效果MD 任务虽不支持热迁移但应用层每 30 分钟落盘一次PLUMEDRESTART关键字抢占恢复仅丢 ≤30 分钟算力研究员能接受。3. 多租户配额Kueue Slurm 统一视图的「伪全局调度」Kueue 管不了 SlurmSlurm 管不了 K8s。搞了个中间层quota-syncerGo 协程每 10s 跑一次从 Slurmsacctmgr show assoc formataccount,GrpTRESMins拿各账户已用 GPU 分钟数。从 KueueClusterQueue.status.flavors[].used拿 K8s 侧占用。汇总写入 Redisquota:{org_id}:used_gpu_minutes提交网关准入时只看这键。go// quota-syncer 核心同步逻辑片段func (s *Syncer) syncLoop() {ticker : time.NewTicker(10 * time.Second)for range ticker.C {slurmUsage, _ : s.slurmClient.GetAccountUsage() // map[org]float64 (gpu-min)kueueUsage, _ : s.kueueClient.GetClusterQueueUsage() // map[org]float64merged : make(map[string]float64)for k, v : range slurmUsage { merged[k] v }for k, v : range kueueUsage { merged[k] v }pipe : s.redis.Pipeline()for org, used : range merged {limit : s.getQuotaLimit(org) // 从 CM 读配额上限pipe.Set(ctx, fmt.Sprintf(quota:%s:used, org), used, 0)pipe.Set(ctx, fmt.Sprintf(quota:%s:limit, org), limit, 0)// 提交网关 Lua 脚本原子检查if used request limit then reject}_, _ pipe.Exec(ctx)}}提交网关侧 Lua 脚本保证原子性lua-- check_and_consume_quota.lualocal used_key KEYS[1]local limit_key KEYS[2]local request tonumber(ARGV[1])local used tonumber(redis.call(GET, used_key) or 0)local limit tonumber(redis.call(GET, limit_key) or 0)if used request limit thenreturn {0, used, limit} -- 拒绝endredis.call(INCRBY, used_key, request)return {1, used request, limit} -- 通过方案对比为何放弃「全 K8s」与「全 Slurm」| 维度 | 纯 K8s (Kueue JobSet MPI Operator) | 纯 Slurm (Pyxis Enroot) |混合模式当前落地|| :--- | :--- | :--- | :--- ||MPI 通信性能| 依赖 HostNetwork 手动亲和性NCCL 拓扑感知弱 | 原生srun --mpipmi2拓扑感知最优 |Slurm 独占 MPI 池零损耗||容器化生态兼容| 原生支持 Ray/PyTorchJob/KubeFlow | 需 Enroot 转镜像调试链路长 |K8s 侧原生Slurm 侧仅跑传统 MPI||抢占/回收粒度| Kueue Preemption 支持优先级但 Gang Scheduling 易死锁 | Slurm 抢占成熟但无感知容器状态 |分域抢占Slurm 抢 SlurmKueue 抢 K8s跨域仅配额联动||数据亲和性调度| Scheduler Plugin/Extender 灵活 |sbatch --constraint表达力弱 |Extender Fluid 缓存感知跨域数据预热走统一 DataLoad Job||运维复杂度| 单一栈但 MPI Operator 仍不稳定 (v0.7.0) | 成熟稳定但容器化体验差 |双栈运维成本 30%换取业务零改造上线| 别信「一套调度器走天下」。MPI 死磕 K8s 是给运维找罪受PyTorch 死磕 Slurm 是给研发找罪受。分域治理、配额联动、数据解耦才是混部的务实解。效果数字说话上线 3 周观测窗口2026-07-01 至 2026-07-21对比重构前基线| 指标 | 重构前 | 重构后 | 变化幅度 || :--- | :--- | :--- | :--- ||平均数据加载耗时首轮 Epoch/Step| 2h 14min |18min|↓ 86.5%||Alluxio 缓存命中率| 12% |91%|↑ 79pp||任务排队 P99 时长| 4h 12min |19min|↓ 92.4%||抢占导致的有效算力损失| 100%全量重跑 |≤ 30min/次|↓ 99%||集群 GPU 平均利用率| 45% |78%|↑ 33pp||跨租户配额争抢投诉| 日均 6 单 |0 单|清零|存储侧顺带优化了 Cephosd_op_threads8、bluestore_min_alloc_size64K针对 2MB 大块顺序读配合 Alluxioalluxio.user.file.readtype.defaultCACHE_PROMOTE单节点顺序读吞吐从 3.2 GB/s 稳在 9.8 GB/s接近 100Gbps 网卡物理上限。总结后端架构的「确定性」不在模型层在调度层这回重构的核心心得就三条数据亲和性调度必须下沉到 Extender/Operator 层别指望业务侧写nodeSelector也别指望通用调度器插件能扛住高并发打分。GPU 任务的 Checkpoint 是应用层契约不是基础设施魔法。CRIU 在显存面前失效强制约定SIGUSR1torch.save/ PLUMED RESTART平台只负责信号传递与制品版本管理。异构集群别强行合一Slurm 管 MPI、K8s 管 Cloud-Native Training配额层做最终一致性同步即可别试图搞统一调度器那是架构师的自嗨不是工程师的交付物。下一步打算把quota-syncer替换成基于 KueueAdmissionCheck的原生准入链路把 Slurm 用量作为外部指标喂给 Prometheus Adapter再砍掉一层 Redis 中间商。不过那是下个迭代的事了——当下集群跑稳了研究员不骂娘了这才是后端交付的硬指标。#后端 #Java #SpringBoot #Kubernetes #Slurm #AI4S #异构调度你在实际项目中有遇到类似问题吗欢迎在评论区分享你的经验和解决方案。

相关新闻

KMS_VL_ALL_AIO:Windows与Office智能激活技术的深度解析

KMS_VL_ALL_AIO:Windows与Office智能激活技术的深度解析

KMS_VL_ALL_AIO:Windows与Office智能激活技术的深度解析 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 在当今数字化办公环境中,Windows操作系统和Microsoft Office套件…

2026/7/31 1:13:55 阅读更多 →
Navicat重置工具:轻松实现Mac版无限试用的完整指南

Navicat重置工具:轻松实现Mac版无限试用的完整指南

Navicat重置工具:轻松实现Mac版无限试用的完整指南 【免费下载链接】navicat_reset_mac navicat mac版无限重置试用期脚本 Navicat Mac Version Unlimited Trial Reset Script 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 还在为Navicat…

2026/7/31 1:13:55 阅读更多 →
支付宝前端大神集体转型Agent开发,小白也能抓住下一个程序员黄金赛道!

支付宝前端大神集体转型Agent开发,小白也能抓住下一个程序员黄金赛道!

支付宝顶尖前端团队转型Agent开发,引发行业关注。文章分析了Agent开发的兴起原因,包括AI编程工具的普及、企业对能交付AI产品的人的需求增加以及Agent开发的商业价值。Agent开发全栈工程师需要前端、后端和AI能力,能够独立交付企业级Agent&am…

2026/7/31 1:13:55 阅读更多 →

最新新闻

MaixCAM与无刷电机云台视觉跟踪系统开发实战

MaixCAM与无刷电机云台视觉跟踪系统开发实战

1. 项目背景与需求分析在嵌入式视觉项目中,云台控制系统是实现目标跟踪、图像稳定的关键技术组件。传统舵机云台存在精度低、响应慢、易抖动等问题,而无刷电机凭借高扭矩、低噪音、长寿命等优势,正逐渐成为高性能云台的首选驱动方案。轮趣无刷…

2026/7/31 2:21:16 阅读更多 →
RAG 入门到精通 - Rerank  Hybrid Search

RAG 入门到精通 - Rerank Hybrid Search

在前两天的版本中,我一直在重复地进行评估 - 补数据 - 重建数据集。 看上去像是在告诉大家只要数据整好了,RAG就可用了。但是,真实情况不是这样。 之所以我在不停的补数据,其实是因为自己还是有一点咖啡知识的。作为一个手冲咖啡党…

2026/7/31 2:21:16 阅读更多 →
DNF私服技术架构解析:从70版本微变到安徒恩副本稳定性

DNF私服技术架构解析:从70版本微变到安徒恩副本稳定性

如果你是一位资深 DNF 私服玩家,最近可能已经注意到一个现象:打着"70版本""异界套""安徒恩"旗号的服务端如雨后春笋般涌现。但真正能稳定运行一年以上的服务器却凤毛麟角。今天要分析的"王者归来新开70dnf经典微变&q…

2026/7/31 2:21:16 阅读更多 →
模拟优选算法:从原理到工业级实现

模拟优选算法:从原理到工业级实现

1. 为什么我们需要模拟优选算法?在计算机科学领域,算法优选是个永恒的话题。想象你面前有10条不同的路线可以回家,有的距离短但红绿灯多,有的绕远但全程高速,还有的可能正在施工——这就是算法优选要解决的典型问题。而…

2026/7/31 2:21:16 阅读更多 →
从游戏残局到团队协作:静音协作法解决信息过载

从游戏残局到团队协作:静音协作法解决信息过载

那天晚上,我正打着一局残局,队友突然在语音里喊:“你别动!放着我来!” 紧接着就是一阵密集的枪声和指挥。结果呢?他冲出去不到三秒就倒了,还怪我没跟上。那一瞬间,我脑子里就一个念头…

2026/7/31 2:21:16 阅读更多 →
零基础转行网络安全,普通人如何靠挖漏洞实现收入逆袭

零基础转行网络安全,普通人如何靠挖漏洞实现收入逆袭

行业风口:普通人转行的最佳窗口期在当前的就业环境下,许多非计算机专业出身的朋友都在寻找新的职业突破口。网络安全领域正迎来一个前所未有的爆发期,这并非空穴来风,而是由政策驱动和市场刚需共同作用的结果。随着《网络安全法》…

2026/7/31 2:20:16 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻