Skip to content

Image URI in CreateModelStep can not be a Sagemaker Properties object. #3103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BasHuijben opened this issue May 12, 2022 · 2 comments
Closed
Labels
component: pipelines Relates to the SageMaker Pipeline Platform type: bug

Comments

@BasHuijben
Copy link

BasHuijben commented May 12, 2022

Describe the bug
When deploying a model, we create a pipeline consisting of three steps:

  1. Get latest model version (LambdaStep). Depending on the environment we are in, we select different models from the model registry. For instance in dev we select the latest registered model, but in prod we select the latest approved model.
  2. Create model (CreteModelStep).
  3. Deploy model (LambdaStep).

We create a new model with the following code (step 2):

model = Model(name=model_package_name,
              image_uri=step_latest_model_version.properties.Outputs["model_image"],
              model_data=step_latest_model_version.properties.Outputs["model_artifact"],
              sagemaker_session=sagemaker_session,
              role=CONFIG['role'])
step_create_model = CreateModelStep(name='Create-model',
                                    model=model,
                                    inputs=None,
                                    display_name=model_package_name,
                                    depends_on=[step_latest_model_version])

This was working fine in version 2.72.2 but in versions 2.82.2 and 2.89.0 (did not test more versions) it is giving the following error when we upsert the pipeline:

Traceback (most recent call last):
  File ".../sagemaker_bug.py", line 45, in <module>
    response = pipeline.upsert(role_arn=...,
  File "...\lib\site-packages\sagemaker\workflow\pipeline.py", line 219, in upsert
    response = self.create(role_arn, description, tags, parallelism_config)
  File "...\lib\site-packages\sagemaker\workflow\pipeline.py", line 116, in create
    kwargs = self._create_args(role_arn, description, parallelism_config)
  File "...\lib\site-packages\sagemaker\workflow\pipeline.py", line 138, in _create_args
    pipeline_definition = self.definition()
  File "...\lib\site-packages\sagemaker\workflow\pipeline.py", line 301, in definition
    request_dict = self.to_request()
  File "...\lib\site-packages\sagemaker\workflow\pipeline.py", line 91, in to_request
    "Steps": list_to_request(self.steps),
  File "...\lib\site-packages\sagemaker\workflow\utilities.py", line 42, in list_to_request
    request_dicts.append(entity.to_request())
  File "...\lib\site-packages\sagemaker\workflow\steps.py", line 213, in to_request
    step_dict = super().to_request()
  File "...\lib\site-packages\sagemaker\workflow\steps.py", line 102, in to_request
    "Arguments": self.arguments,
  File "...\lib\site-packages\sagemaker\workflow\steps.py", line 435, in arguments
    container_defs=self.model.prepare_container_def(
  File "...\lib\site-packages\sagemaker\model.py", line 414, in prepare_container_def
    deploy_key_prefix = fw_utils.model_code_key_prefix(
  File "...\lib\site-packages\sagemaker\fw_utils.py", line 398, in model_code_key_prefix
    training_job_name = sagemaker.utils.name_from_image(image)
  File "...\lib\site-packages\sagemaker\utils.py", line 60, in name_from_image
    return name_from_base(base_name_from_image(image), max_length=max_length)
  File "...\lib\site-packages\sagemaker\utils.py", line 102, in base_name_from_image
    m = re.match("^(.+/)?([^:/]+)(:[^:]+)?$", image)
  File "...\lib\re.py", line 191, in match
    return _compile(pattern, flags).match(string)
TypeError: expected string or bytes-like object

The reason for this is that image is equal to a Sagemaker Properties object and not a string. This makes sense because we set image_uri to step_latest_model_version.properties.Outputs["model_image"].

Personally I think you should be able to provide a Properties object as image_uri when you would like to deploy a model from the model registry inside a Sagemaker pipeline, like in version 2.72.2.

To reproduce
I reproduced the error with the following code:

import boto3

import sagemaker
from sagemaker.lambda_helper import Lambda
from sagemaker.workflow.steps import CreateModelStep
from sagemaker.workflow.lambda_step import LambdaStep, LambdaOutput, LambdaOutputTypeEnum
from sagemaker import Model
from sagemaker.workflow.pipeline import Pipeline


region = sagemaker.Session().boto_region_name
sm_client = boto3.client("sagemaker")
boto_session = boto3.Session(region_name=region)
sagemaker_session = sagemaker.session.Session(boto_session=boto_session,
                                              sagemaker_client=sm_client)

lambda_func = Lambda(function_name='latest-model-package',
                     execution_role_arn=your_own_execution_role,
                     script='latest_model_package.py',
                     handler="latest_model_package.get_latest_model_package_lambda")


lambda_outputs = [LambdaOutput(output_name="image_uri", output_type=LambdaOutputTypeEnum.String),
                  LambdaOutput(output_name="model_artifact", output_type=LambdaOutputTypeEnum.String)]
step_latest_model_version = LambdaStep(name="Get-latest-model",
                                       lambda_func=lambda_func,
                                       inputs={},
                                       outputs=lambda_outputs)

model = Model(name='test',
              image_uri=step_latest_model_version.properties.Outputs["image_uri"],
              model_data=step_latest_model_version.properties.Outputs["model_artifact"],
              sagemaker_session=sagemaker_session,
              role=your_own_role')
step_create_model = CreateModelStep(name='Create-model',
                                    model=model,
                                    inputs=None,
                                    display_name='test',
                                    depends_on=[step_latest_model_version])

pipeline = Pipeline(name='test-pipeline',
                    steps=[step_latest_model_version, step_create_model])

# submit pipeline
response = pipeline.upsert(role_arn=your_own_role,
                           description='test pipeline')
latest_model_package.py
def get_latest_model_package_lambda(event, context):
    return {'image_uri': 'image_uri_of_model_package',
            'model_artifact': 'model_artifact_of_model_package'}

Expected behavior
The pipeline should work with a Sagemaker Property object as input for the image_uri parameter of the CreateModelStep class, like in version 2.72.2

Screenshots or logs
see error message above.

System information
A description of your system. Please provide:

  • SageMaker Python SDK version: 2.82.2 and 2.89.0
  • Framework name (eg. PyTorch) or algorithm (eg. KMeans): -
  • Framework version: -
  • Python version: 3.8
  • CPU or GPU: CPU
  • Custom Docker image (Y/N): N

Additional context

@jerrypeng7773 jerrypeng7773 added the component: pipelines Relates to the SageMaker Pipeline Platform label May 12, 2022
@navaj0
Copy link
Contributor

navaj0 commented May 12, 2022

This is the suspicious PR: #2870. It adds a bunch of new lines in the prepare_container_def method, which might have caused regression.

@jerrypeng7773
Copy link
Contributor

@BasHuijben we merged a PR to address this issue, closing this issue for now, feel free to re-open if you have any other concern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: pipelines Relates to the SageMaker Pipeline Platform type: bug
Projects
None yet
Development

No branches or pull requests

3 participants