Secrets(密钥)和环境变量#

环境变量是向任务传递配置和 Secrets(密钥)的强大方式。SkyPilot 中有两种类型的环境变量

用户指定的环境变量#

用户指定的环境变量对于传递 Secrets(密钥)以及任务所需的任何参数或配置非常有用。它们在 file_mountssetuprun 中可用。

您可以通过几种方式指定任务可用的环境变量

  • 任务 YAML 中的 envs 字段 (dict)

    envs:
      MYVAR: val
    
  • sky launch/exec CLI 中的 --env-file 标志,指向一个 dotenv 文件(优先级高于上述方式)

    # sky launch example.yaml --env-file my_app.env
    # cat my_app.env
    MYVAR=val
    WANDB_API_KEY=MY_WANDB_API_KEY
    HF_TOKEN=MY_HF_TOKEN
    
  • sky launch/exec CLI 中的 --env 标志(优先级高于上述方式)

提示

要将环境变量标记为必需,并让 SkyPilot 强制检查其是否存在(如果未指定则报错),请在任务 YAML 中将其设置为空字符串或 null。例如,以下任务 YAML 中的 WANDB_API_KEYHF_TOKEN 已被标记为必需

envs:
  WANDB_API_KEY:
  HF_TOKEN: null
  MYVAR: val

任务 YAML 的 file_mountssetuprun 部分可以通过 ${MYVAR} 语法访问这些变量。

传递 Secrets(密钥)#

我们建议通过以下方式将 Secrets(密钥)传递给执行任务的节点:首先在当前 shell 中使其可用,然后使用 --env SECRET 将其传递给 SkyPilot

$ sky launch -c mycluster --env HF_TOKEN --env WANDB_API_KEY task.yaml
$ sky exec mycluster --env WANDB_API_KEY task.yaml

提示

您不需要直接传递值,例如 --env WANDB_API_KEY=1234。当未指定值时(例如,--env WANDB_API_KEY),SkyPilot 会从本地环境变量中读取它。

file_mounts 中使用#

# Sets default values for some variables; can be overridden by --env.
envs:
  MY_BUCKET: skypilot-temp-gcs-test
  MY_LOCAL_PATH: tmp-workdir
  MODEL_SIZE: 13b

file_mounts:
    /mydir:
        name: ${MY_BUCKET}  # Name of the bucket.
        mode: MOUNT

    /another-dir2:
        name: ${MY_BUCKET}-2
        source: ["~/${MY_LOCAL_PATH}"]

    /checkpoint/${MODEL_SIZE}: ~/${MY_LOCAL_PATH}

这些变量的值由 SkyPilot 在解析任务 YAML 时填充。

更多信息请参阅 examples/using_file_mounts_with_env_vars.yaml

setuprun 中使用#

所有用户指定的环境变量都会导出到任务的 setuprun 命令中(即在运行时可访问)。

例如,这对于传递 Secrets(密钥)(参见下文)或传递配置非常有用

# Sets default values for some variables; can be overridden by --env.
envs:
  MODEL_NAME: decapoda-research/llama-65b-hf

run: |
  python train.py --model_name ${MODEL_NAME} <other args>
$ sky launch --env MODEL_NAME=decapoda-research/llama-7b-hf task.yaml  # Override.

完整的示例请参阅 llm/vllm/serve.yamlllm/vicuna/train.yaml

SkyPilot 环境变量#

SkyPilot 导出了一些预定义的环境变量,这些变量在任务执行期间可用。这些变量包含有关当前集群或任务的信息,对于分布式框架(如 torch.distributed、OpenMPI 等)非常有用。请参阅分布式多节点作业托管作业中的示例。

这些变量的值由 SkyPilot 在任务执行时填充。您可以通过以下方式访问这些变量

  • 在任务 YAML 的 setup/run 命令(一个 Bash 脚本)中,使用 ${MYVAR} 语法访问它们;

  • setup/run 中启动的程序中,使用语言的标准方法访问它们(例如,Python 中的 os.environ)。

setup 和 run 阶段可以访问不同的 SkyPilot 环境变量集

setup 的环境变量#

名称

定义

示例

SKYPILOT_SETUP_NODE_RANK

正在设置的节点的排名(从 0 到 num_nodes-1 的整数 ID)。

0

SKYPILOT_SETUP_NODE_IPS

集群中节点的 IP 地址字符串,顺序与节点排名相同,每行包含一个 IP 地址。

请注意,这不一定与 run 阶段的节点相同:setup 阶段在集群的所有节点上运行,而 run 阶段可以在节点的子集上运行。

1.2.3.4
3.4.5.6

SKYPILOT_NUM_NODES

集群中的节点数量。与 $(echo "$SKYPILOT_NODE_IPS" | wc -l) 的值相同。

2

SKYPILOT_TASK_ID

分配给每个任务的唯一 ID。

请参阅run 的环境变量中的描述。

sky-2023-07-06-21-18-31-563597_myclus_1

对于托管 Spot 作业:sky-managed-2023-07-06-21-18-31-563597_my-job-name_1-0

SKYPILOT_CLUSTER_INFO

包含集群信息的 JSON 字符串。要访问信息,您可以在 bash 中解析 JSON 字符串 echo $SKYPILOT_CLUSTER_INFO | jq .cloud 或在 Python 中

import json
json.loads(
  os.environ['SKYPILOT_CLUSTER_INFO']
)['cloud']

{"cluster_name": "my-cluster-name", "cloud": "GCP", "region": "us-central1", "zone": "us-central1-a"}

SKYPILOT_SERVE_REPLICA_ID

服务内副本的 ID(从 1 开始)。仅适用于服务的副本任务。

1

由于 setup 命令总是在集群的所有节点上运行,SkyPilot 确保这两个环境变量(排名和 IP 列表)在同一集群上的多次 setup 中永远不会改变。

run 的环境变量#

名称

定义

示例

SKYPILOT_NODE_RANK

执行任务的节点的排名(从 0 到 num_nodes-1 的整数 ID)。在此处阅读更多信息:分布式多节点作业

0

SKYPILOT_NODE_IPS

保留用于执行任务的节点的 IP 地址字符串,每行包含一个 IP 地址。在此处阅读更多信息:分布式多节点作业

1.2.3.4

SKYPILOT_NUM_NODES

分配给执行当前任务的节点数量。与 $(echo "$SKYPILOT_NODE_IPS" | wc -l) 的值相同。在此处阅读更多信息:分布式多节点作业

1

SKYPILOT_NUM_GPUS_PER_NODE

每个节点上保留用于执行任务的 GPU 数量;与 accelerators: <name>:<count> 中的数量相同(如果是小数则向上取整)。在此处阅读更多信息:分布式多节点作业

0

SKYPILOT_TASK_ID

分配给每个任务的唯一 ID,格式为“sky-__”。用于日志记录目的:例如,在集群上使用唯一的输出路径;传递给 Weights & Biases 等。每个任务的日志存储在集群的 ~/sky_logs/${SKYPILOT_TASK_ID%%_*}/tasks/*.log

如果一个任务作为托管 Spot 作业运行,则该作业的所有恢复都将具有相同的 ID 值。ID 格式为“sky-managed-_ (_)_-”,其中当使用管道时,<task-name> 将会出现,即一个托管 Spot 作业中有多个任务。

sky-2023-07-06-21-18-31-563597_myclus_1

对于托管 Spot 作业:sky-managed-2023-07-06-21-18-31-563597_my-job-name_1-0

SKYPILOT_CLUSTER_INFO

包含集群信息的 JSON 字符串。要访问信息,您可以在 bash 中解析 JSON 字符串 echo $SKYPILOT_CLUSTER_INFO | jq .cloud 或在 Python 中

import json
json.loads(
  os.environ['SKYPILOT_CLUSTER_INFO']
)['cloud']

{"cluster_name": "my-cluster-name", "cloud": "GCP", "region": "us-central1", "zone": "us-central1-a"}

SKYPILOT_SERVE_REPLICA_ID

服务内副本的 ID(从 1 开始)。仅适用于服务的副本任务。

1