All Products
Search
Document Center

Platform For AI:PAI DLC job — Distributed training

Last Updated:Sep 01, 2026

Manage DLC (Deep Learning Containers) distributed training jobs — submit, inspect, stop, stream logs, and more.

job submit

pai dlc job submit --name NAME --image IMAGE --command CMD [flags]

Parameter

Type

Default

Description

--name

string

Job name Required

--command

string

Command to run on each node Required

--image

string

Container image (applied to all roles that don't specify their own image)

--job-type

string

PyTorchJob

Framework type PyTorchJob TFJob MPIJob XGBoostJob ElasticBatchJob RayJob FlinkBatchJob DataJuicerJob

--workspace-id

string

config

Workspace ID

Pay-as-you-go (ECS instance type)

--worker-spec

string

Worker ECS instance type (e.g., ecs.gn6v-c8g1.2xlarge)

--worker-count

int

1

Number of worker replicas

Subscription (resource quota)

--resource-id

string

Resource quota or resource group ID

--cpu

string

Number of CPU cores (e.g., 8)

--memory

string

Memory size (e.g., 64Gi)

--gpu

string

Number of GPUs (e.g., 1)

--gpu-type

string

GPU model (e.g., A100)

--shared-memory

string

Shared memory size (e.g., 16Gi)

Multi-role topology (mutually exclusive with --worker-*)

--role

stringArray

Role definition in NAME:key=value,... format. Repeatable.

Valid NAME values: chief / evaluator / graphlearn / head / master / ps / worker. Keys: count / cpu / gpu / gpu-type / memory / shared-memory / spec / image / restart-policy / spot / spot-strategy / spot-price-limit / spot-discount-limit / oversold-type / chief

--role-json

stringArray

Role extension fields in NAME:{PascalCase JSON} format. Repeatable. Use for fields not covered by --role, such as SystemDisk and ExtraPodSpec.

Data and code

--data-source

stringArray

Data source configuration. Repeatable. Shorthand: id[:mount_path[:version]]; key-value: uri=oss://bucket/path/, mount-path=/mnt/data, enable-cache=true

--code-source

string

Code source ID

--code-branch

string

Code branch (requires --code-source)

--code-commit

string

Code commit hash (requires --code-source)

--code-mount-path

string

Mount path for code

--thirdparty-lib

stringArray

Pre-installed Python packages (e.g., numpy==1.26.4). Repeatable.

--thirdparty-lib-dir

string

Directory containing requirements.txt

Scheduling and run control

--priority

int32

0

Scheduling priority, 1–9 (0 uses the server-side default)

--scheduling-strategy

string

Scheduling strategy IntelligentScheduling CentralizedScheduling DistributedScheduling

--success-policy

string

Distributed success policy ChiefWorker AllWorkers

--max-running-time-minutes

int

0

Maximum running time in minutes (0 = unlimited)

--allow-nodes

string

Allowed scheduling nodes (comma-separated node names)

--deny-nodes

string

Excluded nodes (comma-separated node names)

--env

stringArray

Environment variables in KEY=VALUE format. Repeatable.

--accessibility

string

Visibility PRIVATE PUBLIC

--description

string

Job description

--image-username

string

Username for private image registry

--image-password

string

Password for private image registry

--credential-config

string

Credential configuration JSON

--elastic-spec

string

Elastic scaling configuration JSON

--settings

string

Advanced job settings JSON

--user-vpc

string

VPC network configuration JSON

Wait and debug

--wait

bool

false

Block after submit until the job reaches a terminal state

--wait-for

string

Succeeded

Target status for --wait

--wait-interval

int

10

Polling interval in seconds

--wait-timeout

int

3600

Maximum wait time in seconds

--dry-run

bool

false

Print the request body without submitting

--generate-skeleton

bool

false

Print a request template and exit. Defaults to JSON; add -o yaml for a YAML template with per-field comments that map to CLI flags. Both formats are accepted by --body-json.

--body-json

string

Full CreateJob request body (PascalCase field names). Accepts inline JSON, @job.json / @job.yaml to read from file, and @- to read from stdin. Scalar flags (--name, --command, etc.) override matching fields; topology and list flags (--role, --worker-*, --env, --data-source, etc.) are mutually exclusive with this flag.

--from-file

string

Read the job from a YAML or JSON file. Field names correspond to CLI flags without leading dashes (name, command, worker-count…). CLI flags override file values, which is useful for saving a job template and tweaking one field per run. Use - for stdin. Mutually exclusive with --body-json.

--batch

string

Batch-submit all job files (.json/.yaml/*.yml, same format as --from-file, one job per file) in a directory. All files are validated before submission. Requires --yes, or preview first with --dry-run. Already-created jobs aren't rolled back on failure (their IDs are printed to stdout).

--override / --override-string / --override-unset

stringArray

Modify request body fields before submission. See --override request body editing

Common examples

# 1. Pay-as-you-go: single-role Worker training (simplest form)
pai dlc job submit \
  --name ddp-demo \
  --image pytorch:2.0.1-gpu-py310-cu118-ubuntu20.04 \
  --command "torchrun --nproc_per_node=8 train.py" \
  --worker-spec ecs.gn6v-c8g1.8xlarge \
  --worker-count 4

# 2. Subscription: use resource quota (cpu/gpu/memory instead of spec)
pai dlc job submit \
  --name ddp-prepaid \
  --image pytorch:2.0.1-gpu-py310-cu118-ubuntu20.04 \
  --command "torchrun --nproc_per_node=8 train.py" \
  --resource-id quota-a1b2c3d4e5f6 \
  --worker-count 4 \
  --cpu 8 --memory 64Gi --gpu 1 --gpu-type A100

# 3. Multi-role topology: different specs per role (--role is mutually exclusive with --worker-*)
pai dlc job submit \
  --name tf-ps-demo \
  --job-type TFJob \
  --command "python train.py" \
  --role chief:count=1,spec=ecs.gn6v-c8g1.8xlarge \
  --role worker:count=4,spec=ecs.gn6v-c8g1.8xlarge \
  --role ps:count=2,spec=ecs.g7.16xlarge \
  --success-policy ChiefWorker

# 4. Data source: two syntaxes (shorthand vs key-value)
#    Shorthand: registered dataset ID + mount path
pai dlc job submit --name ds-demo --image pytorch:2.1 \
  --command "python train.py" --worker-spec ecs.g7.xlarge \
  --data-source d-abc123:/mnt/data
#    Key-value: specify OSS path directly (no pre-registered dataset needed)
pai dlc job submit --name ds-demo --image pytorch:2.1 \
  --command "python train.py" --worker-spec ecs.g7.xlarge \
  --data-source uri=oss://my-bucket/path/,mount-path=/mnt/data

# 5. --dry-run: preview the request body without submitting
pai dlc job submit --name test --image pytorch:2.1 \
  --command "python train.py" --worker-spec ecs.g7.xlarge --dry-run

# 6. --generate-skeleton + --body-json advanced workflow
#    Step 1: Generate a YAML template with per-field comments
pai dlc job submit --generate-skeleton -o yaml > job.yaml
#    Step 2: Edit job.yaml — remove unneeded fields, fill in values
#    Step 3: Submit with --body-json (accepts both JSON and YAML)
pai dlc job submit --body-json @job.yaml

# 7. --from-file job template workflow (field names = flag names, more intuitive than --body-json)
cat > job.yaml << 'EOF'
name: bert-pretrain
image: pytorch:2.1
command: torchrun train.py
worker-spec: ecs.gn6v-c8g1.8xlarge
worker-count: 4
EOF
pai dlc job submit --from-file job.yaml
#    Override file fields with CLI flags: reuse the same template with a different name
pai dlc job submit --from-file job.yaml --name bert-pretrain-lr001

# 8. --batch: batch-submit job files from a directory
pai dlc job submit --batch jobs/ --dry-run   # Preview first
pai dlc job submit --batch jobs/ --yes       # Actually submit
Note

The --generate-skeleton -o yaml output includes a comment on every field that explains its purpose and the corresponding CLI flag. Use it to configure advanced fields that the CLI doesn't expose directly. For day-to-day use, prefer CLI flags or --from-file; reach for --body-json only when you need API-level field names.

job list

pai dlc job list [flags]

Parameter

Type

Default

Description

--workspace-id

string

config

Workspace ID

--all-workspaces

bool

false

Query across all accessible workspaces

--status

string

Filter by status (Running / Succeeded / Failed, etc.)

--display-name

string

Filter by job name

--job-type

string

Filter by framework type (PyTorchJob / TFJob, etc.)

--show-own

bool

false

Show only jobs submitted by the current user

--since

string

7d

Time window (e.g., 7d, 48h, 365d). Jobs outside this window aren't returned

--sort-by

string

Sort field (e.g., GmtCreateTime)

--order

string

Sort direction asc desc

--page

int

1

Page number

--page-size

int

20

Items per page

--columns

string

Custom output columns. Default: job_id, display_name, job_type, status, gmt_create_time, duration

job get

pai dlc job get <job-id> [--brief]

Parameter

Type

Default

Description

--brief

bool

false

Compact output — omit Pods / Specs / History details

job stop / delete

pai dlc job stop <job-id> [-y] [--dry-run]
pai dlc job delete <job-id> [-y] [--dry-run]

Parameter

Type

Default

Description

-y, --yes

bool

false

Skip the confirmation prompt

--dry-run

bool

false

Preview the operation without executing it

Warning

Stopped jobs can't be recovered. In-progress training data is lost.

job logs

pai dlc job logs <job-id> [--pod <pod-id>] [flags]

When --pod isn't specified, the command automatically selects the job's primary pod (master, chief, driver, etc.). The selection is printed to stderr so that stdout stays clean. If the primary pod can't be determined, the command lists all pods for you to choose from instead of guessing.

Parameter

Type

Default

Description

--pod

string

Auto-select primary pod

Pod ID. Omit to read from the job's primary pod

--pod-uid

string

Pod UID, used to distinguish same-named pods after a restart

--all-pods

bool

false

Read all pods at once, prefixing each log line with its source pod. --tail applies per-pod — use a small value for multi-node jobs. Mutually exclusive with --pod and --follow

--follow

bool

false

Stream logs continuously (poll until interrupted)

--since

string

7 days ago

Show only logs after the specified time (e.g., 30m, 2h, 3d). For jobs that ended more than 7 days ago, widen this value explicitly to avoid InvalidTimeRange errors

--tail

int

2000

Show only the last N lines (counted from newest)

job events

pai dlc job events <job-id> [--pod <pod-id>] [flags]

Read system events for a DLC job or one of its pods. Events record scheduling and lifecycle information that the training output doesn't cover: why a pod is still Pending, what killed it, or when it was restarted. They answer questions that job logs can't — a pod that never started has no logs, but it does have events.

Parameter

Type

Default

Description

--pod

string

Read events for this pod (uses a different API). Omit to read the job's own events

--all-pods

bool

false

Read events for all pods at once, prefixing each line with its source pod. --max applies per-pod — use a small value for multi-node jobs

--pod-uid

string

Pod UID, used to distinguish same-named pods after a restart (requires --pod)

--max

int

2000

Maximum number of events to return (API MaxEventsNum)

--since

string

7d

Show only events after the specified time (e.g., 30m, 2h, 3d). Widen this for long-running jobs

# See what the server did with the job
pai dlc job events dlc1abc2def3ghi

# Find out why a specific pod isn't Running
pai dlc job events dlc1abc2def3ghi --pod dlc1abc2def3ghi-master-0

# Read all pods at once, 50 events each
pai dlc job events dlc1abc2def3ghi --all-pods --max 50

# Widen the time window for long-running jobs
pai dlc job events dlc1abc2def3ghi --since 30d
Note

Recommended troubleshooting order: run job events first to see what happened at the scheduling layer (Pending reasons, OOMKilled, restart records), then run job logs to see what the training process itself output.

job exec

pai dlc job exec <job-id> [--pod <pod-id>] -- <command>...

Execute a command in a pod of a DLC job and print the output. A single quoted argument preserves shell syntax: pai dlc job exec <job-id> -- "nvidia-smi | head -20". Multiple tokens are re-quoted individually so that spaces are preserved, but shell syntax passed as separate tokens is forwarded literally.

Parameter

Type

Default

Description

--pod

string

Auto-select primary pod

Target Pod ID. Omit to auto-select using the same logic as job logs. The selection is printed to stderr; stdout carries the command's own output

--pod-uid

string

Pod UID, used to reject stale targets after a pod restart

--timeout

int

120

Execution timeout in seconds

Warning

Two limitations from the transport channel (the pod's Web Terminal, a single pseudo-terminal): ① stdout and stderr are merged into stdout (like a real terminal); the exit code is recovered by echoing it from the shell, so the image must contain a POSIX shell. ② Non-interactive: no input is sent — commands that prompt for input hang until --timeout.

job resubmit

pai dlc job resubmit <job-id> [flags]

Rebuild the submit request from an existing job and send it again. Useful for rerunning failed jobs or rerunning with tweaks. Scalar parameters (--command, --priority, --name, etc.) replace the corresponding fields. Topology and list parameters (--worker-count, --env, etc.) are rejected — use --export to export, edit, and resubmit instead.

Parameter

Type

Default

Description

--name

string

Original name

New job name, useful for associating it with the original

--command / --priority / --job-type and other scalar parameters

Original values

Replace the corresponding fields before resubmitting

--export

bool

false

Print the rebuilt request body without submitting. Edit it, then submit with job submit --body-json @file

--dry-run

bool

false

Preview the rebuilt request body without sending

Warning

GetJob doesn't return all original fields (e.g., SuccessPolicy, JobMaxRunningTimeMinutes, some data source options). These fields aren't automatically restored — re-specify them through flags when needed. Use --export first to check which fields were actually restored.

# Rerun as-is
pai dlc job resubmit dlc1abc2def3ghi

# Rerun with a new name and command
pai dlc job resubmit dlc1abc2def3ghi --name resnet50-v2 \
  --command "torchrun --nproc_per_node=8 train.py --batch-size 512"

# Export to a file, edit, then resubmit
pai dlc job resubmit dlc1abc2def3ghi --export -o yaml > job.yaml
pai dlc job submit --body-json @job.yaml

job wait

pai dlc job wait <job-id> [--for Succeeded]

Parameter

Type

Default

Description

--for

string

Succeeded

Target status Creating Queuing Dequeued Running Succeeded Failed Stopped Stopping Restarting WaitingConfig Deleted

--interval

int

10

Polling interval in seconds

--timeout

int

3600

Maximum wait time in seconds

The wait also ends immediately when the job reaches any other terminal state (Succeeded, Failed, or Stopped).