SkyPilot 实战指南:用三大抽象与 Task YAML 驾驭 25+ 云、Kubernetes 与 Slurm 上的 AI 工作负载
【免费下载链接】skypilotThe AI Compute Platform for frontier teams. SkyPilot turns fragmented AI compute into one AI supercomputer, so frontier AI teams build custom intelligence faster.项目地址: https://gitcode.com/GitHub_Trending/sk/skypilot
SkyPilot 是一套统一框架,用同一种 YAML 与命令行接口在 25+ 朵云(AWS、GCP、Azure、Coreweave、Nebius、Lambda、Together AI、RunPod 等)、Kubernetes 集群和 Slurm 集群上启动集群、运行任务、托管模型。本文基于仓库中 agent/skills/skypilot/SKILL.md 及其参考文档整理而成,面向需要"用代码批量调度 GPU 资源"的开发者与 Agent 开发者,读完你能够:判断什么场景该用 SkyPilot、按阶段选择正确抽象(集群 / Managed Jobs / SkyServe)、写出可复制的任务 YAML、理解多云故障切换与成本优化的底层机制,并把存量 Slurm 负载迁移到 SkyPilot。
何时使用 SkyPilot
适合用 SkyPilot 的场景:
- 在任意云、Slurm 或 Kubernetes 集群上管理计算资源;
- 在任何云 / K8s / Slurm 上拉起 CPU / GPU / TPU(GB300、GB200、B200、H200、H100 等)实例;
- 运行训练、微调或批量推理任务;
- 用自动伸缩与多云副本托管模型(SkyServe);
- 运行带自动生命周期管理与恢复的长时任务(Managed Jobs);
- 跨云寻找最便宜或最易获得的 GPU。
不适合的场景:仅限本地的负载(直接用 Docker / conda)。
三大核心抽象:按工作流阶段选对工具
SkyPilot 围绕三个核心抽象设计,对应开发、训练、生产三个阶段:
1. SkyPilot Clusters(sky launch/sky exec)——交互式开发与调试
- 用于初期开发、调试与实验;
- 启动一个集群,SSH 进入或连接 VSCode/Cursor(
code --remote ssh-remote+CLUSTER)快速迭代; - 集群在你
sky stop/sky down或 autostop 触发前持续运行; - 最适合:原型开发、调试、短实验。
2. Managed Jobs(sky jobs launch)——长时训练与批量任务
- 用于提交无需人工看护的长时任务;
- 管理完整生命周期:供给(provisioning)、执行、恢复、销毁;
- 自动从 spot 抢占、配额限制和瞬时故障中恢复;
- 跨云、Kubernetes 和 Slurm 工作(可处理抢占与配额);
- 最适合:训练、微调、超参搜索、批量推理。
3. SkyServe(sky serve up)——生产级模型托管
- 用于大规模带自动伸缩的模型托管;
- 可先用
sky launch+ 开放端口验证 serving 配置,再改用sky serve up扩容; - 提供负载均衡、自动伸缩和多云副本;
- 最适合:模型推理端点、API 服务。
环境引导:启动前的三步检查
对 Agent 或首次使用的用户,按以下顺序确认 SkyPilot 已安装、已连接 API server、已有云凭据,确认后即可直接进入任务。
Step 1:检查安装与 API server 连通性
sky api info| 输出内容 | 含义 | 下一步 |
|---|---|---|
| Server 版本与状态 | Server 正常运行并已连接 | 引导完成,直接进入任务 |
No SkyPilot API server is connected | 未连接 server | 进入"启动或连接 server" |
Could not connect to SkyPilot API server | 远程 server 不可达或认证过期 | 告知用户,建议sky api login --relogin -e <endpoint>重连 |
command not found: sky | 未安装 SkyPilot | 进入"安装 SkyPilot" |
安装 SkyPilot(仅当sky命令不存在时):
pip install "skypilot[aws,gcp,kubernetes]" # 按用户所需云选择 extras不确定用户需要哪些云时先询问,然后重新运行sky api info。
启动或连接 server(仅当 server 未运行时):询问用户是否有现成的 SkyPilot API server 可连接,还是需要本地启动一个。
- 连接已有 server:
sky api login -e <API_SERVER_URL>,URL 由用户提供; - 本地启动:
sky api start。
完成任一路径后重新运行sky api info确认可达。sky api start默认绑定 127.0.0.1:46580,如需远程访问可参考 CLI Reference 中的--host 0.0.0.0、--port等选项。
Step 2:检查云凭据(仅全新环境,若 server 已在运行可跳过)
sky check -o json该命令显示哪些云启用/禁用。若用户目标云未启用,指导其完成凭据配置(参见 Troubleshooting)。从源码角度看,sky check的核心逻辑位于 sky/check.py,它逐云检测凭据与依赖并给出enabled/disabled及原因;输出同样支持-o json结构化解析(见 CLI Reference)。
核心命令速查
状态/查询类命令统一加-o json获取结构化 JSON 而非表格,便于脚本与 Agent 解析。
Clusters——交互式开发与调试:
| 命令 | 说明 |
|---|---|
sky launch -c NAME task.yaml | 启动一个集群或运行一个任务 |
sky exec NAME task.yaml | 在已有集群上运行任务(跳过供给;每次都会重新同步 workdir) |
sky exec NAME task.yaml -d | 同上,但立即返回(不流式输出日志) |
sky status -o json | 显示所有集群 |
sky logs NAME | 流式查看集群上的任务日志 |
sky logs NAME --no-follow | 打印已有日志后立即退出 |
sky logs NAME --tail 50 | 打印最后 50 行日志后退出 |
sky logs NAME --status | 以退出码表达任务状态:0=成功,100=失败,101=未结束,102=不存在,103=已取消 |
sky queue NAME -o json | 列出集群上的任务及状态(结构化 JSON) |
sky stop NAME/sky start NAME | 停止/重启以节省成本(保留磁盘) |
sky down NAME | 彻底销毁集群 |
sky gpus list -o json | 跨云列出可用 GPU 类型 |
Managed Jobs——长时无人值守负载:
| 命令 | 说明 |
|---|---|
sky jobs launch task.yaml | 启动一个 Managed Job(自动生命周期 + 恢复) |
sky jobs queue -o json | 显示所有 Managed Job 及其状态 |
sky jobs logs JOB_ID | 流式查看 Managed Job 日志 |
sky jobs cancel JOB_ID | 取消 Managed Job |
SkyServe——带自动伸缩的模型托管:
| 命令 | 说明 |
|---|---|
sky serve up serve.yaml -n NAME | 启动模型托管服务 |
sky serve status NAME | 显示服务状态与端点 URL |
sky serve update NAME new.yaml | 滚动更新运行中的服务 |
sky serve down NAME | 销毁服务 |
完整命令与全部参数见 CLI Reference。
快速上手
# 启动一个 GPU 集群 sky launch -c mycluster --gpus H100 -- nvidia-smi # 从 YAML 运行任务 sky launch -c mycluster task.yaml # SSH 进入集群 ssh mycluster # 连接 VSCode 或 Cursor 做交互式开发 code --remote ssh-remote+mycluster /home/user/sky_workdir # 或:cursor --remote ssh-remote+mycluster /home/user/sky_workdir # 销毁 sky down mycluster--gpus支持V100:8、V100(等价于 1 张)甚至小数V100:0.5(调度框架支持分数 GPU,见 CLI Reference)。
Task YAML 结构详解
Task YAML 是 SkyPilot 的主接口,所有字段均可选,未指定时使用默认值。完整 schema 见 YAML Specification。
# task.yaml name: my-training-job # 同步到远端 ~/sky_workdir 的本地目录 workdir: . # 节点数(分布式训练用) num_nodes: 1 resources: # GPU/TPU 加速器(SkyPilot 自动选择最便宜的云/区域) accelerators: H200:8 # 可选:锁定特定云/区域/基础设施 # infra: aws # 或 aws/us-east-1、k8s、ssh/my-pool # 若不写 infra,SkyPilot 自动在全部已启用云/区域间故障切换, # 找到最便宜的可用选项。 # 使用 spot 实例节省成本 use_spot: false # 磁盘大小(GB) disk_size: 256 # 为服务开放端口 ports: 8080 # 环境变量(在 file_mounts、setup、run 中均可访问) envs: MODEL_NAME: my-model BATCH_SIZE: 32 # setup:集群创建时执行一次,复用集群时被缓存 setup: | pip install torch transformers # run:主命令 run: | python train.py --model $MODEL_NAME --batch-size $BATCH_SIZE常用 resources 字段(节选)
accelerators:<name>:<count>,如H100:4;也可写有序列表['L4:1', 'H100:1', 'A100:1'](按顺序尝试)或无序集合{A100:1, V100:1}(一起优化、优先最便宜)。infra:<cloud>/<region>/<zone>,region/zone 可选;k8s/<context-name>亦支持;各分量支持通配符*,如aws/*/us-east-1a。cpus/memory:4+表示"至少 4 个 vCPU"、32+表示"至少 32 GiB",64GB、1024MB等带单位写法同样支持。use_spot:默认false(按需实例);true使用 spot/preemptible 实例,通常可显著降低成本。disk_size/disk_tier:OS 磁盘大小(GB 或带单位);磁盘档位low/medium/high/ultra/best,默认medium。注意在 Kubernetes 上它映射为 pod 的resources.requests.ephemeral-storage(见 yaml-spec.md)。network_tier:standard(默认)或best。best会启用高性能互联——AWS 上启用 EFA、GCP 上启用 GPUDirect-TCPX/TCPXO/RDMA、Nebius 上启用 InfiniBand;Kubernetes 侧对 EKS/HyperPod、GKE、CoreWeave CKS、Nebius 等 context 亦有对应支持(详见 yaml-spec.md)。max_hourly_cost:按小时成本上限过滤实例;use_spot: true时对 spot 价格生效。ports:整数、范围(10052-10100)或列表;自动添加防火墙/入站规则,仅支持 TCP。集群端口在每次sky launch时更新,旧端口防火墙规则在集群终止前不会移除。labels:应用于实例的标签,AWS 映射为 tag、GCP 映射为 label、Kubernetes 映射为 pod label;仅首次 launch 时应用。autostop:true(默认 5 分钟)、数字(分钟)、带单位(10h)或对象{idle_minutes, down, wait_for};wait_for可选jobs_and_ssh(默认)/jobs/none。
envs 与 secrets
envs中的值可在file_mounts、setup、run中引用,并可用 CLI 覆盖:sky launch/exec --env KEY=val。secrets与 envs 类似,但只能在 setup/run 中使用,且在日志与 dashboard 中会被脱敏,可用--secret SECRET=val覆盖。仓库 examples/ 中有大量组合范例,例如 examples/managed_job_with_storage.yaml 演示了 envs + file_mounts + managed job 的组合用法。
file_mounts 与 volumes
file_mounts支持:本地路径 → 远端路径(rsync 同步);source: s3://...的对象存储;三种模式:
MOUNT(默认):FUSE 流式挂载,按需读取,磁盘占用小;COPY:setup 时全量下载,支持读写修改;MOUNT_CACHED:带本地缓存(rclone)的挂载,适合重复访问,可配合type预调优工作负载类型(MODEL_CHECKPOINT_RO/RW、DATASET_RO/RW)。
volumes用于 Kubernetes 上的持久/临时卷与 Slurm 容器的主机路径绑定。完整说明与可复制示例见 yaml-spec.md 与 examples.md。
多文档 YAML:流水线 / 任务组
一个 YAML 内可用---分隔多个 task,构成串行流水线;在文件头声明execution: parallel则成为并行任务组(job group)。这一机制在 Slurm 迁移场景中用于替代--dependency链,详见下文与 migrating-from-slurm.md。
GPU 与云选择:把选择权交给优化器
关键原则:让 SkyPilot 自己选云和区域,不要手动解析sky gpus list输出去挑云/区域/机型。SkyPilot 的优化器会在所有已启用的云之间自动选择最便宜的可用选项。只有用户明确要求某个云或区域时才写infra:。
默认行为(推荐)——只写 GPU 类型:
resources: accelerators: H200:8 # SkyPilot 自动挑选有 H200:8 的最便宜的云/区域如果用户没指定 GPU 类型,先问清楚需要什么 GPU(或要跑什么模型/负载以便给出建议)。不要替用户运行sky gpus list并替他决定——把选项交给用户,或用any_of让 SkyPilot 最大化可用性:
# 让 SkyPilot 从多个可接受 GPU 中挑选(最便宜者胜出) resources: any_of: - accelerators: H100:8 - accelerators: A100-80GB:8 - accelerators: A100:8用户有严格偏好时才用ordered:
# 先在 AWS 尝试 H100,回退到 GCP,再回退到 A100 resources: ordered: - infra: aws/us-east-1 accelerators: H100:8 - infra: gcp/us-central1 accelerators: H100:8 - infra: aws/us-west-2 accelerators: A100-80GB:8仅当用户明确说"用 AWS"或"跑在 GCP us-central1"时才设置infra::
resources: infra: aws # 用户明确要求 AWS accelerators: H100:8底层原理:any_of表示候选集无序,故障切换顺序由优化器决定(倾向最便宜);ordered表示严格按声明顺序故障切换(见 yaml-spec.md)。优化器会综合当前价格、可用性、配额等一起评估。若想先预览优化器会选哪朵云、哪个机型、什么价格而不真正供给资源,用sky launch --dryrun task.yaml(注意sky jobs launch没有--dryrun,即使最终命令是 jobs launch 也要用sky launch做 dry-run)。
集群生命周期管理
# 启动并运行任务 sky launch -c mycluster task.yaml # 启动时即设置 autostop(推荐:省成本,无需后续命令) sky launch -c mycluster task.yaml -i 30 # 空闲 30 分钟后停止 sky launch -c mycluster task.yaml -i 30 --down # 空闲 30 分钟后销毁 # 通过 CLI 覆盖/传入环境变量 sky launch -c mycluster task.yaml --env MODEL_NAME=llama3 --env BATCH_SIZE=64 # 在同一个集群上重跑不同任务(快,跳过供给) sky exec mycluster another_task.yaml # 运行内联命令 sky exec mycluster -- python train.py --epochs 10 # 启动后补设 autostop(若启动时忘了 -i) sky autostop mycluster -i 30 # 空闲 30 分钟后停止,保留磁盘(可 sky start 恢复) sky autostop mycluster -i 30 --down # 空闲 30 分钟后销毁(磁盘删除,不可恢复) # 停止省成本,之后重启 sky stop mycluster sky start mycluster # 彻底销毁 sky down mycluster数据留存差异:sky stop/sky start保留磁盘;sky down删除磁盘;两者都会重新同步 file_mounts 与 workdir;写入云存储挂载(file_mounts+mode: MOUNT的桶)的数据始终保留。需要跨sky down持久化的数据应写入云存储,具体对照见 troubleshooting.md。
Workdir 同步行为(易踩坑)
workdir:在每次sky exec前通过rsync同步到远端~/sky_workdir。rsync 是增量式的——本地删除的文件不会从远端删除。这可能导致实验跑到过期的构建产物或旧配置上。
确保干净状态,在sky exec前先 SSH 清理:
ssh mycluster "rm -rf ~/sky_workdir" sky exec mycluster task.yaml或只在run:内清理特定产物:
run: | find ~/sky_workdir/build -name '*.o' -delete 2>/dev/null || true cd ~/sky_workdir && make若只想排除大文件/生成物,可在 workdir 里使用.skyignore(语法同.gitignore,SkyPilot 也遵循.gitignore)减少同步体积,例如排除data/、*.bin、wandb/(见 troubleshooting.md)。
Managed Jobs:长时任务的自动生命周期
用sky jobs launch提交无需看护的长时任务。SkyPilot 管理完整生命周期——供给、执行、从抢占/配额/故障中恢复、销毁:
# managed-job.yaml name: training-job resources: accelerators: A100:8 run: | python train.py --resume-from-checkpoint# 以 Managed Job 启动 sky jobs launch managed-job.yaml # 查看状态 sky jobs queue -o json # 流式查看日志 sky jobs logs <job_id> # 取消 sky jobs cancel <job_id>Checkpoint 模式:训练脚本应将 checkpoint 保存到持久存储(云存储桶或卷),重启时从最新 checkpoint 恢复。SkyPilot 负责集群层面的恢复,你的脚本负责状态层面的恢复。一个完整范例是 examples/managed_job_with_storage.yaml(持久化 checkpoint 桶 + 自动恢复)。
job_recovery 恢复策略
EAGER_NEXT_REGION(默认):节点故障时直接去下一个区域。对 spot 实例很实用——实践中某区域发生抢占通常意味着该区域资源短缺。FAILOVER:先在同一区域重启,找不到资源才去下一区域。
同时支持max_restarts_on_errors(用户代码错误即非零退出码的最大重启次数)和recover_on_exit_codes(指定退出码总是触发恢复、不计入上述上限,适合 NCCL 超时等已知瞬时错误)。字段与默认值表见 yaml-spec.md。
排查 Managed Job:details是答案
当用户问"我的任务在干什么 / 为什么 pending / 为什么失败"时,按顺序执行以下命令,问题一有答案即停:
sky jobs queue -v -o json——-v会补充details、failure_reason等字段。对未启动的任务,details就是答案:它会说明集群在等什么,例如 Slurm 的QOSGrpGRES或Dependency原因及其所在分区。sky jobs logs JOB_ID --tail 100 --no-follow—— 最近的任务输出;加--controller看供给/恢复日志。
details的常见形态与含义:
details | 含义 | 下一步 |
|---|---|---|
Waiting for other jobs to launch | controller 到达并发启动上限 | 无需处理,持续时间列会显示等待时长 |
Waiting for higher priority jobs to launch | 有更高优先级任务在前 | 若本任务更重要,可在 YAML 中调高priority |
In backoff, waiting for resources | 供给失败在重试 | sky jobs logs N --controller --no-follow显示上次失败原因 |
Recovering: <reason> | 集群丢失或任务崩溃(如 OOMKilled) | 修复原因,恢复是自动的 |
Failure: <reason> | 终态失败 | 阅读原因,用sky jobs logs N --no-follow看任务输出 |
Launching (pending: <reason>; partition: <p>) | 任务 STARTING 且 Slurm 尚未分配节点 | 见下方 Slurm pending 原因 |
Launching (nodes allocated; ...) | 排队结束,正在引导 | 无需处理 |
Slurm 常见 pending 原因分类(Resources/Priority→容量不足等配额;QOSGrpGRES/QOSMax*→QoS/账号配额满;Dependency→等待另一 Slurm 任务;JobHeldUser/JobHeldAdmin→任务被 hold;BeginTime→未到预定开始时间),详见 job-investigation.md。
环境变量:分布式协调的接口
SkyPilot 会在每个节点注入分布式协调所需的环境变量,其注入逻辑可从源码确认:SKYPILOT_NODE_IPS(换行分隔的全部节点 IP,head 在前)与SKYPILOT_NUM_GPUS_PER_NODE在 sky/backends/task_codegen.py 中写入任务环境;SKYPILOT_JOB_RANK(Managed Job 数组中的下标)在 sky/jobs/controller.py 中注入;SKYPILOT_NUM_JOBS在 sky/jobs/server/core.py 中设置;SKYPILOT_TASK_ID在 sky/jobs/utils.py 中生成。
| 变量 | 说明 |
|---|---|
SKYPILOT_NODE_IPS | 全部节点 IP(换行分隔,head 第一行) |
SKYPILOT_NODE_RANK | 当前节点从 0 开始的序号(head=0) |
SKYPILOT_NUM_NODES | 集群总节点数 |
SKYPILOT_NUM_GPUS_PER_NODE | 当前节点 GPU 数 |
SKYPILOT_JOB_RANK/SKYPILOT_NUM_JOBS | 仅--num-jobs时设置:数组下标 / 总数 |
SKYPILOT_TASK_ID | 任务 ID |
多节点 PyTorch DDP 的标准写法:
num_nodes: 2 resources: accelerators: A100:8 run: | HEAD_IP=$(echo "$SKYPILOT_NODE_IPS" | head -n1) torchrun \ --nnodes=$SKYPILOT_NUM_NODES \ --nproc_per_node=$SKYPILOT_NUM_GPUS_PER_NODE \ --node_rank=$SKYPILOT_NODE_RANK \ --master_addr=$HEAD_IP \ --master_port=12345 \ train_ddp.py注意:setup和run会在所有节点执行;需要 head-only 的逻辑(如 DeepSpeed/Ray 协调器启动)务必用if [ "$SKYPILOT_NODE_RANK" == "0" ]包起来。DeepSpeed、FSDP、Ray Train、NCCL 调优的完整配置见 advanced-patterns.md。
SkyServe:模型托管与自动伸缩
# serve.yaml resources: accelerators: A100:1 ports: 8080 run: | python -m vllm.entrypoints.openai.api_server \ --model meta-llama/Llama-3.1-8B-Instruct \ --port 8080 service: readiness_probe: /v1/models replica_policy: min_replicas: 1 max_replicas: 3 target_qps_per_replica: 5# 启动服务 sky serve up serve.yaml -n my-llm # 查看状态 / 获取端点 sky serve status my-llm sky serve status my-llm --endpoint # 滚动更新 sky serve update my-llm new-serve.yaml # 销毁 sky serve down my-llmservice 字段要点:
readiness_probe(必需):/v1/models字符串形式(GET + 默认参数)或对象形式。对象支持path、post_data(改为 POST 探活,适合需要一次生成测试的 LLM)、initial_delay_seconds(默认 1200,按服务启动时间设置)、timeout_seconds(默认 15)、endpoint_probe_interval_seconds(默认 10)、consecutive_failure_threshold_timeout。探活返回 200 才开始路由流量。replica_policy(与replicas二选一必需):min_replicas(必需)、max_replicas(不设则固定副本数)、target_qps_per_replica(设置了才启用自动伸缩)、upscale_delay_seconds(默认 300,防激进扩容)、downscale_delay_seconds(默认 1200,防激进缩容)。replicas:固定副本数的简化形式。load_balancer.stream_timeout_seconds:负载均衡器等待代理响应流的最长时间(默认 120)。
生产级能力还包括:blue-green 更新(sky serve update --mode blue_green)、spot 副本 + on-demand 兜底(base_ondemand_fallback_replicas/dynamic_ondemand_fallback)、TLS 终结(service.tls)、多实例感知负载均衡(instance_aware_least_load)、按 GPU 类型差异化 QPS 目标等,见 advanced-patterns.md。
常见工作流
微调工作流
- 编写含
setup(装依赖)与run(训练命令)的任务 YAML; - 用
file_mounts或workdir同步代码; sky launch -c train task.yaml启动;sky logs train监控;sky exec train -- python eval.py在同一集群上评估;sky down train结束清理。
超参扫描
- 用
envs编写参数化 YAML; - 批量启动多个 Managed Job:
for lr in 1e-4 1e-5 1e-6; do sky jobs launch sweep.yaml --env LR=$lr --name sweep-lr-$lr done - 用
sky jobs queue -o json监控。每个 Job 独立供给、独立自动恢复(见 advanced-patterns.md)。
模型服务部署
- 编写带
service:段的 serve YAML; sky serve up serve.yaml -n my-service;sky serve status my-service --endpoint获取端点;- 更新模型:
sky serve update my-service updated.yaml。
并行实验提交(多 VM)
用sky exec -d向多台 VM 提交任务而不阻塞,再收集结果:
# 提交全部实验(detached,排队后立即返回) for i in 1 2 3 4; do sky exec exp-vm-0$i task.yaml --env LR=1e-$i -d done # 获取某集群最新 job id job_id=$(sky queue exp-vm-01 -o json \ | python3 -c "import sys, json; jobs = json.load(sys.stdin).get('exp-vm-01', []); print(max(j['job_id'] for j in jobs) if jobs else '')") # 等待某任务完成并取最后 50 行 sky logs exp-vm-01 $job_id --status && sky logs exp-vm-01 $job_id --tail 50 # 一次性查看集群上所有任务 sky queue exp-vm-01 -o json迁移存量 Slurm 负载
当用户有现成sbatch脚本、salloc工作流,或询问 Slurm 命令如何映射到 SkyPilot 时,先读 Migrating from Slurm 再写任何 YAML。该映射有若干不易察觉的坑:
--time不映射到autostop——Slurm 上不支持 autostop,应使用config.slurm.sbatch_options.time;- 裸
srun <cmd>通常应直接去掉而不是翻译——run本身就在每个节点执行;只有 MPI/PMIx 启动器保留srun,且需加--overlap和 rank-0 守卫; --account/--qos/--exclusive等未建模的指令通过config.slurm.sbatch_options原样传给sbatch;sbatch --array映射为sky jobs launch --num-jobs加$SKYPILOT_JOB_RANK,而不是 shell 循环。
#SBATCH指令映射速查:
#SBATCH指令 | SkyPilot YAML | 说明 |
|---|---|---|
--nodes=2 | num_nodes: 2 | 任务级字段,不在resources下 |
--gpus-per-node=8/--gres=gpu:h100:8 | resources.accelerators: H100:8 | 以--gres=gpu:<type>:<count>发出;名称须匹配集群 GRES 配置 |
--cpus-per-task=32 | resources.cpus: 32+ | +表示"至少" |
--mem=256G | resources.memory: 256+ | 单位 GB |
--partition=gpu | resources.infra: slurm/<cluster>/gpu | 省略则让优化器选分区 |
--time=24:00:00 | config.slurm.sbatch_options.time: "24:00:00" | 不是autostop |
--job-name=train | name: train | |
--output=/--error= | (不映射) | SkyPilot 管理任务日志 |
其余(--account、--qos等) | config.slurm.sbatch_options.<key> | 原样透传为#SBATCH行 |
环境变量映射:$SLURM_JOB_NODELIST→$SKYPILOT_NODE_IPS、$SLURM_NNODES→$SKYPILOT_NUM_NODES、$SLURM_NODEID/$SLURM_PROCID→$SKYPILOT_NODE_RANK、$SLURM_GPUS_PER_NODE→$SKYPILOT_NUM_GPUS_PER_NODE、$SLURM_JOB_ID→$SKYPILOT_TASK_ID、$SLURM_ARRAY_TASK_ID→$SKYPILOT_JOB_RANK、$SLURM_ARRAY_TASK_COUNT→$SKYPILOT_NUM_JOBS。在 Slurm 上,底层分配的任务级SLURM_*变量在run中仍存在(脚本保持可运行),但 SkyPilot 自己的 job step 的 step 级变量会被刻意清空。生成的新 YAML 应优先使用SKYPILOT_*变量,因为它们让任务可移植到 Kubernetes 和云。
校验:用sky launch --dryrun <yaml>验证(不真正供给,仅解析资源并运行优化器);sky jobs launch没有--dryrun,故即使最终命令是 jobs launch 也要用sky launch做 dry-run。
两种情形要区分:SkyPilot 跑在用户现有 Slurm 集群上(通过登录节点sbatch提交,集群不变)vs. 迁移到 Kubernetes 或云(YAML 相同但约束不同)。不要假设用户想离开 Slurm;迁移到 Kubernetes 是另一个独立问题。
Slurm 上的不支持项:autostop/sky stop、ports:/sky serve、use_spot: true均不支持;image_id: docker:...需要集群装 Pyxis;桶挂载(mode: MOUNT)需要计算节点有 FUSE。因为 Slurm 上无 autostop,空闲的sky launch集群会一直占着分配,直到sky down——批量类工作优先用sky jobs launch以便自动释放分配。
Agent 程序化使用:反馈循环
以编程方式使用 SkyPilot 时遵循以下循环:
- 验证:
sky launch --dryrun task.yaml(检查资源可用性/成本); - 启动:
sky launch -c mycluster task.yaml; - 监控:
sky status -o json与sky queue mycluster -o json; - 等待完成:
sky logs mycluster <JOB_ID>(流式日志以便观察进度并对停滞做出反应;阻塞直到任务结束;JOB_ID 从sky queue mycluster -o json获取)。对不需要中间输出的长任务,用sky logs mycluster <JOB_ID> --status(静默阻塞,成功退出 0); - 检查输出:
sky logs mycluster <JOB_ID> --no-follow或--tail 100; - 调试:
ssh mycluster(交互式); - 迭代:
sky exec mycluster updated_task.yaml(在已有集群上运行); - 清理:
sky down mycluster。
永远不要用
sleep+sky queue轮询——用sky logs CLUSTER JOB_ID流式阻塞到完成;只需要退出码用--status;只需最近输出用--tail N。轮询浪费 token、引入时序 bug 且脆弱。
常见 Agent 错误对照
| 错误 | 为什么不对 | 正确做法 |
|---|---|---|
从sky gpus list输出手动挑云/区域 | SkyPilot 优化器自动完成且更优 | 只设accelerators:让 SkyPilot 选择 |
长时无人值守任务用sky launch | 被抢占或中断后无恢复 | 无人值守工作用sky jobs launch |
完成后忘记sky down或 autostop | 空闲集群浪费钱 | 始终清理,或启动时用-i <minutes> --down |
用户没要求却硬编码infra: aws | 限制可用性并推高成本 | 仅当用户明确要求某云时设infra: |
不用envs:做可配置值 | 难以复用或从 CLI 覆盖 | YAML 用envs:+--env KEY=VAL参数化 |
sky launch不带-c <name> | 生成随机名集群,难以引用 | 始终用-c命名集群 |
| 解析状态命令的表格输出 | 表格格式面向人类,解析脆弱 | 用-o json获取结构化输出 |
使用废弃的cloud:/region:/zone:字段 | 已被infra:取代 | 用infra: aws/us-east-1 |
用sleep+sky queue轮询状态 | 浪费 token、时序 bug、脆弱 | 用sky logs CLUSTER JOB_ID --status阻塞到完成 |
| 以为 workdir 同步会删除远端文件 | rsync 增量式;旧远端文件跨sky exec保留 | SSH 手动清理~/sky_workdir,或在run:里清理 |
只看最后输出却不用--tail | 长任务流式全量日志浪费 token | 用--tail 50只取最后 N 行 |
常见问题速查
| 问题 | 解决 |
|---|---|
| GPU 不可用 | 用any_of提供备选,或换区域/云 |
| setup 太慢 | SkyPilot 会缓存 setup;重跑用sky exec跳过 |
| 任务静默失败 | sky logs <cluster>或ssh <cluster>调试 |
| 集群卡在 INIT | sky down <cluster>后重新启动 |
| 抢占/配额 | 用sky jobs launch获得自动恢复与生命周期管理 |
| 端口不可访问 | 确认resources.ports:已设置且安全组放行 |
| 文件同步慢 | 大数据集用云存储挂载而非workdir |
| 凭据错误 | 运行sky check -o json检查哪些云被禁用及其原因 |
更系统的排查(安装与凭据、启动失败、setup 失败、分布式训练、挂载存储、Managed Job、SkyServe、SSH/API server 各分节)见 troubleshooting.md。
深入阅读
- CLI Reference——全部命令与参数(含
sky launch的--dryrun、-i、--env/--secret、sky jobs launch的--num-jobs、--job-recovery等) - YAML Specification——完整 task YAML schema、file mounts、环境变量、SkyServe 与 job pool 字段
- Python SDK——程序化 API 与 SDK 用法
- Advanced Patterns——多云策略、分布式训练、生产模式、成本优化
- Migrating from Slurm——
sbatch脚本转 task YAML、Slurm 命令/环境变量映射、Slurm 特有约束 - Job Investigation——"任务在干什么/为什么"的命令编排,
details与 Slurm pending 原因解读 - Troubleshooting——错误诊断与解决方案
- Examples——可直接复制粘贴的任务 YAML 示例
仓库 examples/ 与 llm/ 目录中还有上百个可直接参考的端到端 YAML(vLLM 服务、LoRA 微调、多节点 DDP、spot 训练、向量数据库、SkyRL 等),可作为编写自有任务配置的起点。
【免费下载链接】skypilotThe AI Compute Platform for frontier teams. SkyPilot turns fragmented AI compute into one AI supercomputer, so frontier AI teams build custom intelligence faster.项目地址: https://gitcode.com/GitHub_Trending/sk/skypilot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考