Skip to content

Commit 6cf52df

Browse files
committed
Add Pythonic SageMaker training and processing
Allow typed Flyte task functions to run directly inside single-node SageMaker Training and Processing jobs through rendered container entrypoints. Preserve Flyte outputs and error semantics, validate SageMaker runtime constraints, and document the ECR, IAM, S3, networking, and secret-management requirements. Signed-off-by: Rohit Sharma <rohitrsh@gmail.com>
1 parent 915dbcd commit 6cf52df

13 files changed

Lines changed: 1529 additions & 3 deletions

File tree

flytekit/extend/backend/utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ def is_terminal_phase(phase: TaskExecution.Phase) -> bool:
3737
"""
3838
Return true if the phase is terminal.
3939
"""
40-
return phase in [TaskExecution.SUCCEEDED, TaskExecution.ABORTED, TaskExecution.FAILED]
40+
return phase in [
41+
TaskExecution.SUCCEEDED,
42+
TaskExecution.ABORTED,
43+
TaskExecution.FAILED,
44+
TaskExecution.RETRYABLE_FAILED,
45+
]
4146

4247

4348
def get_connector_secret(secret_key: str) -> str:

plugins/flytekit-aws-sagemaker/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,86 @@ training `InputDataConfig` S3 URI) or after one for evaluation. The
220220
`SageMakerStopProcessingJobTask` / `SageMakerDescribeProcessingJobTask` helpers
221221
mirror their training-job counterparts.
222222

223+
## Pythonic Training and Processing
224+
225+
Training and Processing also support a Flyte-native mode for code that is more
226+
naturally expressed as a typed Python function than as a complete boto3 job
227+
request. Use `SageMakerProcessing` or `SageMakerTraining` as the `task_config`
228+
on a normal `@task`:
229+
230+
```python
231+
from flytekit import ImageSpec, task
232+
from flytekitplugins.awssagemaker_processing import SageMakerProcessing
233+
from flytekitplugins.awssagemaker_training import SageMakerTraining
234+
235+
ROLE = "arn:aws:iam::<account-id>:role/<sagemaker-execution-role>"
236+
REGION = "us-east-1"
237+
238+
# The registry must resolve to Amazon ECR. When base_image is omitted, Flytekit
239+
# supplies its version-compatible default image before building and pushing.
240+
image = ImageSpec(
241+
name="sagemaker-pythonic",
242+
registry="<account-id>.dkr.ecr.us-east-1.amazonaws.com",
243+
packages=["numpy"],
244+
)
245+
246+
247+
@task(
248+
task_config=SageMakerProcessing(
249+
execution_role_arn=ROLE,
250+
region=REGION,
251+
instance_type="ml.m5.large",
252+
),
253+
container_image=image,
254+
)
255+
def preprocess(values: list[float]) -> list[float]:
256+
mean = sum(values) / len(values)
257+
return [value - mean for value in values]
258+
259+
260+
@task(
261+
task_config=SageMakerTraining(
262+
execution_role_arn=ROLE,
263+
region=REGION,
264+
instance_type="ml.m5.xlarge",
265+
),
266+
container_image=image,
267+
)
268+
def train(values: list[float]) -> float:
269+
return sum(value * value for value in values)
270+
```
271+
272+
The connector puts Flyte's rendered container arguments into SageMaker's
273+
`ContainerEntrypoint`. Inside the SageMaker container, `pyflyte-execute` runs
274+
the function and writes its typed result to Flyte's `outputs.pb`. User failures
275+
are written to `error.pb`, preserve recoverable/non-recoverable semantics, and
276+
fail the SageMaker job.
277+
278+
Requirements and current constraints:
279+
280+
- `container_image` is required. An `ImageSpec` is the simplest option; a plain
281+
image URI must already contain a compatible Flytekit runtime and must be
282+
available through a SageMaker-supported ECR registry.
283+
- Pythonic jobs currently require `instance_count=1`. Running the same Flyte
284+
function on every SageMaker host would duplicate side effects and race on
285+
Flyte output files.
286+
- The connector identity needs the relevant SageMaker lifecycle permissions and
287+
`iam:PassRole`. The SageMaker execution role needs ECR pull, CloudWatch Logs,
288+
and read/write access to Flyte's S3 input, fast-registration, and output
289+
prefixes.
290+
- Kubernetes-mounted secrets and Flyte pod environment injection are not
291+
available inside SageMaker. Use the SageMaker execution role and an AWS secret
292+
service for runtime credentials. Do not place secrets in `environment`; task
293+
configuration and container environment values are serialized in the Flyte
294+
task template.
295+
- `SageMakerProcessing.network_config` accepts the boto3 `NetworkConfig` shape.
296+
`EnableNetworkIsolation=True` is not supported because the Flyte entrypoint
297+
must access S3. `SageMakerTraining.vpc_config` accepts the training-job
298+
`VpcConfig` shape.
299+
- Pythonic Training returns the function's typed Flyte output; it does not treat
300+
SageMaker's generated `model.tar.gz` as the task result. Set `output_s3_path`
301+
only when that SageMaker-side archive is also needed.
302+
223303
## Hyperparameter Tuning
224304

225305
`SageMakerHyperParameterTuningJobTask` runs `CreateHyperParameterTuningJob` and

0 commit comments

Comments
 (0)