Platform for AI (PAI) lets you create custom components for specific use cases. You can connect these custom components with official PAI components in Designer to build more flexible pipelines. This article describes how to create a custom component.
Background information
Custom components are built on KubeDL, an open-source AI workload management framework from Alibaba Cloud that is based on Kubernetes.
When you create a custom component, you can select a job type, such as TensorFlow, PyTorch, XGBoost, or ElasticBatch, create input and output pipelines, and configure hyperparameters. After you create a custom component, Designer converts its settings into a visual configuration panel. For more information, see Procedure.
KubeDL provides a synchronized set of environment variables for each job type. You can use these variables to get the number of instances and topology information. For more information, see Appendix 1: Job types.
You can read data from input and output pipelines and access hyperparameter data by setting environment variables in the command. For more information, see How to read pipeline and hyperparameter data.
In your execution code, you can access input or output pipelines either through environment variables or directly through the mount path inside the container. For more information, see Input and output directory structure.
Prerequisites
A workspace is required. All custom components you create are bound to this workspace. For more information, see Create and manage workspaces.
Procedure
Go to the component management page.
Log on to the PAI console.
In the left-side navigation pane, click Workspaces. On the Workspaces page, click the name of the target workspace.
In the left-side navigation pane, choose AI Computing Asset Management>Custom Components.
On the component list page, click New Component. On the New Component page, configure the following parameters.
Basic information
Parameter
Description
Component Name
The name of the custom component. The name must be unique within your Alibaba Cloud account in the same region.
Description
A brief description of the custom component to help distinguish it from others.
Component Version
The version number for the custom component you are creating.
NoteWe recommend that you use the
x.y.zversioning format to manage versions. For example, you can set the first major version to 1.0.0. For minor bug fixes, you can update the version number to 1.0.1. For minor feature upgrades, you can update the version number to 1.1.0. This versioning method is clear and straightforward, and helps you understand the differences and updates between versions.Version Description
A description for the current version of the custom component. For example: Initial version.
Execution configuration
Parameter
Description
Job type
When creating a custom component, you must select a job type. PAI supports TensorFlow, PyTorch, XGBoost, and ElasticBatch, which correspond to the TFJob, PyTorchJob, XGBoostJob, and ElasticBatchJob types in KubeDL. For more information about each job type, see Appendix: Job types.
Image
You can select a Community Image, an Alibaba Cloud Image, or a Custom Image. You can also configure the address for any of these image types on the Image URL tab.
NoteTo ensure job stability, use an image from Container Registry (ACR) in the same region as your workspace. Public network bandwidth is limited.
Currently, only ACR Personal Edition is supported, not the Enterprise Edition. The image address must be the VPC address in the format:
registry-vpc.${region}.aliyuncs.com.Frequent updates can delay image cache updates, increasing the job startup time.
To ensure that the image executes properly, it must contain the
sh shellcommand. In addition, commands in the image are executed by usingsh -c.If you use a custom image, make sure it includes a Python execution environment and the pip command. Otherwise, the job might fail.
Code
The code for a custom component can come from an OSS directory or a Git repository:
OSS mount: When the component runs, all files in the mounted OSS directory are downloaded to the
/ml/usercode/directory. You can then use commands to execute these files.NoteWe recommend storing only the files essential for the current algorithm in this directory. Including unnecessary files can increase the component's startup time or cause a timeout.
If a requirements.txt file exists in the code directory, the algorithm runtime automatically executes
pip install -r requirements.txtto install the required dependencies.
PAI code configuration: Configure the Git repository.
Command
The command to run in the component's image. You can use environment variables to retrieve the actual values at runtime. The configuration format is as follows:
python main.py $PAI_USER_ARGS --{CHANNEL_NAME} $PAI_INPUT_{CHANNEL_NAME} --{CHANNEL_NAME} $PAI_OUTPUT_{CHANNEL_NAME} && sleep 150 && echo "job finished"In the command, you can read data for hyperparameters, input pipelines, and output pipelines by using the PAI_USER_ARGS, PAI_INPUT_{CHANNEL_NAME}, and PAI_OUTPUT_{CHANNEL_NAME} environment variables. For details on how to read this data, see How to read pipeline and hyperparameter data.
For example, if the input pipelines are named test and train, and the output pipelines are named model and checkpoints, the command would look like this:
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"The accompanying entry point file, main.py, provides an example of the logic for parsing arguments. You can integrate your own algorithm logic into this file. The following is an example of its content:
import os import argparse import json def parse_args(): """Parse arguments passed to the script.""" 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))The following logs are printed when the sample code runs. This method allows you to access the parameter information for the job:
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 finishedPipelines and parameters
Click
to configure the input pipelines, output pipelines, and parameters for the custom component. Follow these naming conventions:Names must be globally unique.
Names can contain numbers, letters, underscores (_), and hyphens (-), but cannot start with an underscore.
NoteIf a name contains characters that are not supported by environment variables (which only allow letters, numbers, and underscores), these characters are replaced with underscores when environment variables are generated. In addition, lowercase letters are converted to uppercase. To avoid conflicts, do not use names that could become identical after this conversion. For example, parameter names like test_model and test-model would both become PAI_HPS_TEST_MODEL, causing a conflict.
The following figure shows how the pipeline and parameter configurations map to the component's UI in Designer:

The following table describes the parameters.
Parameter
Description
Input
An input pipeline provides the custom component with input data or a model for fine-tuning. You can configure the following parameters:
Input Name: The name of the input pipeline. Refer to the UI for naming requirements.
Input source: Specifies that the input pipeline reads data from a path in OSS, NAS, or MaxCompute. The input data is mounted to the
/ml/input/data/{channel_name}/directory in the training container. This allows the component to read the data from OSS, NAS, or MaxCompute by reading local files.
Output
An output pipeline saves results, such as the trained model and checkpoints. You can configure the following parameters:
Output Name: The name of the output pipeline. Refer to the UI for naming requirements.
Storage: For each output pipeline, you must specify an OSS or MaxCompute directory. This directory will be mounted to the
/ml/output/{channel_name}/path in the training container.
Arguments
Configure the following hyperparameter settings:
Parameter Name: The name of the parameter. Refer to the UI for naming requirements.
Type: The supported types are Int, Float, String, and Bool.
Constraint: After selecting a type other than Bool (Int, Float, or String), click Constraints in the Default Value column to configure parameter constraints. The constraint types are as follows:
Range: Specify a value range by setting a maximum and minimum value.
Enumeration: Define a list of enumerated values for the parameter.
Training constraints
Training constraints define the computing resources for a training job. You can turn on the Enable Training Constraints switch to configure them.
These constraints limit the options available in the Execution Tuning panel when you use this component in a pipeline, such as Instance Type, Specification, Number of Instances, and Max Running Time (sec).
The following table describes the parameters.
Parameter
Description
Machine Type
Specify whether the custom component runs on CPU or GPU instances.
Support Multi-machine
Determines whether the component supports distributed execution on multiple machines:
Supported: When the component runs, you can configure the number of nodes.
Not Supported: When the component runs, the number of nodes is fixed at 1 and cannot be changed.
Support Multi-GPU
This parameter is available only when you select GPU for Machine Type.
Determines whether the custom component supports multiple GPUs:
Supported: You can select either single-GPU or multi-GPU instances for the instance type.
Not Supported: You can only select single-GPU instances for the instance type.
Click Submit.
The newly created custom component appears on the component list page.
After the component is created, you can use it in Designer. For more information, see Use a Custom Component.
Appendix 1: Job types
TensorFlow (TFJob)
If your custom component's job type is TensorFlow (TFJob), the job's node topology information is injected through the TF_CONFIG environment variable. The following example shows the format of the environment variable's value:
{
"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
}
}The key parameters are described as follows:
Parameter | Description |
cluster | A description of the TensorFlow cluster. This is a map type:
|
task |
|
PyTorch (PyTorchJob)
If your custom component's job type is PyTorch (PyTorchJob), the following environment variables are injected:
RANK: A value of 0 indicates that the current node is the master node. A non-zero value indicates a worker node.
WORLD_SIZE: The total number of machines in the job.
MASTER_ADDR: The address of the master node.
MASTER_PORT: The port of the master node.
XGBoost (XGBoostJob)
If your custom component's job type is XGBoost (XGBoostJob), the following environment variables are injected:
RANK: A value of 0 indicates that the current node is the master node. A non-zero value indicates a worker node.
WORLD_SIZE: The total number of machines in the job.
MASTER_ADDR: The address of the master node.
MASTER_PORT: The port of the master node.
WORKER_ADDRS: The addresses of the worker nodes, sorted by RANK.
WORKER_PORT: The port of the worker nodes.
The following are examples:
Distributed job (more than one node)
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=9999Single-node job
NoteIf there is only one node, it acts as the master node. In this case, the WORKER_ADDRS and WORKER_PORT environment variables are not injected.
WORLD_SIZE=1 MASTER_PORT=9999 MASTER_ADDR=train1pt84cj****-master-0 RANK=0
ElasticBatch (ElasticBatchJob)
ElasticBatch is a job type designed for distributed, elastic, and offline batch inference. ElasticBatch jobs have the following features:
Easy parallelism for increased throughput.
Significantly reduced job waiting time. A job can start as soon as some worker nodes have resources.
Automatically detects slow machines and starts backup workers to replace them, preventing long-tail latency or job hangs.
Globally and dynamically distributes data shards, allowing faster nodes to process more data.
Supports early stopping. After all data is processed, unstarted workers are not launched, which prevents an increase in the job's total runtime.
Provides fault tolerance. If a single worker fails, it is automatically restarted.
An ElasticBatch job consists of two types of nodes: AIMaster and Worker.
AIMaster: Responsible for the global management of the job, including dynamic distribution of data shards, monitoring the data throughput of each worker, and fault tolerance.
Worker: A worker node retrieves a data shard from the AIMaster, processes the data, writes back the results, and then retrieves the next shard. This dynamic process allows faster nodes to process more data and slower nodes to process less.
When an ElasticBatch job starts, it launches an AIMaster node and worker nodes. Your code runs on the worker nodes. The ELASTICBATCH_CONFIG environment variable is injected into the worker nodes. The following is an example of its value format:
{
"task": {
"type": "worker",
"index": 0
},
"environment": "cloud"
}The parameters are described as follows:
task.type: Indicates the task type of the current node.
task.index: The index of the current node within the list of network addresses for its role.
Appendix 2: How custom components work
Read pipeline and hyperparameter data
Read input pipeline data
The path for each input pipeline is injected into the job's container through the PAI_INPUT_{CHANNEL_NAME} environment variable.
For example, if a custom component has two input pipelines, train and test, with the values oss://<YourOssBucket>.<OssEndpoint>/path-to-data/ and oss://<YourOssBucket>.<OssEndpoint>/path-to-data/test.csv respectively, the injected environment variables are as follows:
PAI_INPUT_TRAIN=/ml/input/data/train/
PAI_INPUT_TEST=/ml/input/data/test/test.csvRead output pipeline data
A component retrieves the output pipeline path from the PAI_OUTPUT_{CHANNEL_NAME} environment variable.
For example, if a custom component has two output pipelines named model and checkpoints, the following environment variables are injected:
PAI_OUTPUT_MODEL=/ml/output/model/
PAI_OUTPUT_CHECKPOINTS=/ml/output/checkpoints/Read hyperparameter data
You can read hyperparameter data by using the following environment variables:
PAI_USER_ARGS
When the component runs, all hyperparameters for the job are injected into the training job's container as the PAI_USER_ARGS environment variable, using the format
--{hyperparameter_name} {hyperparameter_value}.For example, if a training job specifies the hyperparameters
{"epochs": 10, "batch-size": 32, "learning-rate": 0.001}, the value of the PAI_USER_ARGS environment variable is:PAI_USER_ARGS="--epochs 10 --batch-size 32 --learning-rate 0.001"PAI_HPS_{HYPERPARAMETER_NAME}
The value of each hyperparameter is also injected into the job's container as a separate environment variable. In the hyperparameter name, any characters that are not supported by environment variables (which only allow letters, numbers, and underscores) are replaced with underscores.
For example, if a training job specifies the hyperparameters
{"epochs": 10, "batch-size": 32, "train.learning_rate": 0.001}, the corresponding environment variables are as follows:PAI_HPS_EPOCHS=10 PAI_HPS_BATCH_SIZE=32 PAI_HPS_TRAIN_LEARNING_RATE=0.001PAI_HPS
All hyperparameters are injected into the job's container as the PAI_HPS environment variable in JSON format.
For example, if a training job passes the hyperparameters
{"epochs": 10, "batch-size": 32}, the value of the PAI_HPS environment variable is:PAI_HPS={"epochs": 10, "batch-size": 32}
Input and output directory structure
In your execution code, besides using environment variables, you can also access input and output pipelines directly through their mount paths. When a component's task runs in a container, the system creates the following directory structure:
Code path:
/ml/usercode/.Hyperparameter configuration file:
/ml/input/config/hyperparameters.json.The complete configuration file for the training job is
/ml/input/config/training_job.json.The directory path of the input pipeline:
/ml/input/data/{channel_name}/.Output pipeline directory path:
/ml/output/{channel_name}/.
The following is a complete example of the input and output directory structure for a job executed by a custom component:
/ml
|-- usercode # User code is loaded into the /ml/usercode directory. This is also the working directory for the user code. You can get this path from the PAI_WORKING_DIR environment variable.
| |-- requirements.txt
| |-- main.py
|-- input # Job input data and configuration.
| |-- config # The config directory contains the job's configuration information. You can get this path from the PAI_CONFIG_DIR environment variable.
| |-- training_job.json # The complete job configuration.
| |-- hyperparameters.json # Hyperparameters for the training job.
| |-- data # Job InputChannels: The following directory contains two channels: train_data and test_data.
| |-- test_data
| | |-- test.csv
| |-- train_data
| |-- train.csv
|-- output # Job OutputChannels: This example has two output channels: model and checkpoints.
|-- model # The output path can be retrieved from the PAI_OUTPUT_{OUTPUT_CHANNEL_NAME} environment variable.
|-- checkpointsDetermine the number of GPUs
After a task starts, you can use the environment variable NVIDIA_VISIBLE_DEVICES to determine whether the current machine has GPUs and the number of GPU cards. For example, NVIDIA_VISIBLE_DEVICES=0,1,2,3 indicates that the current machine has 4 GPU cards.