托管作业#
提示
此功能非常适合横向扩展:长时间运行单个作业,或并行运行大量作业。
SkyPilot 支持托管作业(sky jobs
),它可以自动重试失败、从 Spot 实例抢占中恢复并在完成后清理。
要启动托管作业,请使用 sky jobs launch
$ sky jobs launch -n myjob hello_sky.yaml
Task from YAML spec: hello_sky.yaml
Managed job 'myjob' will be launched on (estimated):
Considered resources (1 node):
------------------------------------------------------------------------------------------
CLOUD INSTANCE vCPUs Mem(GB) ACCELERATORS REGION/ZONE COST ($) CHOSEN
------------------------------------------------------------------------------------------
AWS m6i.2xlarge 8 32 - us-east-1 0.38 ✔
------------------------------------------------------------------------------------------
Launching a managed job 'myjob'. Proceed? [Y/n]: Y
... <job is submitted and launched>
(setup pid=2383) Running setup.
(myjob, pid=2383) Hello, SkyPilot!
✓ Managed job finished: 1 (status: SUCCEEDED).
Managed Job ID: 1
📋 Useful Commands
├── To cancel the job: sky jobs cancel 1
├── To stream job logs: sky jobs logs 1
├── To stream controller logs: sky jobs logs --controller 1
├── To view all managed jobs: sky jobs queue
└── To view managed job dashboard: sky jobs dashboard
作业在临时 SkyPilot 集群上启动,进行端到端管理,并自动清理。
托管作业有以下几个优点
使用 Spot 实例:作业可以在自动恢复的 Spot 实例上运行。这通过使可抢占 Spot 实例对长时间运行的作业有用,从而显著节省成本(例如,GPU VM 可节省约 70%)。
跨区域和云服务商扩展:轻松同时运行和管理数千个作业,使用跨多个区域/云服务商的实例和 GPU。
从故障中恢复:当作业失败时,您可以自动在新集群上重试,消除不稳定失败。
托管管道:运行包含多个任务的管道。这对于运行相互依赖的一系列任务非常有用,例如数据处理、训练模型,然后在模型上运行推理。
目录
创建托管作业#
托管作业是使用标准 SkyPilot YAML 创建的。例如
# bert_qa.yaml
name: bert-qa
resources:
accelerators: V100:1
use_spot: true # Use spot instances to save cost.
envs:
# Fill in your wandb key: copy from https://wandb.ai/authorize
# Alternatively, you can use `--env WANDB_API_KEY=$WANDB_API_KEY`
# to pass the key in the command line, during `sky jobs launch`.
WANDB_API_KEY:
# Assume your working directory is under `~/transformers`.
# To get the code for this example, run:
# git clone https://github.com/huggingface/transformers.git ~/transformers -b v4.30.1
workdir: ~/transformers
setup: |
pip install -e .
cd examples/pytorch/question-answering/
pip install -r requirements.txt torch==1.12.1+cu113 --extra-index-url https://download.pytorch.org/whl/cu113
pip install wandb
run: |
cd examples/pytorch/question-answering/
python run_qa.py \
--model_name_or_path bert-base-uncased \
--dataset_name squad \
--do_train \
--do_eval \
--per_device_train_batch_size 12 \
--learning_rate 3e-5 \
--num_train_epochs 50 \
--max_seq_length 384 \
--doc_stride 128 \
--report_to wandb \
--output_dir /tmp/bert_qa/
注意
工作目录 (Workdir) 和 包含本地文件的文件挂载 (file mounts) 将被自动上传到云存储桶。作业完成后,存储桶将被清理。
要将此 YAML 作为托管作业启动,请使用 sky jobs launch
$ sky jobs launch -n bert-qa-job bert_qa.yaml
要查看所有标志,您可以运行 sky jobs launch --help
或查看CLI 参考获取更多信息。
SkyPilot 将启动并开始监控该作业。
在后台,SkyPilot 会为作业启动一个临时集群。
如果发生 Spot 抢占或任何机器故障,SkyPilot 将自动跨区域和云服务商搜索资源以重新启动作业。
作业完成后,资源会立即清理。
提示
您可以在非托管的 sky launch
上测试您的 YAML,然后使用 sky jobs launch
进行生产运行作为托管作业。
sky launch
和 sky jobs launch
界面相似,但在不同场景下有用。
|
|
---|---|
长期存在、手动管理的集群 |
为每个作业专门配置的自动管理的集群 |
Spot 抢占必须手动恢复 |
Spot 抢占自动恢复 |
并行作业数量受限于集群资源 |
轻松同时管理数百或数千个作业 |
适合交互式开发 |
适合横向扩展生产作业 |
使用托管作业#
要查看所有命令和选项的列表,请运行 sky jobs --help
或阅读CLI 参考。
查看所有托管作业列表
$ sky jobs queue
Fetching managed jobs...
Managed jobs:
ID NAME RESOURCES SUBMITTED TOT. DURATION JOB DURATION #RECOVERIES STATUS
2 roberta 1x [A100:8][Spot] 2 hrs ago 2h 47m 18s 2h 36m 18s 0 RUNNING
1 bert-qa 1x [V100:1][Spot] 4 hrs ago 4h 24m 26s 4h 17m 54s 0 RUNNING
流式查看正在运行的托管作业的日志
$ sky jobs logs -n bert-qa # by name
$ sky jobs logs 2 # by job ID
取消托管作业
$ sky jobs cancel -n bert-qa # by name
$ sky jobs cancel 2 # by job ID
注意
如果托管作业发生任何故障,您可以查看 sky jobs queue -a
获取失败的简要原因。有关资源调配的更多详细信息,请查看 sky jobs logs --controller <job_id>
。
作业仪表盘#
使用 sky jobs dashboard
打开仪表盘查看所有作业
$ sky jobs dashboard
这将自动打开浏览器选项卡以显示仪表盘

UI 显示的信息与 CLI sky jobs queue -a
相同。当需要监控大量进行中的作业时,UI 特别有用,因为基于终端的 CLI 可能需要多页才能显示。
在 Spot 实例上运行#
托管作业可以在 Spot 实例上运行,SkyPilot 会自动恢复抢占。
要在 Spot 实例上运行,请使用 sky jobs launch --use-spot
,或在您的 SkyPilot YAML 中指定 use_spot: true
。
name: spot-job
resources:
accelerators: A100:8
use_spot: true
run: ...
提示
Spot 实例是可能被“抢占”的云虚拟机。云服务商可以强制关闭底层虚拟机并移除您的访问权限,从而中断在该实例上运行的作业。
作为交换,Spot 实例比不受抢占影响的普通实例(所谓的“按需”实例)便宜得多。根据云服务商和虚拟机类型的不同,Spot 实例可以便宜 70-90%。
SkyPilot 会自动跨区域和云服务商查找可用的 Spot 实例以最大化可用性。任何 Spot 抢占都由 SkyPilot 自动处理,无需用户干预。
这里是训练作业的示例,它可以在 AWS 和 GCP 的不同区域之间故障转移。

托管 Spot 作业 与 启动非托管 Spot 集群 快速对比
命令 |
是否托管? |
可 SSH 连接? |
最适合用于 |
---|---|---|---|
|
是,抢占自动恢复 |
否 |
横向扩展长时间运行的作业(例如,数据处理、训练、批量推理) |
|
否,不处理抢占 |
是 |
在 Spot 实例上进行交互式开发(特别是对于抢占率低的硬件) |
Spot 或按需/预留实例#
默认情况下,将使用按需实例(而非 Spot 实例)。要使用 Spot 实例,您必须在命令行上指定 --use-spot
或在您的 SkyPilot YAML 中指定 use_spot: true
。
但是,您也可以告诉 SkyPilot 根据可用性使用Spot 实例和按需实例。在您的 SkyPilot YAML 中,使用 any_of
指定 Spot 或按需/预留实例作为作业的候选资源。有关更多详细信息,请参阅此处的文档。
resources:
accelerators: A100:8
any_of:
- use_spot: true
- use_spot: false
在此示例中,SkyPilot 将选择最便宜的资源使用,这几乎肯定是 Spot 实例。如果 Spot 实例不可用,SkyPilot 将回退到启动按需/预留实例。
检查点和恢复#
为了从 Spot 实例抢占中快速恢复,通常需要一个云存储桶来存储作业的状态(例如,模型检查点)。未存储在云存储桶中的任何磁盘数据将在恢复过程中丢失。
下面是将存储桶挂载到 /checkpoint
的示例
file_mounts:
/checkpoint:
name: # NOTE: Fill in your bucket name
mode: MOUNT_CACHED # or MOUNT
要了解不同模式的更多信息,请参阅SkyPilot 存储桶挂载和高性能训练。
实际示例#
有关更多训练示例和最佳实践,请参阅模型训练指南。
用户代码失败时的作业重启#
抢占或硬件故障将自动恢复,但默认情况下,用户代码失败(非零退出码)不会自动恢复。
在某些情况下,您可能希望即使应用程序代码失败也能自动重启作业。例如,如果训练作业由于 NVIDIA 驱动程序问题或 NCCL 超时而崩溃,应将其恢复。要指定此设置,您可以在作业 YAML 文件中的 resources.job_recovery
中设置 max_restarts_on_errors
。
resources:
accelerators: A100:8
job_recovery:
# Restart the job up to 3 times on user code errors.
max_restarts_on_errors: 3
如果您的代码有任何非零退出码,这将最多重启作业 3 次(总共 4 次尝试)。每次重启都在新调配的临时集群上运行。
我的作业何时会被恢复?#
以下是 SkyPilot 处理各种类型故障的方式
用户代码失败( |
如果设置了 |
实例被抢占或底层硬件失败 |
拆除旧的临时集群,在另一区域调配新集群,然后重启作业。 |
因云配额或容量限制找不到可用资源 |
无限期地尝试其他区域和其他云服务商,直到找到资源。 |
云配置/认证问题或无效作业配置 |
将作业标记为 |
要查看用户代码(setup
或 run
命令)的日志,请使用 sky jobs logs <job_id>
。如果存在资源调配或恢复问题,您可以通过运行 sky jobs logs --controller <job_id>
查看资源调配日志。
提示
在后台,SkyPilot 使用一个“控制器”来调配、监控和恢复底层的临时集群。请参阅工作原理:作业控制器。
扩展到大量作业#
您可以轻松地同时管理数十、数百或数千个托管作业。这非常适合批处理作业,例如数据处理、批量推理或超参数搜索。要查看并行启动大量作业的示例,请参阅大量并行作业。
要增加可以同时运行的最大作业数量,请参阅扩展作业控制器的最佳实践。
托管管道#
管道是一个包含按顺序运行的一系列任务的托管作业。
这对于运行相互依赖的一系列任务非常有用,例如训练模型,然后在模型上运行推理。不同的任务可以有不同的资源需求,以便为每个任务使用适当的资源,从而节省成本,同时减轻用户管理任务的负担。
注意
换句话说,托管作业要么是单个任务,要么是任务管道。所有托管作业都通过 sky jobs launch
提交。
要运行管道,请在 YAML 文件中指定任务序列。下面是一个示例
name: pipeline
---
name: train
resources:
accelerators: V100:8
any_of:
- use_spot: true
- use_spot: false
file_mounts:
/checkpoint:
name: train-eval # NOTE: Fill in your bucket name
mode: MOUNT
setup: |
echo setup for training
run: |
echo run for training
echo save checkpoints to /checkpoint
---
name: eval
resources:
accelerators: T4:1
use_spot: false
file_mounts:
/checkpoint:
name: train-eval # NOTE: Fill in your bucket name
mode: MOUNT
setup: |
echo setup for eval
run: |
echo load trained model from /checkpoint
echo eval model on test set
上面的 YAML 定义了一个包含两个任务的管道。第一个 name: pipeline
为管道命名。第一个任务名为 train
,第二个任务名为 eval
。任务之间由包含三个破折号 ---
的行分隔。每个任务都有自己的 resources
、setup
和 run
部分。任务按顺序执行。如果一个任务失败,后续任务将被跳过。
要在任务之间传递数据,请使用共享文件挂载。在此示例中,train
任务将其输出写入 /checkpoint
文件挂载,然后 eval
任务可以从中读取。
要提交管道,使用相同的命令 sky jobs launch
。管道将由 SkyPilot 自动启动和监控。您可以使用 sky jobs queue
或 sky jobs dashboard
检查管道的状态。
$ sky jobs launch -n pipeline pipeline.yaml
$ sky jobs queue
Fetching managed job statuses...
Managed jobs
In progress jobs: 1 RECOVERING
ID TASK NAME RESOURCES SUBMITTED TOT. DURATION JOB DURATION #RECOVERIES STATUS
8 pipeline - 50 mins ago 47m 45s - 1 RECOVERING
↳ 0 train 1x [V100:8][Spot|On-demand] 50 mins ago 47m 45s - 1 RECOVERING
↳ 1 eval 1x [T4:1] - - - 0 PENDING
注意
环境变量 $SKYPILOT_TASK_ID
也可在每个任务的 run
部分使用。它对于管道中的每个任务都是唯一的。例如,上述 eval
任务的 $SKYPILOT_TASK_ID
是:“sky-managed-2022-10-06-05-17-09-750781_pipeline_eval_8-1”。
设置作业文件存储桶#
对于托管作业,SkyPilot 需要一个中间存储桶来存储任务中使用的文件,例如本地文件挂载、临时文件和工作目录。如果您未配置存储桶,SkyPilot 将为每次作业启动自动创建一个名为 skypilot-filemounts-{username}-{run_id}
的临时存储桶。作业完成后,SkyPilot 会自动删除该存储桶。
或者,您可以预先调配一个存储桶,并通过在 ~/.sky/config.yaml
中设置 jobs.bucket
将其用作文件存储的中间存储桶。
# ~/.sky/config.yaml
jobs:
bucket: s3://my-bucket # Supports s3://, gs://, https://<azure_storage_account>.blob.core.windows.net/<container>, r2://, cos://<region>/<bucket>
如果您选择指定存储桶,请确保该存储桶已存在并且您拥有必要的权限。
当使用预先调配的中间存储桶 jobs.bucket
时,SkyPilot 会在存储桶根目录下创建作业特定的目录来存储文件。它们的组织结构如下
# cloud bucket, s3://my-bucket/ for example
my-bucket/
├── job-15891b25/ # Job-specific directory
│ ├── local-file-mounts/ # Files from local file mounts
│ ├── tmp-files/ # Temporary files
│ └── workdir/ # Files from workdir
└── job-cae228be/ # Another job's directory
├── local-file-mounts/
├── tmp-files/
└── workdir/
当使用自定义存储桶(jobs.bucket
)时,作业完成时,SkyPilot 创建的作业特定目录(例如 job-15891b25/
)将被移除。
提示
多个用户可以共享同一个中间存储桶。每个用户的作业将拥有自己唯一的作业特定目录,确保文件分开且井井有条。
工作原理:作业控制器#
作业控制器是在云中运行的小型按需 CPU 虚拟机或 Pod,用于管理用户的所有作业。在提交第一个托管作业时自动启动,并在空闲 10 分钟后自动停止(即,所有托管作业完成后且在此期间没有提交新的托管作业)。因此,管理其生命周期无需用户操作。
您可以使用 sky status
查看控制器,并使用 -r/--refresh
标志刷新其状态。
虽然作业控制器的成本可以忽略不计(运行时约 0.25 美元/小时,停止时低于 0.004 美元/小时),您仍然可以使用 sky down <job-controller-name>
手动将其拆除,其中 <job-controller-name>
可以在 sky status
的输出中找到。
注意
拆除作业控制器将丢失所有已完成托管作业的日志和状态信息。只有在没有进行中的托管作业时才允许拆除,以确保不发生资源泄漏。
要调整作业控制器实例的大小,请参阅自定义作业控制器资源。
设置和最佳实践#
使用长期凭证#
由于作业控制器是用于管理其他云实例的长期实例,因此最好使用不会过期的静态凭证。如果凭证过期,控制器可能无法清理作业,导致昂贵的云实例泄漏。因此,建议设置长期凭证访问,例如 AWS 上的 ~/.aws/credentials
文件,或 GCP 上的服务账户 JSON 密钥文件。
要为作业控制器使用长期静态凭证,只需确保 SkyPilot 正在使用正确的凭证即可。它们将自动上传到作业控制器。如果您已经在使用不会过期的本地凭证,则无需采取任何行动。
设置凭证
AWS:创建专用的 SkyPilot IAM 用户并使用静态
~/.aws/credentials
文件。其他云服务商:确保您正在使用不会过期的凭证。
自定义作业控制器资源#
您可能出于多种原因需要自定义作业控制器的资源
增加可以同时运行的最大作业数量,这取决于控制器实例的大小。(默认:90,请参阅最佳实践)
使用成本较低的控制器(如果您有少量并发托管作业)。
强制作业控制器在特定位置运行。(默认:最便宜的位置)
更改作业控制器的 disk_size 以存储更多日志。(默认:50GB)
为实现上述目标,您可以在 ~/.sky/config.yaml
中通过以下字段指定自定义配置
jobs:
# NOTE: these settings only take effect for a new jobs controller, not if
# you have an existing one.
controller:
resources:
# All configs below are optional.
# Specify the location of the jobs controller.
cloud: gcp
region: us-central1
# Bump cpus to allow more managed jobs to be launched concurrently. (Default: 4+)
cpus: 8+
# Bump memory to allow more managed jobs to be running at once.
# By default, it scales with CPU (8x).
memory: 64+
# Specify the disk_size in GB of the jobs controller.
disk_size: 100
resources
字段的规范与普通 SkyPilot 作业相同;请参见此处。
注意
如果您有现有控制器(无论是停止的还是正在运行的),这些设置将不会生效。要使其生效,首先需要拆除现有控制器,这要求所有进行中的作业完成或被取消。
要查看您当前的作业控制器,请使用 sky status
。
$ sky status --refresh
Clusters
NAME LAUNCHED RESOURCES STATUS AUTOSTOP COMMAND
my-cluster-1 1 week ago 1x AWS(m6i.4xlarge) STOPPED - sky launch --cpus 16 --cloud...
my-other-cluster 1 week ago 1x GCP(n2-standard-16) STOPPED - sky launch --cloud gcp --...
sky-jobs-controller-919df126 1 day ago 1x AWS(r6i.xlarge, disk_size=50) STOPPED 10m sky jobs launch --cpus 2 ...
Managed jobs
No in-progress managed jobs.
Services
No live services.
在此示例中,您可以看到作业控制器(sky-jobs-controller-919df126
)是 AWS 上的 r6i.xlarge,这是默认大小。
要拆除当前控制器以便应用新的资源配置,请使用 sky down
。
$ sky down sky-jobs-controller-919df126
WARNING: Tearing down the managed jobs controller. Please be aware of the following:
* All logs and status information of the managed jobs (output of `sky jobs queue`) will be lost.
* No in-progress managed jobs found. It should be safe to terminate (see caveats above).
To proceed, please type 'delete': delete
Terminating cluster sky-jobs-controller-919df126...done.
Terminating 1 cluster ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
下次您使用 sky jobs launch
时,将创建一个具有更新资源的新控制器。
扩展作业控制器的最佳实践#
提示
对于托管作业,强烈建议使用用于云认证的长期凭证。这样作业控制器的凭证就不会过期。这在大型生产运行中尤为重要,可以避免资源泄漏。
控制器支持的活动作业数量取决于控制器的大小。有两个限制适用
正在启动的作业数量:最多为
4 * vCPU 数量
。作业在首次启动、启动实例或恢复时计入此限制。默认控制器大小有 4 个 CPU,意味着可以同时启动 16 个作业。
正在运行的作业数量:最多为
内存 / 350MiB
,上限为2000
个作业。默认控制器大小有 32GiB 内存,意味着可以并行运行约 90 个作业。
默认大小适用于大多数中等使用场景,但如果您需要同时运行数百或数千个作业,则应增加控制器的大小。
为获得最大并行度,建议进行以下配置
jobs:
controller:
resources:
# In our testing, aws > gcp > azure
cloud: aws
cpus: 128
# Azure does not have 128+ CPU instances, so use 96 instead
# cpus: 96
memory: 600+
disk_size: 500
注意
请记住按照上述说明拆除控制器以应用这些更改。
使用此配置,您将获得以下性能
云服务商 |
实例类型 |
启动中的作业 |
运行中的作业 |
---|---|---|---|
AWS |
r6i.32xlarge |
同时启动 512 个 |
同时运行 2000 个 |
GCP |
n2-highmem-128 |
同时启动 512 个 |
同时运行 2000 个 |
Azure |
Standard_E96s_v5 |
同时启动 384 个 |
同时运行 1930 个 |