def test_deploy_update_endpoint(tfo, time, sagemaker_session): framework_model = DummyFrameworkModel(sagemaker_session) endpoint_name = "endpoint-name" sparkml_model = SparkMLModel(model_data=MODEL_DATA_2, role=ROLE, sagemaker_session=sagemaker_session) model = PipelineModel(models=[framework_model, sparkml_model], role=ROLE, sagemaker_session=sagemaker_session) model.deploy( instance_type=INSTANCE_TYPE, initial_instance_count=1, endpoint_name=endpoint_name, update_endpoint=True, ) sagemaker_session.create_endpoint_config.assert_called_with( name=model.name, model_name=model.name, initial_instance_count=INSTANCE_COUNT, instance_type=INSTANCE_TYPE, tags=None, ) config_name = sagemaker_session.create_endpoint_config( name=model.name, model_name=model.name, initial_instance_count=INSTANCE_COUNT, instance_type=INSTANCE_TYPE, ) sagemaker_session.update_endpoint.assert_called_with( endpoint_name, config_name) sagemaker_session.create_endpoint.assert_not_called()
def test_deploy_tags(tfo, time, sagemaker_session): framework_model = DummyFrameworkModel(sagemaker_session) sparkml_model = SparkMLModel(model_data=MODEL_DATA_2, role=ROLE, sagemaker_session=sagemaker_session) model = PipelineModel(models=[framework_model, sparkml_model], role=ROLE, sagemaker_session=sagemaker_session) tags = [{"ModelName": "TestModel"}] model.deploy(instance_type=INSTANCE_TYPE, initial_instance_count=1, tags=tags) sagemaker_session.endpoint_from_production_variants.assert_called_with( name="mi-1-2017-10-10-14-14-15", production_variants=[{ "InitialVariantWeight": 1, "ModelName": "mi-1-2017-10-10-14-14-15", "InstanceType": INSTANCE_TYPE, "InitialInstanceCount": 1, "VariantName": "AllTraffic", }], tags=tags, wait=True, kms_key=None, data_capture_config_dict=None, )
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 test_delete_model(tfo, time, sagemaker_session): framework_model = DummyFrameworkModel(sagemaker_session) pipeline_model = PipelineModel( [framework_model], role=ROLE, sagemaker_session=sagemaker_session ) pipeline_model.deploy(instance_type=INSTANCE_TYPE, initial_instance_count=1) pipeline_model.delete_model() sagemaker_session.delete_model.assert_called_with(pipeline_model.name)
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)
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)
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_deploy(tfo, time, sagemaker_session): framework_model = DummyFrameworkModel(sagemaker_session) sparkml_model = SparkMLModel(model_data=MODEL_DATA_2, role=ROLE, sagemaker_session=sagemaker_session) model = PipelineModel(models=[framework_model, sparkml_model], role=ROLE, sagemaker_session=sagemaker_session) model.deploy(instance_type=INSTANCE_TYPE, initial_instance_count=1) sagemaker_session.endpoint_from_production_variants.assert_called_with( 'mi-1-2017-10-10-14-14-15', [{ 'InitialVariantWeight': 1, 'ModelName': 'mi-1-2017-10-10-14-14-15', 'InstanceType': INSTANCE_TYPE, 'InitialInstanceCount': 1, 'VariantName': 'AllTraffic' }], None)
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_network_isolation(tfo, time, sagemaker_session): framework_model = DummyFrameworkModel(sagemaker_session) sparkml_model = SparkMLModel(model_data=MODEL_DATA_2, role=ROLE, sagemaker_session=sagemaker_session) model = PipelineModel( models=[framework_model, sparkml_model], role=ROLE, sagemaker_session=sagemaker_session, enable_network_isolation=True, ) model.deploy(instance_type=INSTANCE_TYPE, initial_instance_count=1) sagemaker_session.create_model.assert_called_with( model.name, ROLE, [ { "Image": "mi-1", "Environment": { "SAGEMAKER_PROGRAM": "blah.py", "SAGEMAKER_SUBMIT_DIRECTORY": "s3://mybucket/mi-1-2017-10-10-14-14-15/sourcedir.tar.gz", "SAGEMAKER_CONTAINER_LOG_LEVEL": "20", "SAGEMAKER_REGION": "us-west-2", }, "ModelDataUrl": "s3://bucket/model_1.tar.gz", }, { "Image": "246618743249.dkr.ecr.us-west-2.amazonaws.com/sagemaker-sparkml-serving:2.2", "Environment": {}, "ModelDataUrl": "s3://bucket/model_2.tar.gz", }, ], vpc_config=None, enable_network_isolation=True, )
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)
preproc_model_url = args.preproc_model sm_role = get_sm_execution_role(False, region) preproc_model = SKLearnModel(model_data=preproc_model_url, source_dir=os.path.abspath( os.path.dirname(__file__)), role=sm_role, entry_point='infer_preproc.py', sagemaker_session=sess) ll_image = get_image_uri(region, 'linear-learner') ll_model = Model(model_data=model_url, image=ll_image, role=sm_role, sagemaker_session=sess) timestamp_prefix = strftime("%Y-%m-%d-%H-%M-%S", gmtime()) model_name = 'inference-pipeline-' + timestamp_prefix endpoint_name = 'inference-pipeline-ep-' + timestamp_prefix sm_model = PipelineModel(name=model_name, role=sm_role, models=[preproc_model, ll_model], sagemaker_session=sess) print('Deploying SM EndPoint') sm_model.deploy(initial_instance_count=1, instance_type='ml.c4.xlarge', endpoint_name=endpoint_name) print(f'SageMaker deployed to endpoint - {endpoint_name}')