创建自定义组件

更新时间:
复制 MD 格式

自定义组件支持您封装自有算法,并在 Designer 中与 PAI 官方组件串联使用,实现灵活的工作流编排。

背景信息

自定义组件底层采用阿里云开源的 KubeDL,一个基于 Kubernetes 的 AI 工作负载管理框架。

创建自定义组件时,您可以选择任务类型(Tensorflow、PyTorch、XGBoost、ElasticBatch)、创建输入输出管道、配置超参等。组件创建后会转换为 Designer 界面可视化参数,详情参见操作步骤

前提条件

已创建工作空间。自定义组件与工作空间绑定。详情参见创建及管理工作空间

操作步骤

  1. 进入组件管理页面。

    1. 登录PAI 控制台

    2. 在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。

    3. 在左侧导航栏,选择AI资产管理>自定义组件

  2. 在组件列表页面,单击新建组件,并在新建组件页面配置以下参数。

    • 基本信息配置

      参数

      描述

      组件名称

      自定义组件名称,在同一个地域下要求主账号内唯一。

      组件描述

      简要描述自定义组件,便于区分不同组件。

      组件版本

      创建的自定义组件版本号。

      说明

      建议使用 x.y.z 格式管理版本。例如首个版本为 1.0.0,修复问题时升级为 1.0.1,功能升级时升级为 1.1.0。

      版本描述

      对当前创建的自定义组件版本进行描述。例如:初始版本。

    • 执行配置

      参数

      描述

      任务类型

      选择任务类型。支持 TensorflowPyTorchXGBoostElasticBatch 四种类型,分别对应KubeDL中的TFJobPyTorchJobXGBoostJob、ElasticBatchJob四种任务类型。详情参见附录:任务类型介绍

      执行镜像

      当前支持选择社区镜像官方镜像自定义镜像,您也可以在镜像地址页签配置三种类型的镜像地址。

      说明
      • 为保证任务稳定性,请使用同一 Region 下阿里云镜像服务(ACR)。

      • 仅支持 ACR 个人版,不支持企业版。镜像地址请填写 VPC 地址,格式为:registry-vpc.${region}.aliyuncs.com

      • 请勿在同一版本中频繁更新自定义镜像,否则镜像缓存无法及时刷新,导致任务启动时间延长。

      • 镜像中必须包含 sh shell 命令,系统通过 sh -c 方式执行命令。

      • 自定义镜像中须包含 Python 环境和 pip 命令,否则任务可能运行失败。

      执行代码

      自定义组件的代码目录支持 OSS 目录和 Git 地址:

      • OSS 挂载:组件运行时,该 OSS 目录中的文件会下载到/ml/usercode/目录下,您可以通过命令执行该目录下的文件。

        说明
        • 建议该目录只存放算法必需的文件,文件过多会导致启动超时。

        • 代码目录中存在 requirements.txt 时,运行时会自动执行pip install -r requirements.txt安装相关依赖。

      • PAI 代码配置:配置 Git 代码库。

      执行命令

      组件镜像的执行命令。通过环境变量获取实际值,格式如下:

      python main.py $PAI_USER_ARGS --{CHANNEL_NAME} $PAI_INPUT_{CHANNEL_NAME} --{CHANNEL_NAME} $PAI_OUTPUT_{CHANNEL_NAME} && sleep 150 && echo "job finished"

      通过 PAI_USER_ARGSPAI_INPUT_{CHANNEL_NAME}、PAI_OUTPUT_{CHANNEL_NAME} 环境变量读取超参、输入和输出管道数据,详情参见如何读取管道及超参数据

      例如:输入管道名称分别为test、train;输出管道名称分别为model、checkpoints,则配置示例如下:

      python main.py $PAI_USER_ARGS --train $PAI_INPUT_TRAIN --test $PAI_INPUT_TEST --model $PAI_OUTPUT_MODEL --checkpoints $PAI_OUTPUT_CHECKPOINTS && sleep 150 && echo "job finished"

      代码入口文件 main.py 的参数解析逻辑示例如下,实际使用时将您的算法逻辑整合进去即可:

      import os
      
      import argparse
      import json
      
      def parse_args():
          """解析给到脚本的arguments."""
          parser = argparse.ArgumentParser(description="PythonV2 component script example.")
      
          # input & output channels
          parser.add_argument("--train", type=str, default=None, help="input channel train.")
          parser.add_argument("--test", type=str, default=None, help="input channel test.")
          parser.add_argument("--model", type=str, default=None, help="output channel model.")
          parser.add_argument("--checkpoints", type=str, default=None, help="output channel checkpoints.")
      
          # parameters
          parser.add_argument("--param1", type=int, default=None, help="param1")
          parser.add_argument("--param2", type=float, default=None, help="param2")
          parser.add_argument("--param3", type=str, default=None, help="param3")
          parser.add_argument("--param4", type=bool, default=None, help="param4")
          parser.add_argument("--param5", type=int, default=None, help="param5")
      
          args, _ = parser.parse_known_args()
          return args
      
      if __name__ == "__main__":
          args = parse_args()
      
          print("Input channel train={}".format(args.train))
          print("Input channel test={}".format(args.test))
          print("Output channel model={}".format(args.model))
          print("Output channel checkpoints={}".format(args.checkpoints))
      
          print("Parameters param1={}".format(args.param1))
          print("Parameters param2={}".format(args.param2))
          print("Parameters param3={}".format(args.param3))
          print("Parameters param4={}".format(args.param4))
          print("Parameters param5={}".format(args.param5))
      

      示例代码运行时的日志输出如下:

      Input channel train=/ml/input/data/train
      Input channel test=/ml/input/data/test/easyrec_config.config
      Output channel model=/ml/output/model/
      Output channel checkpoints=/ml/output/checkpoints/
      Parameters param1=6
      Parameters param2=0.3
      Parameters param3=test1
      Parameters param4=True
      Parameters param5=2
      job finished
    • 管道及参数

      单击image..png配置自定义组件的输入管道(Input Channel)、输出管道(Output Channel)和参数。名称命名格式如下:

      • 要求全局唯一,且互相不能重复。

      • 支持数字、字母、下划线(_)和减号(-),不能以下划线开头。

        说明

        名称中不支持的字符(仅支持字母、数字和下划线)会被替换为下划线,小写字母会转为大写。请避免转换后产生冲突,例如 test_model 和 test-model 转换后都是 PAI_HPS_TEST_MODEL。

      管道及参数配置与 Designer 组件界面参数的对应关系:a8ff0de8871ede6a80f9c642b4f187aa..png

      具体参数配置说明如下:

      参数

      描述

      输入

      通过输入管道获取输入数据或 Fine-tune 模型,支持配置以下参数:

      • 输入名称:参照界面提示配置输入管道名称。

      • 输入来源:指定输入管道读取 OSS、NAS 或 MaxCompute 路径的数据。输入数据会挂载到训练容器的/ml/input/data/{channel_name}/目录下,组件可像读取本地文件一样访问 OSS、NAS 或 MaxCompute 上的数据。

      输出

      输出管道用于保存训练模型、Checkpoints等结果,支持配置以下参数:

      • 输出名称:参照界面提示配置输出管道名称。

      • 存储类型:指定一个 OSS 或 MaxCompute 目录,该目录会挂载到训练容器的/ml/output/{channel_name}/下。

      参数

      超参信息,支持配置以下参数:

      • 参数名称:参照界面提示配置参数名称。

      • 参数类型:目前支持配置Int、Float、String、Bool四种类型。

      • 约束:选择除Bool外的参数类型(包括Int、Float、String)后,在默认值列,单击约束,来配置参数约束关系。约束类型取值如下:

        • 范围:通过配置最大值和最小值来指定取值范围。

        • 枚举:为参数配置枚举值。

    • 训练约束

      训练约束定义训练任务所需的计算资源。打开开启训练约束开关即可配置。

      配置训练约束后,在 Designer 工作流中使用该组件时,右侧执行调优面板中的机器实例类型规格选择机器数量最大运行时长(秒)等参数将受约束限制。

      具体参数说明如下:

      参数

      描述

      机器类型

      选择组件支持 CPU 或 GPU 机器。

      支持多机

      是否支持多机分布式运行:

      • 支持:运行时支持配置节点数。

      • 不支持:运行时节点数固定为 1,不可修改。

      支持多卡

      仅当机器类型选择GPU时,支持配置该参数。

      是否支持多卡 GPU:

      • 支持机器类型支持选择单卡或多卡GPU机器。

      • 不支持机器类型仅支持选择单卡GPU机器。

  3. 单击提交

    组件列表页面显示已创建的自定义组件。

组件创建成功后,后续您可以在Designer中使用该自定义组件,详情参见使用自定义组件

附录1:任务类型介绍

Tensorflow(TFJob)

任务类型为 Tensorflow(TFJob) 时,节点拓扑信息通过环境变量 TF_CONFIG 注入,格式示例如下:

{
  "cluster": {
    "chief": [
      "dlc17****iui3e94-chief-0.t104140334615****.svc:2222"
    ],
    "evaluator": [
      "dlc17****iui3e94-evaluator-0.t104140334615****.svc:2222"
    ],
    "ps": [
      "dlc17****iui3e94-ps-0.t104140334615****.svc:2222"
    ],
    "worker": [
      "dlc17****iui3e94-worker-0.t104140334615****.svc:2222",
      "dlc17****iui3e94-worker-1.t104140334615****.svc:2222",
      "dlc17****iui3e94-worker-2.t104140334615****.svc:2222",
      "dlc17****iui3e94-worker-3.t104140334615****.svc:2222"
    ]
  },
  "task": {
    "type": "chief",
    "index": 0
  }
}

关键参数说明:

参数

描述

cluster

TensorFlow 集群描述,Map 类型:

  • Key:节点的角色类型(Chief、Worker、PS、Evaluator 或 Master)。

  • Value:该角色的机器网络地址列表。

task

  • type:当前节点的角色类型。

  • index:当前节点在其角色对应的网络地址列表中的索引。

Pytorch(PyTorchJob)

任务类型为 Pytorch(PyTorchJob) 时,注入以下环境变量:

  • RANK:当前节点的序号。0 表示 Master 节点,非 0 为 Worker 节点。

  • WORLD_SIZE:任务中机器的总数量。

  • MASTER_ADDR:Master 节点的地址。

  • MASTER_PORT:Master 节点的端口。

XGBoost(XGBoostJob)

任务类型为 XGBoost(XGBoostJob) 时,注入以下环境变量:

  • RANK:当前节点的序号。0 表示 Master 节点,非 0 为 Worker 节点。

  • WORLD_SIZE:任务中机器的总数量。

  • MASTER_ADDR:Master 节点的地址。

  • MASTER_PORT:Master 节点的端口。

  • WORKER_ADDRS:Worker 节点的地址,按 RANK 顺序排列。

  • WORKER_PORT:Worker 节点的端口。

示例如下:

  • 分布式任务(节点数超过 1)

    WORLD_SIZE=6
    WORKER_ADDRS=train1pt84cj****-worker-0,train1pt84cj****-worker-1,train1pt84cj****-worker-2,train1pt84cj****-worker-3,train1pt84cj****-worker-4
    MASTER_PORT=9999
    MASTER_ADDR=train1pt84cj****-master-0
    RANK=0
    WORKER_PORT=9999
  • 单节点运行

    说明

    单节点运行时,节点为 Master 节点,不会注入 WORKER_ADDRS 和 WORKER_PORT 环境变量。

    WORLD_SIZE=1
    MASTER_PORT=9999
    MASTER_ADDR=train1pt84cj****-master-0
    RANK=0

ElasticBatch(ElasticBatchJob)

ElasticBatch 是一种分布式离线弹性批量推理作业类型,具有以下特点:

  • 轻松并行,吞吐量翻倍。

  • 任务等待时间大幅降低,部分 Worker 有资源即可运行。

  • 自动监测慢机并启动 Backup Worker 替换,避免任务长尾或挂起。

  • 支持数据分片全局动态分发,让快节点处理更多数据。

  • 支持任务早停,数据全部处理完成后,未启动的 Worker 不再启动。

  • 支持容错处理,单 Worker 偶发失败会自动重启。

ElasticBatch Job 包含 AIMaster 和 Worker 两类节点:

  • AIMaster:负责 Job 的全局管控,包括数据分片动态分发、Worker 性能监测和容错处理。

  • Worker:工作节点,从 AIMaster 获取分片后执行数据读取、处理和写回,然后获取下一个分片。动态分片机制使快机器处理更多数据,慢机器少处理数据。

ElasticBatch 任务启动后,您的代码运行在 Worker 节点中。Worker 节点会注入 ELASTICBATCH_CONFIG 环境变量,格式示例如下:

{
  "task": {
    "type": "worker",
    "index": 0
  },
  "environment": "cloud"
}

参数说明:

  • task.type:当前节点的角色类型。

  • task.index:当前节点在其角色对应的网络地址列表中的索引。

附录2:自定义组件实现原理

如何读取管道及超参数据

读取输入管道数据

每个输入管道的数据路径通过 PAI_INPUT_{CHANNEL_NAME} 环境变量注入到容器中。

例如组件有 train、test 两个输入管道,其值分别为:oss://<YourOssBucket>.<OssEndpoint>/path-to-data/oss://<YourOssBucket>.<OssEndpoint>/path-to-data/test.csv,注入的环境变量如下:

PAI_INPUT_TRAIN=/ml/input/data/train/
PAI_INPUT_TEST=/ml/input/data/test/test.csv

读取输出管道数据

通过 PAI_OUTPUT_{CHANNEL_NAME} 环境变量获取输出路径。

例如组件有 model 和 checkpoints 两个输出管道,注入的环境变量如下:

PAI_OUTPUT_MODEL=/ml/output/model/
PAI_OUTPUT_CHECKPOINTS=/ml/output/checkpoints/

读取超参数据

超参数据通过以下环境变量读取:

  • PAI_USER_ARGS

    所有超参以 --{hyperparameter_name} {hyperparameter_value} 的形式注入到 PAI_USER_ARGS 环境变量中。

    例如指定超参 {"epochs": 10, "batch-size": 32, "learning-rate": 0.001},则 PAI_USER_ARGS 的值为:

    PAI_USER_ARGS="--epochs 10 --batch-size 32 --learning-rate 0.001"
  • PAI_HPS_{HYPERPARAMETER_NAME}

    每个超参也会单独以环境变量注入。超参名中不支持的字符(仅支持字母、数字和下划线)会被替换为下划线。

    例如指定超参 {"epochs": 10, "batch-size": 32, "train.learning_rate": 0.001},对应的环境变量如下:

    PAI_HPS_EPOCHS=10
    PAI_HPS_BATCH_SIZE=32
    PAI_HPS_TRAIN_LEARNING_RATE=0.001
  • PAI_HPS

    所有超参以 JSON 格式通过 PAI_HPS 环境变量注入。

    例如传递超参 {"epochs": 10, "batch-size": 32},则 PAI_HPS 的值为:

    PAI_HPS={"epochs": 10, "batch-size": 32}

输入输出目录结构

除了通过环境变量获取管道路径,也可以直接访问容器内的挂载路径。任务在容器内执行时,按以下规则创建路径:

  • 代码路径:/ml/usercode/

  • 超参配置文件:/ml/input/config/hyperparameters.json

  • 训练作业的完整配置文件:/ml/input/config/training_job.json

  • 输入管道的目录路径:/ml/input/data/{channel_name}/

  • 输出管道的目录路径:/ml/output/{channel_name}/

输入输出目录结构完整示例如下:

/ml
|-- usercode                        # 用户代码加载到/ml/usercode目录,这里也是用户代码的工作目录. 可以通过环境变量PAI_WORKING_DIR获得。
|   |-- requirements.txt
|   |-- main.py
|-- input                           # 作业输入数据和配置信息
|   |-- config                      # config目录包含了作业的配置信息, 可以通过PAI_CONFIG_DIR获取。
|       |-- training_job.json       # 作业的完整配置。
|       |-- hyperparameters.json    # 训练作业超参.
|   |-- data                        # 作业的InputChannels: 以下目录包含了两个channel: train_data和test_data。
|       |-- test_data
|       |   |-- test.csv
|       |-- train_data
|           |-- train.csv
|-- output                          # 作业的输出Channels: 这里有model/checkpoints两个输出channel。
        |-- model                   # 通过环境变量PAI_OUTPUT_{OUTPUT_CHANNEL_NAME}可以获输出路径。
        |-- checkpoints

如何判断是否是GPU机器以及GPU卡数

任务启动后,通过环境变量 NVIDIA_VISIBLE_DEVICES 判断当前机器是否有 GPU 及 GPU 卡数。例如 NVIDIA_VISIBLE_DEVICES=0,1,2,3 表示当前机器有 4 张 GPU 卡。