Azure / Azure/azure-sdk-for-python

[azure-ml] Serverless Spark compute fails with missing Synapse cluster identifier

Open
#39,646 2 comments 0 reactions 1 assignee Claimed by @vivram View on GitHub
Client customer-reported dataprep Machine Learning needs-team-attention question Service Attention
Dominant language
Python
Stars
5.6k
Forks
3.4k
Avg merge
1d 21h
Merged PRs (30d)
193

Description

- **Package Name**: azure-ml
- **Package Version**: 2.34.0
- **Operating System**:
- **Python Version**: 3.12.8

**Describe the bug**
I am trying to execute Python script on serverless Spark compute on Azure Machine Learning.
I have attached a user assigned Managed Identity to the AML workspace, and am defining the Spark component accordingly.
I have submitted the pipeline, and Spark job using the CLI.
Soon after the component starts running, I get the following Native Error:
```
Traceback (most recent call last):
File "data_prep/data_prep.py", line 75, in
run()
File "data_prep/data_prep.py", line 57, in run
df = table.to_pandas_dataframe()
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/_loggerfactory.py", line 279, in wrapper
return func(*args, **kwargs)
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/mltable/mltable.py", line 1311, in to_pandas_dataframe
raise e
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/mltable/mltable.py", line 1308, in to_pandas_dataframe
raise _reclassify_rslex_error(e)
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/mltable/_validation_and_error_handler.py", line 90, in _reclassify_rslex_error
raise err
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/mltable/mltable.py", line 1300, in to_pandas_dataframe
return get_dataframe_reader().to_pandas_dataframe(self._dataflow)
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/_dataframereader.py", line 355, in to_pandas_dataframe
return _execute(
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/_dataframereader.py", line 266, in _execute
raise e
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/_dataframereader.py", line 246, in _execute
return rslex_execute()
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/_dataframereader.py", line 177, in rslex_execute
(batches, num_partitions, stream_columns) = executor.execute_dataflow(dataflow,
File "/home/trusted-service-user/cluster-env/env/lib/python3.10/site-packages/azureml/dataprep/api/_rslex_executor.py", line 26, in execute_dataflow
(batches, num_partitions, stream_columns) = Executor().execute_dataflow(script,
azureml.dataprep.api.errorhandlers.ExecutionError:
Error Code: ScriptExecution.StreamAccess.Unexpected
Native Error: Dataflow visit error: ExecutionError(StreamError(Unknown("An unexpected error occurred while resolving AccessToken: Missing env var: 'AZUREML_SYNAPSE_CLUSTER_IDENTIFIER'", None)))
VisitError(ExecutionError(StreamError(Unknown("An unexpected error occurred while resolving AccessToken: Missing env var: 'AZUREML_SYNAPSE_CLUSTER_IDENTIFIER'", None))))
=> Failed with execution error: error in streaming from input data sources
ExecutionError(StreamError(Unknown("An unexpected error occurred while resolving AccessToken: Missing env var: 'AZUREML_SYNAPSE_CLUSTER_IDENTIFIER'", None)))
Error Message: Got unexpected error: An unexpected error occurred while resolving AccessToken: Missing env var: 'AZUREML_SYNAPSE_CLUSTER_IDENTIFIER'. | session_id=xxxxxxx

Exiting content uploader.
```
I haven't seen any mention to setting up the environment variable AZUREML_SYNAPSE_CLUSTER_IDENTIFIER for the Spark component.
The managed identity has AI Developer role assigned.

**To Reproduce**
Steps to reproduce the behavior:
1. Create a datastore with parquet files as input for the Spark component.
2. Define Spark component:
```
$schema: http://azureml/sdk-2-0/SparkComponent.json
type: spark

name: model
display_name: Data preparation for model
description: Read an input data, preprocess the input and split it to train and test
version: 0.0.0
is_deterministic: true

code: ../../src/components
entry:
file: data_prep/data_prep.py

inputs:
data:
type: uri_folder
mode: direct
test_train_ratio:
type: number

outputs:
train_data:
type: mltable
mode: direct
test_data:
type: mltable
mode: direct

identity:
type: managed
resources:
instance_type: "Standard_E4S_V3"
runtime_version: "3.4.0"

conf:
spark.driver.cores: 1
spark.driver.memory: 2g
spark.executor.cores: 2
spark.executor.memory: 2g
spark.executor.instances: 1
spark.dynamicAllocation.enabled: True
spark.dynamicAllocation.minExecutors: 1
spark.dynamicAllocation.maxExecutors: 4
spark.hadoop.aml.enable_cache: True
spark.aml.internal.system.job: True
spark.synapse.library.python.env: |
channels:
- defaults
dependencies:
- python=3.10
- pip:
- scipy~=1.10.0
- mltable~=1.6.1
- azureml-fsspec
- fsspec~=2023.4.0

name: momo-base-spark

args: >-
--data ${{inputs.data}}
--test_train_ratio ${{inputs.test_train_ratio}}
--train_data ${{outputs.train_data}}
--test_data ${{outputs.test_data}}
```
4. Define spark component script:
```
import argparse
import pandas as pd
import mltable
from sklearn.model_selection import train_test_split
import argparse
from shared_utilities.constants import PORT_APPLICATION_MAP, APPS_OF_INTEREST
from shared_utilities.utils import init_spark, save_spark_df_as_mltable

def run():
# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument("--data", type=str, help="input path to data")
parser.add_argument("--test_train_ratio", type=float, default=0.2, required=False, help="test train ratio")
parser.add_argument("--train_data", type=str, help="output path to train data")
parser.add_argument("--test_data", type=str, help="output path to test data")
args = parser.parse_args()

# Load the data
# df = pd.read_parquet(args.data)
paths = [
{"pattern": f"{args.data}processDate=*/*.parquet"},
]
table = mltable.from_parquet_files(paths=paths)
print('Paths: ', paths)
partition_format = "processDate={PartitionDate:yyyy-MM-dd}/*.parquet"
table = table.extract_columns_from_partition_format(partition_format)
print('Table: ', table)
df = table.to_pandas_dataframe() ## <- Pipeline fails here
```
5. Define AML pipeline:
```
$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline

experiment_name: model-training
display_name: model-training
description: ML model training pipeline

settings:
default_compute: azureml:serverless

inputs:
pipeline_job_input_data:
type: uri_folder
path: XXXXXXX
mode: direct
pipeline_job_test_train_ratio: 0.2
pipeline_job_n_estimators: 400
pipeline_job_max_depth: 40
pipeline_job_min_samples_split: 10
pipeline_job_random_state: 42
pipeline_job_registered_model_name: 'network_traffic_tagging_model'

jobs:
data_prep_job:
type: spark
component: ../components/data_prep.yml
identity:
type: managed
resources:
instance_type: "Standard_E4S_V3"
runtime_version: "3.4.0"
inputs:
data: ${{parent.inputs.pipeline_job_input_data}}
test_train_ratio: ${{parent.inputs.pipeline_job_test_train_ratio}}
outputs:
train_data:
type: mltable
mode: direct
test_data:
type: mltable
mode: direct
```

**Expected behavior**
I expected the component to run its code using a managed identity.

I am not sure why the component is failing. I assumed that when using Spark Serverless compute, there would be no need to specify a Synapse cluster manually.
Any thoughts or help will be deeply appreciated.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.