OpenResearch 的 Slurm 后端:用 `orx exp run --backend slurm` 把实验批量提交到 HPC 集群 📅 发布时间:2026/9/20 4:18:16 👁 浏览次数: OpenResearch 的 Slurm 后端用orx exp run --backend slurm把实验批量提交到 HPC 集群【免费下载链接】OpenResearchTurn your coding agents into research agents项目地址: https://gitcode.com/GitHub_Trending/op/OpenResearch导读本指南讲解 OpenResearch 项目orx命令行工具内置的 Slurm 计算后端--backend slurm如何通过一条orx exp run命令把实验分支的已提交快照经 SSH 传送到集群登录节点并以sbatch提交为批处理作业。读完本文你将掌握--host、--flavor、--timeout等关键参数的语义理解提交、轮询、取消、日志流式传输的完整调用链与状态判定原理并学会通过slurm.json固化集群默认配置、用orx exp wait/orx exp wake编排等待策略。本文以 slurm.md 为骨架展开源码级佐证来自 src/jobs/slurm.rs、src/local/slurm.rs、src/jobs/ssh.rs 与 src/main.rs。一、什么时候该用 Slurm 后端orx的 compute 技能SKILL.md把后端路由规则写得很明确只有在用户显式要求使用其 Slurm 集群、或 Slurm 是会话中配置的默认后端时才走--backend slurm。其他时候不要因为恰好有 SSH 凭据就切换后端。Slurm 后端的整体工作方式是orx通过 SSH 到达集群登录节点login node在登录节点暂存stage实验分支的已提交快照用sbatch把固定的运行命令作为批处理作业提交给调度器。与 HF / Modal 这类按机器形态machine shape选择算力的后端不同Slurm 后端没有选一台机器的概念——CPU/内存由分区partition与集群默认策略决定orx只负责表达 GPU 请求GRES与时间上限。二、快速上手两条命令原文档给出的最小用法如下orx exp run expId --backend slurm --host login-node --flavor h100:2 --timeout 4h orx exp run expId --backend slurm第一条显式指定登录节点别名、请求 2 张 H100、限制作业时长 4 小时第二条完全省略参数前提是slurm.json中配置了默认 host见第五节。提交成功后终端会输出类似✓ Slurm job submitted. host login-node (job jobid) run run-id返回后立即用orx runs、orx logs、orx exp wait或orx exp wake跟进作业状态见第六节。三、参数语义详解所有参数定义在 src/main.rs 的ExpRunArgs结构体中Slurm 后端的本地入口 src/local/slurm.rs 负责消费它们。--host alias登录节点--host取~/.ssh/config中的host 别名而不是裸 IP 或userhost认证完全交给你的 SSH 配置与 agent/密钥orx从不读取私钥见 src/jobs/ssh.rs 头部注释。只有当slurm.json配置了默认 Slurm host 时才能省略--host。src/compute.rs 的validate_run_args明确校验--host只适用于--backend ssh或--backend slurm其他后端传入会被直接拒绝。--flavor GRESGPU 请求可选原文档说 --flavoris an optional GRES GPU request such ash100:2. Omit it for CPU. 底层映射实现在 src/jobs/slurm.rs 的resolve_gres--flavor写法生成的#SBATCH --gres说明省略无CPU 运行由分区默认决定gpugpu:1单张 GPUgpu:a100:4gpu:a100:4已是完整 GRES 规格原样透传h100:2gpu:h100:2gpu: 原样h100gpu:h100同上需要注意的坑源码中有专门的防御逻辑--flavor cpu这种从 HF/Modal 带过来的肌肉记忆在 Slurm 后端会被拒绝并报错——因为cpu会被拼成无意义的gpu:cpuGRES最终在 sbatch 时报出晦涩错误。CPU 运行的正确做法是直接省略--flavor见 src/local/slurm.rs。没有--image原样使用集群环境Slurm 后端没有镜像标志ExpRunArgs.image被显式拒绝见 src/local/slurm.rs。作业运行在你集群自己的环境里modules、conda、登录 profile 原样生效。这意味着依赖通过集群已有的 module/conda 环境提供而不是容器镜像适合集群管理员没有开放容器能力、或团队统一用 module 管理软件栈的场景。--timeout dur作业时间上限默认 4h默认 4 小时覆盖整个批处理作业的生命周期时长支持90s、30m、4h、1d这种 orx 时长语法解析后转换为秒秒数会被渲染成 Slurm 的--time语法D-HH:MM:SS/HH:MM:SS转换函数slurm_time见 src/jobs/slurm.rs优先级--timeout命令行参数 slurm.json的timeLimit 集群自身默认限制。注意与 HF 后端不同Slurm 后端没有内置的 4h 默认——未设置时回落到配置再落到集群默认见 src/main.rs 的注释。--force允许并发运行默认情况下同一节点上已有 in-flight 运行时会拒绝再次启动--force允许有意为之的并发运行见 SKILL.md 通用启动契约。四、提交链路从快照到sbatch的源码级拆解4.1 通用启动契约无论哪个后端orx都强制三条铁律见 SKILL.md一切计算都用orx exp run启动绝不绕过它直接调sbatch、裸 SSH 或训练命令本身——直接启的作业不被跟踪可能运行的不是记录在案的 commit运行命令保持固定在基线上用orx project edit projectId --run-command cmd设一次子分支只改代码与配置提交前先 commit每个后端都运行记录 commit 的不可变源码快照未提交文件不参与任何后端都不需要 push 到 GitHub。4.2 源码暂存内容寻址的 tar 缓存提交前src/local/slurm.rs 调用stage_source实现在 src/jobs/ssh.rs把实验分支的源码快照打包成 tar按内容摘要digest命名缓存到远端~/.orx/source/digest.tar同一摘要只上传一次重复运行直接复用缓存随后解压到本次运行专属目录~/.orx/runs/run_id/repo/目录权限收紧为 700。4.3 登录节点上发生什么src/jobs/slurm.rs 的run_job依次执行三个 SSH 调用创建运行目录并执行 setup 脚本mkdir -p ~/.orx/runs/run_id chmod 700 … bash -ssetup 脚本含环境导出与test -d repo校验通过stdin传入令牌token不会出现在 argv 或落盘文件里写入 job.sbatchumask 077 cat ~/.orx/runs/run_id/job.sbatchowner-only 权限是因为脚本内嵌了令牌提交cd ~/.orx/runs/run_id sbatch --parsable job.sbatch解析输出得到 Slurm job idparse_job_id处理jobid与jobid;cluster两种格式。设计要点克隆/暂存发生在登录节点提交时而不是计算节点——很多集群的计算节点没有外网作业内克隆会失败这是 Slurm 后端与其他后端作业内拉取刻意不同的地方。4.4 job.sbatch 的结构render_sbatchsrc/jobs/slurm.rs生成固定指令 可选指令 载荷固定指令--job-nameorx-runid前8位、--outputlog、--errorlog、--open-modeappend可选指令--time、--partition、--account、--gres由参数与配置决定载荷以子 shell( cd repo || exit 97; run command )运行exit/set -e只终结子 shell随后仍能执行code$?; echo $code exit_code; exit $code脚本以载荷的退出码退出使 Slurm 自己的 COMPLETED/FAILED 判定与载荷一致环境导出按 key 排序保证脚本确定性并用sh_quote单引号转义防注入默认给 Python 设PYTHONUNBUFFERED1让输出在--output重定向下实时流式可见而非块缓冲。五、slurm.json固化集群默认配置SlurmSettings 结构体src/jobs/slurm.rs定义了用户可调的集群默认值存储于$XDG_CONFIG_HOME/openresearch/slurm.json。所有字段都是可选的——单分区集群上连裸sbatch都能工作不需要任何配置。字段camelCase对应#SBATCH说明host—登录节点的 SSH 配置别名即--host的默认值partition--partition默认分区account--account计费/配额账号timeLimit--time默认时间上限用 orx 时长语法4h、30m示例文件{ host: login-node, partition: gpu, account: lab-a, timeLimit: 4h }加载逻辑src/jobs/slurm.rs文件缺失视为未配置仍可用显式--host运行文件存在但 JSON 解析失败会给出明确报错并提示修复或删除后重配。配置里不存任何密钥——认证全部由 SSH 负责。六、运行生命周期状态轮询、取消、日志与等待6.1 分离的orx supervise不要杀掉它orx exp run提交后立即返回随后会 detach 一个orx supervise进程src/local/slurm.rs负责记录调度器状态与日志。不要 kill 掉它——它可重启、可幂等重挂reattach 句柄是(host, slurm job id)运行目录由 run id 推导kill 掉会导致运行一直停留在 starting。6.2 状态判定exit_code 优先squeue / sacct 兜底inspect_jobsrc/jobs/slurm.rs一次 SSH 探测返回单个状态令牌优先级为exit_code文件调度器无关的地面真相与 ssh 后端一致——作业结束由脚本落盘squeue -h -j jobid -o %T——查询在队列中的活作业sacct -nPX -j jobid -o State——查询已离开队列但没来得及写 exit_code 的作业scancel / 超时 / 节点故障两者皆空则报GONE——但GONE本身不是终结状态slurmctld 短暂宕机或 exit_code 写盘 NFS 延迟也会触发它supervisor 会多次轮询去抖后才判定作业丢失。map_inspect_tokensrc/jobs/slurm.rs把 Slurm 原生状态映射到 orx 统一阶段词汇Slurm 状态orx 阶段备注PENDING/CONFIGURING/REQUEUED/RESV_DEL_HOLDSCHEDULING排队中RUNNING/COMPLETING/SUSPENDED/STAGE_OUT/SIGNALINGRUNNING运行中EXIT 0exit_code 文件COMPLETED载荷成功非零EXIT codeERROR附退出码sacct 的COMPLETEDCOMPLETED脚本以载荷码退出sacct 判定与之一致squeue 的COMPLETEDRUNNING瞬态继续轮询squeue 的NODE_FAIL/PREEMPTEDRUNNING默认JobRequeue1会以同一 job id 重排不可提前终结CANCELLED/REVOKEDCANCELEDTIMEOUT/DEADLINEERROR消息 job hit its time limitFAILED/NODE_FAIL/BOOT_FAIL/OUT_OF_MEMORY/PREEMPTEDsacct 来源ERROR附小写状态名未知状态RUNNING绝不把 supervisor 卡进终结态这套映射有完整的单元测试覆盖src/jobs/slurm.rs包括sacct -P才能避免的定宽截断CANCELLED防御。6.3 取消orx exp cancel→scancel取消走scancelsrc/jobs/slurm.rs对已结束的作业宽容scancel对它们返回非零命令加了2/dev/null || true结果由 supervisor 的下一次轮询观察。6.4 日志复用 SSH 的流式传输Slurm 通过--outputlog把合并的 stdout/stderr 追加到运行目录的log文件日志流式传输直接复用ssh::stream_logs见 src/jobs/ssh.rs因为运行目录布局与 ssh 后端完全一致。6.5 等待与唤醒orx exp wait/orx exp wakeorx exp wait expId阻塞到运行状态变化--project变体是预算循环原语——在首次完成时返回而非启动或排队转运行需要每轮循环重新发出一次返回后必须读orx runs projectId对账所有新终结的运行。默认间隔 5 秒、超时 1800 秒超时非零退出只表示没有变化而非运行失败失败运行会带reason:行provider 容量类失败通常可重试启动后的失败需要读orx logs runId排查orx exp wake expId是结束本轮、作业 done/failed 后再回来的机制只在done/failed时触发且排在用户消息之后同一运行二选一wait 与 wake 不要混用。七、前置检查preflightSlurm 后端提供 per-host 就绪检查src/jobs/slurm.rs一次探测确认主机可 SSH 到达sbatch、squeue、scancel三个 Slurm CLI 均在 PATH输出SLURM_OKbash与tar可用暂存解压依赖输出TOOLS_OKsinfo -h -o %P列出可用分区默认分区的尾部*会被剥掉供配置 UI 选择。未通过检查时orx exp run会直接报错阻止提交避免在集群上留下半成品。八、测试与验证Slurm 后端代码附带两类测试纯函数单元测试src/jobs/slurm.rs验证最小 sbatch 只含固定指令、可选指令与带引号 env 的正确渲染含--time04:00:00的格式化与特殊字符转义、slurm_time的D-HH:MM:SS格式、resolve_gres的 flavor 映射、parse_job_id对123/123;cluster2/ 错误输出的处理活集群 E2E 测试e2e_lifecycle_against_live_cluster默认#[ignore]设置ORX_SLURM_TEST_HOSTssh 别名后通过cargo test jobs::slurm -- --ignored运行覆盖 提交 → SCHEDULING/RUNNING → COMPLETED含日志内容断言以及 scancel → CANCELED 或 GONEaccounting 被禁用时的取消路径。如果你在本机对纯函数部分做验证直接cargo test即可活集群部分务必在自己的集群上跑。九、限制与注意事项无slurmrestd实现刻意走 SSH Slurm CLIsbatch --parsable/squeue/sacct/scancel不用 REST 守护进程——后者需要集群管理员级别的部署而任何有集群账号的人都能 SSH 登录节点与 SkyPilot 相同的取舍见 src/jobs/slurm.rs 头部注释sacct可能被集群全局禁用它是尽力而为的兜底而非依赖不要--flavor cpuCPU 运行直接省略--flavor提交前必须 commit未提交文件不进入快照且任何后端都不需要 push计算节点通常无外网因此源码在登录节点提交时暂存不要在作业内依赖联网克隆不要把 Slurm 后端与其他后端的参数习惯混用--image与--manifest仅 k8s在此后端都会被明确拒绝。按需深入完整后端参考见 slurm.md通用启动契约与等待/唤醒语义见 SKILL.md核心实现见 src/jobs/slurm.rs 与 src/local/slurm.rs。【免费下载链接】OpenResearchTurn your coding agents into research agents项目地址: https://gitcode.com/GitHub_Trending/op/OpenResearch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考