Exemple #1
0
def test_sparkml_model_deploy(sagemaker_session, cpu_instance_type):
    # Uploads an MLeap serialized MLeap model to S3 and use that to deploy a SparkML model to perform inference
    data_path = os.path.join(DATA_DIR, "sparkml_model")
    endpoint_name = "test-sparkml-deploy-{}".format(sagemaker_timestamp())
    model_data = sagemaker_session.upload_data(
        path=os.path.join(data_path, "mleap_model.tar.gz"),
        key_prefix="integ-test-data/sparkml/model",
    )
    schema = json.dumps(
        {
            "input": [
                {"name": "Pclass", "type": "float"},
                {"name": "Embarked", "type": "string"},
                {"name": "Age", "type": "float"},
                {"name": "Fare", "type": "float"},
                {"name": "SibSp", "type": "float"},
                {"name": "Sex", "type": "string"},
            ],
            "output": {"name": "features", "struct": "vector", "type": "double"},
        }
    )
    with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
        model = SparkMLModel(
            model_data=model_data,
            role="SageMakerRole",
            sagemaker_session=sagemaker_session,
            env={"SAGEMAKER_SPARKML_SCHEMA": schema},
        )
        predictor = model.deploy(1, cpu_instance_type, endpoint_name=endpoint_name)

        valid_data = "1.0,C,38.0,71.5,1.0,female"
        assert predictor.predict(valid_data) == "1.0,0.0,38.0,1.0,71.5,0.0,1.0"

        invalid_data = "1.0,28.0,C,38.0,71.5,1.0"
        assert predictor.predict(invalid_data) is None
Exemple #2
0
def test_inference_pipeline_batch_transform(sagemaker_session):
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(SPARKML_DATA_PATH, 'mleap_model.tar.gz'),
        key_prefix='integ-test-data/sparkml/model')
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(XGBOOST_DATA_PATH, 'xgb_model.tar.gz'),
        key_prefix='integ-test-data/xgboost/model')
    batch_job_name = 'test-inference-pipeline-batch-{}'.format(
        sagemaker_timestamp())
    sparkml_model = SparkMLModel(model_data=sparkml_model_data,
                                 env={'SAGEMAKER_SPARKML_SCHEMA': SCHEMA},
                                 sagemaker_session=sagemaker_session)
    xgb_image = get_image_uri(sagemaker_session.boto_region_name, 'xgboost')
    xgb_model = Model(model_data=xgb_model_data,
                      image=xgb_image,
                      sagemaker_session=sagemaker_session)
    model = PipelineModel(models=[sparkml_model, xgb_model],
                          role='SageMakerRole',
                          sagemaker_session=sagemaker_session,
                          name=batch_job_name)
    transformer = model.transformer(1, 'ml.m4.xlarge')
    transform_input_key_prefix = 'integ-test-data/sparkml_xgboost/transform'
    transform_input = transformer.sagemaker_session.upload_data(
        path=VALID_DATA_PATH, key_prefix=transform_input_key_prefix)

    with timeout_and_delete_model_with_transformer(
            transformer,
            sagemaker_session,
            minutes=TRANSFORM_DEFAULT_TIMEOUT_MINUTES):
        transformer.transform(transform_input,
                              content_type=CONTENT_TYPE_CSV,
                              job_name=batch_job_name)
        transformer.wait()
Exemple #3
0
def test_inference_pipeline_model_deploy_with_update_endpoint(
    sagemaker_session, cpu_instance_type, alternative_cpu_instance_type
):
    sparkml_data_path = os.path.join(DATA_DIR, "sparkml_model")
    xgboost_data_path = os.path.join(DATA_DIR, "xgboost_model")
    endpoint_name = "test-inference-pipeline-deploy-{}".format(sagemaker_timestamp())
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(sparkml_data_path, "mleap_model.tar.gz"),
        key_prefix="integ-test-data/sparkml/model",
    )
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(xgboost_data_path, "xgb_model.tar.gz"),
        key_prefix="integ-test-data/xgboost/model",
    )

    with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
        sparkml_model = SparkMLModel(
            model_data=sparkml_model_data,
            env={"SAGEMAKER_SPARKML_SCHEMA": SCHEMA},
            sagemaker_session=sagemaker_session,
        )
        xgb_image = get_image_uri(sagemaker_session.boto_region_name, "xgboost")
        xgb_model = Model(
            model_data=xgb_model_data, image=xgb_image, sagemaker_session=sagemaker_session
        )
        model = PipelineModel(
            models=[sparkml_model, xgb_model],
            role="SageMakerRole",
            sagemaker_session=sagemaker_session,
        )
        model.deploy(1, alternative_cpu_instance_type, endpoint_name=endpoint_name)
        old_endpoint = sagemaker_session.sagemaker_client.describe_endpoint(
            EndpointName=endpoint_name
        )
        old_config_name = old_endpoint["EndpointConfigName"]

        model.deploy(1, cpu_instance_type, update_endpoint=True, endpoint_name=endpoint_name)

        # Wait for endpoint to finish updating
        # Endpoint update takes ~7min. 40 retries * 30s sleeps = 20min timeout
        for _ in retries(40, "Waiting for 'InService' endpoint status", seconds_to_sleep=30):
            new_endpoint = sagemaker_session.sagemaker_client.describe_endpoint(
                EndpointName=endpoint_name
            )
            if new_endpoint["EndpointStatus"] == "InService":
                break

        new_config_name = new_endpoint["EndpointConfigName"]
        new_config = sagemaker_session.sagemaker_client.describe_endpoint_config(
            EndpointConfigName=new_config_name
        )

        assert old_config_name != new_config_name
        assert new_config["ProductionVariants"][0]["InstanceType"] == cpu_instance_type
        assert new_config["ProductionVariants"][0]["InitialInstanceCount"] == 1

    model.delete_model()
    with pytest.raises(Exception) as exception:
        sagemaker_session.sagemaker_client.describe_model(ModelName=model.name)
        assert "Could not find model" in str(exception.value)
def lambda_handler(event, context):
    schema_json = get_schema_json()
    bucket = os.environ['bucket']
    # Get the execution ID
    sess = sagemaker.Session()
    obj = s3.Object(bucket, 'execution.txt')
    exec_id = obj.get()['Body'].read().decode("utf-8")
    role = os.environ['role']
    print(exec_id)
    # Build variables
    training_job = f'{exec_id}-job'
    mleap_model_prefix = f'sagemaker/spark-preprocess-demo/{exec_id}/mleap-model'
    # Create models for Pipeline
    xgb_model = sagemaker.estimator.Estimator.attach(
        training_job).create_model()
    sparkml_data = 's3://{}/{}/{}'.format(os.environ['bucket'],
                                          mleap_model_prefix, 'model.tar.gz')
    sparkml_model = SparkMLModel(model_data=sparkml_data,
                                 env={'SAGEMAKER_SPARKML_SCHEMA': schema_json})

    # Create Pipeline Model
    model_name = 'inference-pipeline-' + exec_id
    sm_model = PipelineModel(name=model_name,
                             role=role,
                             models=[sparkml_model, xgb_model])
    sm_model.transformer(1, 'ml.m4.xlarge')
    event['model_name'] = model_name
    event['timestamp_prefix'] = exec_id
    return event
def test_inference_pipeline_model_deploy_and_update_endpoint(
        sagemaker_session, cpu_instance_type, alternative_cpu_instance_type):
    sparkml_data_path = os.path.join(DATA_DIR, "sparkml_model")
    xgboost_data_path = os.path.join(DATA_DIR, "xgboost_model")
    endpoint_name = "test-inference-pipeline-deploy-{}".format(
        sagemaker_timestamp())
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(sparkml_data_path, "mleap_model.tar.gz"),
        key_prefix="integ-test-data/sparkml/model",
    )
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(xgboost_data_path, "xgb_model.tar.gz"),
        key_prefix="integ-test-data/xgboost/model",
    )

    with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
        sparkml_model = SparkMLModel(
            model_data=sparkml_model_data,
            env={"SAGEMAKER_SPARKML_SCHEMA": SCHEMA},
            sagemaker_session=sagemaker_session,
        )
        xgb_image = image_uris.retrieve("xgboost",
                                        sagemaker_session.boto_region_name,
                                        version="1",
                                        image_scope="inference")
        xgb_model = Model(model_data=xgb_model_data,
                          image_uri=xgb_image,
                          sagemaker_session=sagemaker_session)
        model = PipelineModel(
            models=[sparkml_model, xgb_model],
            role="SageMakerRole",
            predictor_cls=Predictor,
            sagemaker_session=sagemaker_session,
        )
        predictor = model.deploy(1,
                                 alternative_cpu_instance_type,
                                 endpoint_name=endpoint_name)
        endpoint_desc = sagemaker_session.sagemaker_client.describe_endpoint(
            EndpointName=endpoint_name)
        old_config_name = endpoint_desc["EndpointConfigName"]

        predictor.update_endpoint(initial_instance_count=1,
                                  instance_type=cpu_instance_type)

        endpoint_desc = sagemaker_session.sagemaker_client.describe_endpoint(
            EndpointName=endpoint_name)
        new_config_name = endpoint_desc["EndpointConfigName"]
        new_config = sagemaker_session.sagemaker_client.describe_endpoint_config(
            EndpointConfigName=new_config_name)

        assert old_config_name != new_config_name
        assert new_config["ProductionVariants"][0][
            "InstanceType"] == cpu_instance_type
        assert new_config["ProductionVariants"][0]["InitialInstanceCount"] == 1

    model.delete_model()
    with pytest.raises(Exception) as exception:
        sagemaker_session.sagemaker_client.describe_model(ModelName=model.name)
        assert "Could not find model" in str(exception.value)
def test_inference_pipeline_model_deploy(sagemaker_session, cpu_instance_type):
    sparkml_data_path = os.path.join(DATA_DIR, "sparkml_model")
    xgboost_data_path = os.path.join(DATA_DIR, "xgboost_model")
    endpoint_name = "test-inference-pipeline-deploy-{}".format(
        sagemaker_timestamp())
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(sparkml_data_path, "mleap_model.tar.gz"),
        key_prefix="integ-test-data/sparkml/model",
    )
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(xgboost_data_path, "xgb_model.tar.gz"),
        key_prefix="integ-test-data/xgboost/model",
    )

    with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
        sparkml_model = SparkMLModel(
            model_data=sparkml_model_data,
            env={"SAGEMAKER_SPARKML_SCHEMA": SCHEMA},
            sagemaker_session=sagemaker_session,
        )
        xgb_image = image_uris.retrieve("xgboost",
                                        sagemaker_session.boto_region_name,
                                        version="1",
                                        image_scope="inference")
        xgb_model = Model(model_data=xgb_model_data,
                          image_uri=xgb_image,
                          sagemaker_session=sagemaker_session)
        model = PipelineModel(
            models=[sparkml_model, xgb_model],
            role="SageMakerRole",
            sagemaker_session=sagemaker_session,
            name=endpoint_name,
        )
        model.deploy(1, cpu_instance_type, endpoint_name=endpoint_name)
        predictor = Predictor(
            endpoint_name=endpoint_name,
            sagemaker_session=sagemaker_session,
            serializer=JSONSerializer,
            content_type="text/csv",
            accept="text/csv",
        )

        with open(VALID_DATA_PATH, "r") as f:
            valid_data = f.read()
            assert predictor.predict(valid_data) == "0.714013934135"

        with open(INVALID_DATA_PATH, "r") as f:
            invalid_data = f.read()
            assert predictor.predict(invalid_data) is None

    model.delete_model()
    with pytest.raises(Exception) as exception:
        sagemaker_session.sagemaker_client.describe_model(ModelName=model.name)
        assert "Could not find model" in str(exception.value)
Exemple #7
0
def inference_pipeline_ep(role, sess, spark_model_uri, region, bucket,
                          pipeline_model_name, endpoint_name, **context):
    timestamp_prefix = Variable.get("timestamp")
    # sm = boto3.client('sagemaker', region_name=region)
    s3client = boto3.client('s3', region_name=region)

    s3_sparkml_data_uri = spark_model_uri

    # Using S3 calls for listing model artifcats
    s3_xgb_objects = s3client.list_objects_v2(
        Bucket=bucket, StartAfter='sagemaker/spark-preprocess/model/xgboost/')
    obj_list = s3_xgb_objects['Contents']
    obj_list.sort(key=lambda x: x['LastModified'], reverse=False)
    xgboost_model_latest = obj_list[-1]['Key']
    s3_xgboost_model_uri = 's3://' + bucket + '/' + xgboost_model_latest

    # AirFlow XCOM feature
    # s3_xgboost_model_uri = context['task_instance'].xcom_pull(
    #    task_ids='xgboost_model_training')['Training']['ModelArtifacts']['S3ModelArtifacts']

    xgb_container = get_image_uri(sess.region_name,
                                  'xgboost',
                                  repo_version='0.90-1')

    schema_json = schema_utils.abalone_schema()

    sparkml_model = SparkMLModel(
        model_data=s3_sparkml_data_uri,
        role=role,
        sagemaker_session=sagemaker.session.Session(sess),
        env={'SAGEMAKER_SPARKML_SCHEMA': schema_json})

    xgb_model = Model(model_data=s3_xgboost_model_uri,
                      role=role,
                      sagemaker_session=sagemaker.session.Session(sess),
                      image=xgb_container)

    pipeline_model_name = pipeline_model_name

    sm_model = PipelineModel(name=pipeline_model_name,
                             role=role,
                             sagemaker_session=sagemaker.session.Session(sess),
                             models=[sparkml_model, xgb_model])

    endpoint_name = endpoint_name

    sm_model.deploy(initial_instance_count=1,
                    instance_type='ml.c4.xlarge',
                    endpoint_name=endpoint_name)
Exemple #8
0
def test_inference_pipeline_model_deploy(sagemaker_session):
    sparkml_data_path = os.path.join(DATA_DIR, 'sparkml_model')
    xgboost_data_path = os.path.join(DATA_DIR, 'xgboost_model')
    endpoint_name = 'test-inference-pipeline-deploy-{}'.format(
        sagemaker_timestamp())
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(sparkml_data_path, 'mleap_model.tar.gz'),
        key_prefix='integ-test-data/sparkml/model')
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(xgboost_data_path, 'xgb_model.tar.gz'),
        key_prefix='integ-test-data/xgboost/model')

    with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
        sparkml_model = SparkMLModel(model_data=sparkml_model_data,
                                     env={'SAGEMAKER_SPARKML_SCHEMA': SCHEMA},
                                     sagemaker_session=sagemaker_session)
        xgb_image = get_image_uri(sagemaker_session.boto_region_name,
                                  'xgboost')
        xgb_model = Model(model_data=xgb_model_data,
                          image=xgb_image,
                          sagemaker_session=sagemaker_session)
        model = PipelineModel(models=[sparkml_model, xgb_model],
                              role='SageMakerRole',
                              sagemaker_session=sagemaker_session,
                              name=endpoint_name)
        model.deploy(1, 'ml.m4.xlarge', endpoint_name=endpoint_name)
        predictor = RealTimePredictor(endpoint=endpoint_name,
                                      sagemaker_session=sagemaker_session,
                                      serializer=json_serializer,
                                      content_type=CONTENT_TYPE_CSV,
                                      accept=CONTENT_TYPE_CSV)

        with open(VALID_DATA_PATH, 'r') as f:
            valid_data = f.read()
            assert predictor.predict(valid_data) == '0.714013934135'

        with open(INVALID_DATA_PATH, 'r') as f:
            invalid_data = f.read()
            assert (predictor.predict(invalid_data) is None)

    model.delete_model()
    with pytest.raises(Exception) as exception:
        sagemaker_session.sagemaker_client.describe_model(ModelName=model.name)
        assert 'Could not find model' in str(exception.value)
def test_inference_pipeline_batch_transform(sagemaker_session,
                                            cpu_instance_type):
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(SPARKML_DATA_PATH, "mleap_model.tar.gz"),
        key_prefix="integ-test-data/sparkml/model",
    )
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(XGBOOST_DATA_PATH, "xgb_model.tar.gz"),
        key_prefix="integ-test-data/xgboost/model",
    )
    batch_job_name = "test-inference-pipeline-batch-{}".format(
        sagemaker_timestamp())
    sparkml_model = SparkMLModel(
        model_data=sparkml_model_data,
        env={"SAGEMAKER_SPARKML_SCHEMA": SCHEMA},
        sagemaker_session=sagemaker_session,
    )
    xgb_image = image_uris.retrieve("xgboost",
                                    sagemaker_session.boto_region_name,
                                    version="1",
                                    image_scope="inference")
    xgb_model = Model(model_data=xgb_model_data,
                      image_uri=xgb_image,
                      sagemaker_session=sagemaker_session)
    model = PipelineModel(
        models=[sparkml_model, xgb_model],
        role="SageMakerRole",
        sagemaker_session=sagemaker_session,
        name=batch_job_name,
    )
    transformer = model.transformer(1, cpu_instance_type)
    transform_input_key_prefix = "integ-test-data/sparkml_xgboost/transform"
    transform_input = transformer.sagemaker_session.upload_data(
        path=VALID_DATA_PATH, key_prefix=transform_input_key_prefix)

    with timeout_and_delete_model_with_transformer(
            transformer,
            sagemaker_session,
            minutes=TRANSFORM_DEFAULT_TIMEOUT_MINUTES):
        transformer.transform(transform_input,
                              content_type="text/csv",
                              job_name=batch_job_name)
        transformer.wait()
def test_inference_pipeline_model_deploy(sagemaker_session):
    sparkml_data_path = os.path.join(DATA_DIR, 'sparkml_model')
    xgboost_data_path = os.path.join(DATA_DIR, 'xgboost_model')
    endpoint_name = 'test-inference-pipeline-deploy-{}'.format(sagemaker_timestamp())
    sparkml_model_data = sagemaker_session.upload_data(
        path=os.path.join(sparkml_data_path, 'mleap_model.tar.gz'),
        key_prefix='integ-test-data/sparkml/model')
    xgb_model_data = sagemaker_session.upload_data(
        path=os.path.join(xgboost_data_path, 'xgb_model.tar.gz'),
        key_prefix='integ-test-data/xgboost/model')
    schema = json.dumps({
        "input": [
            {
                "name": "Pclass",
                "type": "float"
            },
            {
                "name": "Embarked",
                "type": "string"
            },
            {
                "name": "Age",
                "type": "float"
            },
            {
                "name": "Fare",
                "type": "float"
            },
            {
                "name": "SibSp",
                "type": "float"
            },
            {
                "name": "Sex",
                "type": "string"
            }
        ],
        "output": {
            "name": "features",
            "struct": "vector",
            "type": "double"
        }
    })
    with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
        sparkml_model = SparkMLModel(model_data=sparkml_model_data,
                                     env={'SAGEMAKER_SPARKML_SCHEMA': schema},
                                     sagemaker_session=sagemaker_session)
        xgb_image = get_image_uri(sagemaker_session.boto_region_name, 'xgboost')
        xgb_model = Model(model_data=xgb_model_data, image=xgb_image,
                          sagemaker_session=sagemaker_session)
        model = PipelineModel(models=[sparkml_model, xgb_model], role='SageMakerRole',
                              sagemaker_session=sagemaker_session, name=endpoint_name)
        model.deploy(1, 'ml.m4.xlarge', endpoint_name=endpoint_name)
        predictor = RealTimePredictor(endpoint=endpoint_name, sagemaker_session=sagemaker_session,
                                      serializer=json_serializer, content_type=CONTENT_TYPE_CSV,
                                      accept=CONTENT_TYPE_CSV)

        valid_data = '1.0,C,38.0,71.5,1.0,female'
        assert predictor.predict(valid_data) == "0.714013934135"

        invalid_data = "1.0,28.0,C,38.0,71.5,1.0"
        assert (predictor.predict(invalid_data) is None)

    model.delete_model()
    with pytest.raises(Exception) as exception:
        sagemaker_session.sagemaker_client.describe_model(ModelName=model.name)
        assert 'Could not find model' in str(exception.value)
from pathlib import Path

import boto3
import sagemaker
from cfn_tools import load_yaml
from sagemaker.sparkml.model import SparkMLModel

account = boto3.client('sts').get_caller_identity()['Account']
with open(Path(__file__).parents[2]/'setup/stack.yaml') as f:
    env = load_yaml(f)

file_name = "model.tar.gz"
bucket_name = env['Parameters']['PreBucket']['Default']
role = f'arn:aws:iam::{account}:role/sagemaker-role'
endpoint_name = env['Mappings']['TaskMap']['predict']['name']
model_name = "model"
instance_type = "ml.t2.medium"

if __name__ == "__main__":
    sparkml_model = SparkMLModel(model_data=f"s3://{bucket_name}/{file_name}",
                                 role=role,
                                 sagemaker_session=sagemaker.Session(
                                     boto3.session.Session()),
                                 name=model_name)

    sparkml_model.deploy(initial_instance_count=1,
                         instance_type=instance_type,
                         endpoint_name=endpoint_name)