将 Spot 虚拟机用于训练

概览

您可以使用 Spot 虚拟机来降低运行自定义训练作业的费用。Spot 虚拟机是过剩的 Compute Engine 容量的虚拟机 (VM) 实例。Spot 虚拟机的折扣力度很大,但 Compute Engine 可能会提前停止或删除(抢占)Spot 虚拟机来随时收回容量。

如需了解详情,请参阅 Spot 虚拟机

限制和要求

将 Spot 虚拟机与 Vertex AI 搭配使用时,请考虑以下限制和要求:

  • 将 Spot 虚拟机与 Vertex AI 搭配使用时,所有Spot 虚拟机限制均适用。
  • 仅支持将 Spot 虚拟机与 Vertex AI 搭配使用进行自定义训练和预测。
  • 不支持将 Spot 虚拟机与 TPU Pod 搭配使用。
  • Vertex AI 训练只能使用以下机器系列的 Spot 虚拟机:

    • A2
    • A3
  • 不支持通过 Google Cloud 控制台提交作业。

结算

如果您的工作负载具有容错能力,并且可以承受可能的虚拟机抢占,Spot 虚拟机可以显著降低您的计算费用。如果其中某些虚拟机在处理期间停止,作业会减慢但不会完全停止。Spot 虚拟机可完成您的批处理任务,而不会在现有虚拟机上增加额外的负载,您也不再需要为额外的标准虚拟机支付全价。请参阅抢占处理

使用 Spot 虚拟机时,您需要按作业时长和机器类型付费。您无需为作业在队列中或被抢占的时间付费。

抢占处理

Compute Engine 可随时回收 Spot 虚拟机。因此,您的自定义训练作业必须具有容错能力,才能充分利用 Spot 虚拟机。当抢占式虚拟机被抢占时,自定义训练作业会失败并显示 STOCKOUT 错误,Compute Engine 会尝试最多重启该作业六次。如需了解如何充分利用 Spot 虚拟机,请参阅 Spot 虚拟机最佳实践

以下是一些可用于使自定义训练作业具有容错能力的方法:

  • 创建检查点以保存进度。通过定期存储模型的进度,您可以确保终止的自定义训练作业可以从上次存储的检查点继续运行,而不是从头开始。
  • 使用 Elastic Horovod。借助弹性训练,Horovod 可以扩缩计算资源,而无需重启或从检查点恢复。如需了解详情,请参阅 Elastic Horovod
  • 使用关停脚本。如果 Compute Engine 抢占 Spot 虚拟机,您可以使用关停脚本尝试在虚拟机被抢占前执行清理操作。如需了解详情,请参阅使用关停脚本处理抢占

准备工作

准备自定义训练应用:

将训练作业配置为使用 Spot 虚拟机

您可以通过在调度配置中指定 SPOT 策略,将自定义训练作业配置为使用 Spot 虚拟机。

REST

在使用任何请求数据之前,请先进行以下替换:

  • LOCATION:将运行容器或 Python 软件包的区域。
  • PROJECT_ID:您的项目 ID
  • JOB_NAME:必填。CustomJob 的显示名称。
  • 定义自定义训练作业:
    • MACHINE_TYPE:机器类型。请参阅可用于训练的机器类型
    • REPLICA_COUNT:要使用的工作器副本的数量。在大多数情况下,对于第一个工作器池,请设置为 1
    • 如果训练应用在自定义容器中运行,请指定以下内容:
      • CUSTOM_CONTAINER_IMAGE_URI:包含训练代码的 Docker 容器映像的 URI。了解如何创建自定义容器映像
      • CUSTOM_CONTAINER_COMMAND:可选。启动容器时要调用的命令。此命令会替换容器的默认入口点。
      • CUSTOM_CONTAINER_ARGS:可选。启动容器时要传递的参数。
    • 如果训练应用是在预构建容器中运行的 Python 软件包,请指定以下内容:
      • EXECUTOR_IMAGE_URI:运行所提供代码的容器映像的 URI。请参阅可用于训练的预构建容器
      • PYTHON_PACKAGE_URIS:以逗号分隔的 Cloud Storage URI 列表,指定作为训练程序的 Python 软件包文件及其从属软件包。软件包 URI 的数量上限为 100。
      • PYTHON_MODULE:安装软件包后要运行的 Python 模块名称。
      • PYTHON_PACKAGE_ARGS:可选。要传递给 Python 模块的命令行参数。

HTTP 方法和网址:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/customJobs

请求 JSON 正文:

{
  "displayName": "JOB_NAME",
  "jobSpec": {
    "workerPoolSpecs": [
      {
        "machineSpec": {
          "machineType": "MACHINE_TYPE"
          }
        },
        "replicaCount": REPLICA_COUNT,

        // Union field task can be only one of the following:
        "containerSpec": {
          "imageUri": CUSTOM_CONTAINER_IMAGE_URI,
          "command": [
            CUSTOM_CONTAINER_COMMAND
          ],
          "args": [
            CUSTOM_CONTAINER_ARGS
          ]
        },
        "pythonPackageSpec": {
          "executorImageUri": EXECUTOR_IMAGE_URI,
          "packageUris": [
            PYTHON_PACKAGE_URIS
          ],
          "pythonModule": PYTHON_MODULE,
          "args": [
            PYTHON_PACKAGE_ARGS
          ]
        }
        // End of list of possible types for union field task.
      }
      // Specify one workerPoolSpec for single replica training, or multiple workerPoolSpecs
      // for distributed training.
    ],
    "scheduling": {
      "strategy": "SPOT"
    }
  }
}

如需发送请求,请选择以下方式之一:

curl

将请求正文保存在名为 request.json 的文件中,然后执行以下命令:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/customJobs"

PowerShell

将请求正文保存在名为 request.json 的文件中,然后执行以下命令:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/customJobs" | Select-Object -Expand Content

响应包含有关规范的信息以及 JOB_ID

Python

如需了解如何安装或更新 Vertex AI SDK for Python,请参阅安装 Vertex AI SDK for Python。如需了解详情,请参阅 Vertex AI SDK for Python API 参考文档

customJob = aiplatform.CustomJob(
    display_name=TEST_CASE_NAME,
    worker_pool_specs=worker_pool_spec,
    staging_bucket=OUTPUT_DIRECTORY
)
customJob.run(
    scheduling_strategy=aiplatform.compat.types.custom_job.Scheduling.Strategy.SPOT
)

后续步骤