创建自定义训练作业

自定义训练作业是在 Vertex AI 中运行自定义机器学习 (ML) 训练代码的基本方法。

提交作业之前

在将自定义训练作业提交到 Vertex AI 之前,您需要创建 Python 训练应用自定义容器,以定义您希望在 Vertex AI 上运行的训练代码和依赖项。如果您创建了 Python 训练应用,则可以使用我们的预构建容器运行您的代码。如果您不确定选择哪个选项,请参阅训练代码要求了解详情。

自定义作业包含的内容

创建自定义作业时,您需要指定 Vertex AI 运行训练代码所需的设置,包括:

在工作器池中,您可以指定以下设置:

配置分布式训练

您可以通过指定多个工作器池为分布式训练配置自定义训练作业。

此页面上的大多数示例均为使用一个工作器池的单副本训练作业。要修改它们以进行分布式训练,请执行以下操作:

  • 使用第一个工作器池配置主副本,并将副本计数设置为 1。
  • 添加更多工作器池来配置工作器副本、参数服务器副本或评估器副本(如果您的机器学习框架支持分布式训练的这些额外集群任务)。

详细了解如何使用分布式训练

创建自定义作业

要创建自定义作业,请执行以下操作:

控制台

在 Google Cloud Console 中,您无法直接创建 CustomJob 资源。但是,您可以创建一个创建 CustomJobTrainingPipeline 资源。

以下说明介绍了如何创建 TrainingPipeline,用于创建 CustomJob 且不执行其他操作。如果您想要使用其他 TrainingPipeline 功能(例如使用代管式数据集进行训练或在训练结束时创建 Model 资源),请参阅创建训练流水线

  1. 在 Cloud Console 的 Vertex AI 部分中,转到训练流水线页面。

    转到“训练流水线”

  2. 点击 创建以打开训练新模型窗格。

  3. 选择训练方法步骤中,指定以下设置:

    1. 数据集下拉列表中,选择无代管式数据集

    2. 选择自定义训练(高级)

    点击继续

  4. 定义模型步骤中,输入您为模型选择的名称 MODEL_NAME。点击 Continue

  5. 训练容器步骤中,指定以下设置:

    1. 选择要使用预构建容器还是自定义容器进行训练。

    2. 根据您的选择,执行以下相应操作:

    3. Model output directory 字段中,您可以指定您有权访问的存储分区中的目录的 Cloud Storage URI。目录不需要已经存在。

      此值会在 baseOutputDirectory API 字段中传递给 Vertex AI,该字段设置训练应用在其运行时可以访问的几个环境变量

    4. 参数字段中,您可以视需要指定 Vertex AI 开始运行训练代码时要使用的参数。这些参数的行为因您使用的容器类型而异:

      • 如果您使用的是预构建容器,Vertex AI 会将参数作为命令行标志传递给 Python 模块

      • 如果您使用的是自定义容器,则 Vertex AI 会使用参数替换容器的 CMD 指令

    点击继续

  6. 超参数调节步骤中,确保未选中启用超参数调节复选框。点击继续

  7. 计算和价格步骤中,指定以下设置:

    1. 区域下拉列表中,选择支持自定义训练的区域

    2. 工作器池 0 部分中,指定用于训练的计算资源

      如果指定加速器,请确保所选加速器类型在所选区域可用

      如果您要执行分布式训练,则点击 Add more worker pools,并为您需要的每个额外工作器池指定一组额外的计算资源。

    点击继续

  8. 预测容器步骤中,选择 No prediction container

  9. 点击开始训练以启动自定义训练流水线。

gcloud

以下示例使用 gcloud beta ai custom-jobs create 命令

根据您是创建 Python 训练应用以与预构建容器搭配使用还是使用自定义容器,运行相应的命令:

预构建容器

gcloud beta ai custom-jobs create \
  --region=LOCATION \
  --display-name=JOB_NAME \
  --python-package-uris=PYTHON_PACKAGE_URIS \
  --worker-pool-spec=machine-type=MACHINE_TYPE,replica-count=REPLICA_COUNT,executor-image-uri=PYTHON_PACKAGE_EXECUTOR_IMAGE_URI,python-module=PYTHON_MODULE

请替换以下内容:

  • LOCATION:将运行容器或 Python 软件包的区域。
  • JOB_NAME:必填。CustomJob 的显示名。
  • PYTHON_PACKAGE_URIS:以逗号分隔的 Cloud Storage URI 列表,指定作为训练程序的 Python 软件包文件及其从属软件包。软件包 URI 的数量上限为 100。
  • MACHINE_TYPE:机器类型。请参阅可用于训练的机器类型
  • REPLICA_COUNT:要使用的工作器副本的数量。在大多数情况下,对于第一个工作器池,请设置为 1
  • PYTHON_PACKAGE_EXECUTOR_IMAGE_URI:运行提供的 Python 软件包的容器映像的 URI。请参阅可用于训练的预构建容器
  • PYTHON_MODULE:安装软件包后要运行的 Python 模块名称。

自定义容器

gcloud beta ai custom-jobs create \
  --region=LOCATION \
  --display-name=JOB_NAME \
  --worker-pool-spec=machine-type=MACHINE_TYPE,replica-count=REPLICA_COUNT,container-image-uri=CUSTOM_CONTAINER_IMAGE_URI

请替换以下内容:

  • LOCATION:将运行容器或 Python 软件包的区域。
  • JOB_NAME:必填。CustomJob 的显示名。
  • MACHINE_TYPE:机器类型。请参阅可用于训练的机器类型
  • REPLICA_COUNT:要使用的工作器副本的数量。在大多数情况下,对于第一个工作器池,请设置为 1
  • CUSTOM_CONTAINER_IMAGE_URI:要在每个工作器副本上运行的容器映像的 Artifact Registry、Container Registry 或 Docker Hub URI。

基于本地代码的自定义容器

如果您的本地计算机上有训练代码,则可以使用单个命令执行以下操作:

  • 根据您的代码构建自定义 Docker 映像。
  • 将映像推送到 Container Registry。
  • 根据映像启动 CustomJob

结果类似于使用任何其他自定义容器创建 CustomJob:如果此命令对工作流来说很方便,您可以使用此版本的命令。

准备工作

由于此版本的命令会构建和推送 Docker 映像,因此您必须在本地计算机上执行以下配置:

  1. 安装 Docker Engine。

  2. 如果您使用的是 Linux,请配置 Docker,以便可以在没有 sudo 的情况下运行它

  3. 启用 Container Registry API。

    启用 API

  4. 为 Docker 配置身份验证,以便将 Docker 映像推送到 Container Registry:

    gcloud auth configure-docker
    

构建和推送 Docker 映像,并创建 CustomJob

以下命令基于预构建的训练容器映像和本地 Python 代码构建 Docker 映像,将该映像推送到 Container Registry,然后创建 CustomJob

gcloud beta ai custom-jobs create \
  --region=LOCATION \
  --display-name=JOB_NAME \
  --worker-pool-spec=machine-type=MACHINE_TYPE,replica-count=REPLICA_COUNT,executor-image-uri=PYTHON_PACKAGE_EXECUTOR_IMAGE_URI,local-package-path=WORKING_DIRECTORY,script=SCRIPT_PATH

请替换以下内容:

  • LOCATION:将运行容器或 Python 软件包的区域。

  • JOB_NAME:必填。CustomJob 的显示名。

  • MACHINE_TYPE:机器类型。请参阅可用于训练的机器类型

  • REPLICA_COUNT:要使用的工作器副本的数量。在大多数情况下,对于第一个工作器池,请设置为 1

  • PYTHON_PACKAGE_EXECUTOR_IMAGE_URI:运行提供的 Python 软件包的容器映像的 URI。请参阅可用于训练的预构建容器

    此映像充当您使用此命令构建的新 Docker 映像的基础映像。

  • WORKING_DIRECTORY:本地文件系统中的目录,包含运行训练代码的入口点脚本(请参阅以下列表项)。

    您可以使用该脚本的父级目录或更高级别的目录。为了指定完全限定的 Python 模块名称,您可能需要使用更高级别的目录(请参阅下面的列表项)。如果更高级层的目录包含 requirements.txt 文件setup.py 文件,则可能要使用更高目录,以便在容器中安装其他依赖项;此功能与 gcloud beta ai custom-jobs local-run 命令中的相应功能类似。但是,即使您指定更高级别的目录,此命令也会将入口点脚本的父目录复制到 Docker 映像。

  • SCRIPT_PATH:相对于本地文件系统上的 WORKING_DIRECTORY 的路径,指向作为训练代码入口点的脚本。该脚本可以是 Python 脚本(以 .py 结尾)或 Bash 脚本。

    例如,如果要运行 /hello-world/trainer/task.pyWORKING_DIRECTORY/hello-world,请使用 trainer/task.py 作为此值。

    使用 python-module,而不是 script

    您可以选择将 script=SCRIPT_PATH 替换为 python-module=PYTHON_MODULE,以指定 WORKING_DIRECTORY 中 Python 模块的名称,以作为训练的入口点运行。例如,您可以指定 python-module=trainer.task,而不是 script=trainer/task.py

    在这种情况下,生成的 Docker 容器会将代码作为模块加载而不是加载脚本。如果您的入口点脚本在 WORKING_DIRECTORY 中导入其他 Python 模块,则建议您使用此选项。

配置分布式训练

如果要执行分布式训练,则可以多次指定 --worker-pool-spec 标志,每个工作器池一次。例如,以下示例将调整上述示例,以使用第二个工作器池:

预构建容器

gcloud beta ai custom-jobs create \
  --region=LOCATION \
  --display-name=JOB_NAME \
  --python-package-uris=PYTHON_PACKAGE_URIS \
  --worker-pool-spec=machine-type=MACHINE_TYPE,replica-count=REPLICA_COUNT,executor-image-uri=PYTHON_PACKAGE_EXECUTOR_IMAGE_URI,python-module=PYTHON_MODULE \
  --worker-pool-spec=machine-type=SECOND_POOL_MACHINE_TYPE,replica-count=SECOND_POOL_REPLICA_COUNT,executor-image-uri=SECOND_POOL_PYTHON_PACKAGE_EXECUTOR_IMAGE_URI,python-module=SECOND_POOL_PYTHON_MODULE

自定义容器

gcloud beta ai custom-jobs create \
  --region=LOCATION \
  --display-name=JOB_NAME \
  --worker-pool-spec=machine-type=MACHINE_TYPE,replica-count=REPLICA_COUNT,container-image-uri=CUSTOM_CONTAINER_IMAGE_URI \
  --worker-pool-spec=machine-type=SECOND_POOL_MACHINE_TYPE,replica-count=SECOND_POOL_REPLICA_COUNT,container-image-uri=SECOND_POOL_CUSTOM_CONTAINER_IMAGE_URI

基于本地代码的自定义容器

在命令中使用 local-package-path=WORKING_DIRECTORY 时,只能配置单个工作器池。分布式训练不可用。

高级配置

如果您想指定前面示例中未提供的配置选项,则可以使用 --config 标志指定本地环境中的 config.yaml 文件的路径,该文件包含 CustomJobSpec 的字段。例如:

gcloud beta ai custom-jobs create \
  --region=LOCATION \
  --display-name=JOB_NAME \
  --config=config.yaml

请参阅 config.yaml 文件示例

REST 和命令行

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

  • LOCATION:将运行容器或 Python 软件包的区域。
  • PROJECT_ID:您的项目 ID 或项目编号。
  • JOB_NAME:必填。CustomJob 的显示名。
  • 定义自定义训练作业:
    • MACHINE_TYPE:机器类型。请参阅可用于训练的机器类型
    • ACCELERATOR_TYPE:(可选)附加到作业的加速器类型。
    • ACCELERATOR_COUNT:(可选)附加到作业的加速器数量。
    • DISK_TYPE:(可选)用于作业的启动磁盘类型:pd-standard(默认)或 pd-ssd详细了解磁盘类型
    • DISK_SIZE:(可选)用于作业的启动磁盘大小(以 GB 为单位)。默认值为 100。
    • REPLICA_COUNT:要使用的工作器副本的数量。在大多数情况下,对于第一个工作器池,请设置为 1
    • 如果训练应用在自定义容器中运行,请指定以下内容:
      • CUSTOM_CONTAINER_IMAGE_URI:要在每个工作器副本上运行的容器映像的 Artifact Registry、Container Registry 或 Docker Hub URI。
      • CUSTOM_CONTAINER_COMMAND:(可选)启动容器时要调用的命令。此命令会替换容器的默认入口点。
      • CUSTOM_CONTAINER_ARGS:(可选)启动容器时要传递的参数。
    • 如果训练应用是在预构建容器中运行的 Python 软件包,请指定以下内容:
      • PYTHON_PACKAGE_EXECUTOR_IMAGE_URI:运行提供的 Python 软件包的容器映像的 URI。请参阅可用于训练的预构建容器
      • PYTHON_PACKAGE_URIS:以逗号分隔的 Cloud Storage URI 列表,指定作为训练程序的 Python 软件包文件及其从属软件包。软件包 URI 的数量上限为 100。
      • PYTHON_MODULE:安装软件包后要运行的 Python 模块名称。
      • PYTHON_PACKAGE_ARGS:(可选)要传递给 Python 模块的命令行参数。
    • 了解作业调度选项
    • TIMEOUT:(可选)作业的最长运行时间。
  • 指定要应用于此自定义作业的任何标签的 LABEL_NAMELABEL_VALUE

HTTP 方法和网址:

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

请求 JSON 正文:

{
  "displayName": "JOB_NAME",
  "jobSpec": {
    "workerPoolSpecs": [
      {
        "machineSpec": {
          "machineType": MACHINE_TYPE,
          "acceleratorType": ACCELERATOR_TYPE,
          "acceleratorCount": ACCELERATOR_COUNT
        },
        "replicaCount": REPLICA_COUNT,
        "diskSpec": {
          "bootDiskType": DISK_TYPE,
          "bootDiskSizeGb": DISK_SIZE
        },

        // 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": PYTHON_PACKAGE_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": {
      "timeout": TIMEOUT
    }
  },
  "labels": {
    LABEL_NAME_1": LABEL_VALUE_1,
    LABEL_NAME_2": LABEL_VALUE_2
  }
}

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

curl

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

curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default 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 application-default 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

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

Node.js

/**
 * TODO(developer): Uncomment these variables before running the sample.\
 * (Not necessary if passing values as arguments)
 */

// const customJobDisplayName = 'YOUR_CUSTOM_JOB_DISPLAY_NAME';
// const containerImageUri = 'YOUR_CONTAINER_IMAGE_URI';
// const project = 'YOUR_PROJECT_ID';
// const location = 'YOUR_PROJECT_LOCATION';

// Imports the Google Cloud Job Service Client library
const {JobServiceClient} = require('@google-cloud/aiplatform');

// Specifies the location of the api endpoint
const clientOptions = {
  apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};

// Instantiates a client
const jobServiceClient = new JobServiceClient(clientOptions);

async function createCustomJob() {
  // Configure the parent resource
  const parent = `projects/${project}/locations/${location}`;
  const customJob = {
    displayName: customJobDisplayName,
    jobSpec: {
      workerPoolSpecs: [
        {
          machineSpec: {
            machineType: 'n1-standard-4',
            acceleratorType: 'NVIDIA_TESLA_K80',
            acceleratorCount: 1,
          },
          replicaCount: 1,
          containerSpec: {
            imageUri: containerImageUri,
            command: [],
            args: [],
          },
        },
      ],
    },
  };
  const request = {parent, customJob};

  // Create custom job request
  const [response] = await jobServiceClient.createCustomJob(request);

  console.log('Create custom job response');
  console.log(`${JSON.stringify(response)}`);
}
createCustomJob();

Python

本示例使用的是 Python 版 Vertex SDK。在运行以下代码示例之前,必须先设置身份验证。

from google.cloud import aiplatform

def create_custom_job_sample(
    project: str,
    display_name: str,
    container_image_uri: str,
    location: str = "us-central1",
    api_endpoint: str = "us-central1-aiplatform.googleapis.com",
):
    # The AI Platform services require regional API endpoints.
    client_options = {"api_endpoint": api_endpoint}
    # Initialize client that will be used to create and send requests.
    # This client only needs to be created once, and can be reused for multiple requests.
    client = aiplatform.gapic.JobServiceClient(client_options=client_options)
    custom_job = {
        "display_name": display_name,
        "job_spec": {
            "worker_pool_specs": [
                {
                    "machine_spec": {
                        "machine_type": "n1-standard-4",
                        "accelerator_type": aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,
                        "accelerator_count": 1,
                    },
                    "replica_count": 1,
                    "container_spec": {
                        "image_uri": container_image_uri,
                        "command": [],
                        "args": [],
                    },
                }
            ]
        },
    }
    parent = f"projects/{project}/locations/{location}"
    response = client.create_custom_job(parent=parent, custom_job=custom_job)
    print("response:", response)

后续步骤

  • 请参阅将模型导入 Vertex AI,了解如何创建自定义训练作业,以在 Vertex AI 上运行自定义训练应用。