Skip to content

Commit 183ee8b

Browse files
authored
[ML][Pipelines] Feature: support serverless compute in pipeline job (Azure#28310)
* add serverless in const and update validate logic * update error message (remove suffix sign) * WIP: add test cases * fix missing import which is used in fixture * update test cases YAMLs * update error message and corresponding test
1 parent eb3b485 commit 183ee8b

File tree

11 files changed

+218
-3
lines changed

11 files changed

+218
-3
lines changed

sdk/ml/azure-ai-ml/azure/ai/ml/_schema/core/fields.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
FILE_PREFIX,
4848
INTERNAL_REGISTRY_URI_FORMAT,
4949
LOCAL_COMPUTE_TARGET,
50+
SERVERLESS_COMPUTE,
5051
LOCAL_PATH,
5152
REGISTRY_URI_FORMAT,
5253
RESOURCE_ID_FORMAT,
@@ -685,7 +686,7 @@ def ComputeField(**kwargs):
685686
"""
686687
return UnionField(
687688
[
688-
StringTransformedEnum(allowed_values=[LOCAL_COMPUTE_TARGET]),
689+
StringTransformedEnum(allowed_values=[LOCAL_COMPUTE_TARGET, SERVERLESS_COMPUTE]),
689690
ArmStr(azureml_type=AzureMLResourceType.COMPUTE),
690691
# Case for virtual clusters
691692
fields.Str(),

sdk/ml/azure-ai-ml/azure/ai/ml/constants/_common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
MAX_LIST_CLI_RESULTS = 50
6868
LOCAL_COMPUTE_TARGET = "local"
6969
LOCAL_COMPUTE_PROPERTY = "IsLocal"
70+
SERVERLESS_COMPUTE = "serverless"
7071
CONDA_FILE = "conda_file"
7172
DOCKER_FILE_NAME = "Dockerfile"
7273
COMPUTE_UPDATE_ERROR = (

sdk/ml/azure-ai-ml/tests/pipeline_job/_util.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,25 @@
5656
lambda params: Path(params[0]).name,
5757
DATABINDING_EXPRESSION_TEST_CASES,
5858
)))
59+
60+
61+
SERVERLESS_COMPUTE_TEST_PARAMETERS = [
62+
# test matrix: <pipeline-default-compute> + <step-compute>
63+
(
64+
"none_pipeline_default_compute_invalid",
65+
{
66+
"jobs.vanilla_node.compute": "Compute not set",
67+
"jobs.node_with_resources.compute": "Compute not set",
68+
"jobs.pipeline_node.jobs.vanilla_node.compute": "Compute not set",
69+
"jobs.pipeline_node.jobs.node_with_resources.compute": "Compute not set",
70+
},
71+
), # invalid: none + none / none + resources
72+
(
73+
"none_pipeline_default_compute_valid",
74+
None,
75+
), # valid: none + resources / none + serverless / none + compute target
76+
(
77+
"serverless_pipeline_default_compute_valid",
78+
None,
79+
), # valid serverless + <step-compute> (any combination should be valid)
80+
]

sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_validate.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import json
22
import re
3+
from contextlib import contextmanager
34
from pathlib import Path
5+
from typing import List, Optional
46
from unittest.mock import patch
57

68
import pytest
79
from marshmallow import ValidationError
810
from pytest_mock import MockFixture
911

1012
from azure.ai.ml import Input, MLClient, dsl, load_component, load_job
11-
from azure.ai.ml.constants._common import AssetTypes, InputOutputModes
13+
from azure.ai.ml.constants._common import AssetTypes, InputOutputModes, SERVERLESS_COMPUTE
1214
from azure.ai.ml.entities import Choice, CommandComponent, PipelineJob
1315
from azure.ai.ml.entities._validate_funcs import validate_job
1416
from azure.ai.ml.exceptions import ValidationException, UserErrorException
1517

16-
from .._util import _PIPELINE_JOB_TIMEOUT_SECOND
18+
from .._util import _PIPELINE_JOB_TIMEOUT_SECOND, SERVERLESS_COMPUTE_TEST_PARAMETERS
1719

1820

1921
def assert_the_same_path(actual_path, expected_path):
@@ -269,6 +271,19 @@ def test_register_output_without_name_yaml(self, pipeline_output_path, error_mes
269271
pipeline = load_job(source=pipeline_output_path)
270272
assert error_message in str(e.value)
271273

274+
@pytest.mark.parametrize("test_case,expected_error_message", SERVERLESS_COMPUTE_TEST_PARAMETERS)
275+
def test_pipeline_job_with_serverless_compute(
276+
self, test_case: str, expected_error_message: Optional[List[str]]
277+
) -> None:
278+
yaml_path = f"./tests/test_configs/pipeline_jobs/serverless_compute/{test_case}/pipeline.yml"
279+
pipeline_job = load_job(yaml_path)
280+
validation_result = pipeline_job._validate()
281+
if expected_error_message is None:
282+
assert validation_result.passed
283+
else:
284+
assert validation_result.error_messages == expected_error_message
285+
286+
272287
@pytest.mark.unittest
273288
@pytest.mark.pipeline_test
274289
class TestDSLPipelineJobValidate:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
$schema: https://azuremlschemas.azureedge.net/latest/commandComponent.schema.json
2+
type: command
3+
4+
name: simple_command_component
5+
6+
environment:
7+
image: python
8+
9+
command: >-
10+
echo Hello World
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
2+
type: pipeline
3+
4+
display_name: Pipeline Job with Serverless Compute
5+
6+
jobs:
7+
# command component
8+
vanilla_node:
9+
type: command
10+
component: ../component.yml
11+
node_with_resources:
12+
type: command
13+
component: ../component.yml
14+
resources:
15+
instance_count: 2
16+
# pipeline component
17+
pipeline_node:
18+
type: pipeline
19+
component: ./pipeline_component.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
$schema: https://azuremlschemas.azureedge.net/development/pipelineComponent.schema.json
2+
type: pipeline
3+
4+
name: simple_pipeline_component
5+
6+
jobs:
7+
vanilla_node:
8+
type: command
9+
component: ../component.yml
10+
node_with_resources:
11+
type: command
12+
component: ../component.yml
13+
resources:
14+
instance_count: 2
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
2+
type: pipeline
3+
4+
display_name: Pipeline Job with Serverless Compute
5+
6+
jobs:
7+
# command component
8+
node_with_compute_target:
9+
type: command
10+
component: ../component.yml
11+
compute: azureml:cpu-cluster
12+
node_with_compute_target_and_resources:
13+
type: command
14+
component: ../component.yml
15+
compute: azureml:cpu-cluster
16+
resources:
17+
instance_count: 2
18+
serverless_node:
19+
type: command
20+
component: ../component.yml
21+
compute: azureml:serverless
22+
serverless_node_with_resources:
23+
type: command
24+
component: ../component.yml
25+
compute: azureml:serverless
26+
resources:
27+
instance_count: 2
28+
# pipeline component
29+
pipeline_node:
30+
type: pipeline
31+
component: ./pipeline_component.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
$schema: https://azuremlschemas.azureedge.net/development/pipelineComponent.schema.json
2+
type: pipeline
3+
4+
name: simple_pipeline_component
5+
6+
jobs:
7+
node_with_compute_target:
8+
type: command
9+
component: ../component.yml
10+
compute: azureml:cpu-cluster
11+
node_with_compute_target_and_resources:
12+
type: command
13+
component: ../component.yml
14+
compute: azureml:cpu-cluster
15+
resources:
16+
instance_count: 2
17+
serverless_node:
18+
type: command
19+
component: ../component.yml
20+
compute: azureml:serverless
21+
serverless_node_with_resources:
22+
type: command
23+
component: ../component.yml
24+
compute: azureml:serverless
25+
resources:
26+
instance_count: 2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
2+
type: pipeline
3+
4+
display_name: Pipeline Job with Serverless Compute
5+
6+
settings:
7+
default_compute: azureml:serverless
8+
9+
jobs:
10+
# command component
11+
vanilla_node:
12+
type: command
13+
component: ../component.yml
14+
node_with_resources:
15+
type: command
16+
component: ../component.yml
17+
resources:
18+
instance_count: 2
19+
node_with_compute_target:
20+
type: command
21+
component: ../component.yml
22+
compute: azureml:cpu-cluster
23+
node_with_compute_target_and_resources:
24+
type: command
25+
component: ../component.yml
26+
compute: azureml:cpu-cluster
27+
resources:
28+
instance_count: 2
29+
serverless_node:
30+
type: command
31+
component: ../component.yml
32+
compute: azureml:serverless
33+
serverless_node_with_resources:
34+
type: command
35+
component: ../component.yml
36+
compute: azureml:serverless
37+
resources:
38+
instance_count: 2
39+
# pipeline component
40+
pipeline_node:
41+
type: pipeline
42+
component: ./pipeline_component.yml

0 commit comments

Comments
 (0)