def main(): image_name = "sagemaker-sklearn-rf-regressor-local" # Prepare data for model inference - we use the Boston housing dataset print('Preparing data for model inference') data = fetch_california_housing() X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.25, random_state=42) # we don't train a model, so we will need only the testing data testX = pd.DataFrame(X_test, columns=data.feature_names) # Download a pre-trained model file print('Downloading a pre-trained model file') s3.download_file( 'aws-ml-blog', 'artifacts/scikit_learn_bring_your_own_model/model.joblib', 'model.joblib') # Creating a model.tar.gz file tar = tarfile.open('model.tar.gz', 'w:gz') tar.add('model.joblib') tar.close() model = Model(image_uri=image_name, role=DUMMY_IAM_ROLE, model_data='file://./model.tar.gz') print('Deploying endpoint in local mode') endpoint = model.deploy(initial_instance_count=1, instance_type='local', endpoint_name="my-local-endpoint") predictor = Predictor(endpoint_name="my-local-endpoint", sagemaker_session=sagemaker_session, serializer=CSVSerializer(), deserializer=CSVDeserializer()) predictions = predictor.predict(testX[data.feature_names].head(5).to_csv( header=False, index=False)) print(f"Predictions: {predictions}") print('About to delete the endpoint to stop paying (if in cloud mode).') predictor.delete_endpoint(predictor.endpoint_name)
def _deploy_inference_pipeline( self, inference_containers, initial_instance_count, instance_type, name=None, sagemaker_session=None, endpoint_name=None, tags=None, wait=True, update_endpoint=False, vpc_config=None, enable_network_isolation=False, model_kms_key=None, ): """Deploy a SageMaker Inference Pipeline. Args: inference_containers (list): a list of inference container definitions initial_instance_count (int): The initial number of instances to run in the ``Endpoint`` created from this ``Model``. instance_type (str): The EC2 instance type to deploy this Model to. For example, 'ml.p2.xlarge'. name (str): The pipeline model name. If None, a default model name will be selected on each ``deploy``. sagemaker_session (sagemaker.session.Session): A SageMaker Session object, used for SageMaker interactions (default: None). If not specified, one is created using the default AWS configuration chain. endpoint_name (str): The name of the endpoint to create (default: None). If not specified, a unique endpoint name will be created. tags (List[dict[str, str]]): The list of tags to attach to this specific endpoint. wait (bool): Whether the call should wait until the deployment of model completes (default: True). update_endpoint (bool): Flag to update the model in an existing Amazon SageMaker endpoint. If True, this will deploy a new EndpointConfig to an already existing endpoint and delete resources corresponding to the previous EndpointConfig. If False, a new endpoint will be created. Default: False vpc_config (dict): information about vpc configuration, optionally contains "SecurityGroupIds", "Subnets" model_kms_key (str): KMS key ARN used to encrypt the repacked model archive file if the model is repacked """ # construct Model objects models = [] for container in inference_containers: image = container["Image"] model_data = container["ModelDataUrl"] env = container["Environment"] model = Model( image=image, model_data=model_data, role=self.role, env=env, vpc_config=vpc_config, sagemaker_session=sagemaker_session or self.sagemaker_session, enable_network_isolation=enable_network_isolation, model_kms_key=model_kms_key, ) models.append(model) pipeline = PipelineModel( models=models, role=self.role, name=name, vpc_config=vpc_config, sagemaker_session=sagemaker_session or self.sagemaker_session, ) return pipeline.deploy( initial_instance_count=initial_instance_count, instance_type=instance_type, endpoint_name=endpoint_name, tags=tags, wait=wait, update_endpoint=update_endpoint, )
def create_model( self, name, sagemaker_session=None, candidate=None, vpc_config=None, enable_network_isolation=False, model_kms_key=None, predictor_cls=None, inference_response_keys=None, ): """Creates a model from a given candidate or the best candidate from the automl job Args: name (str): The pipeline model name. sagemaker_session (sagemaker.session.Session): A SageMaker Session object, used for SageMaker interactions (default: None). If not specified, the one originally associated with the ``AutoML`` instance is used.: candidate (CandidateEstimator or dict): a CandidateEstimator used for deploying to a SageMaker Inference Pipeline. If None, the best candidate will be used. If the candidate input is a dict, a CandidateEstimator will be created from it. vpc_config (dict): Specifies a VPC that your training jobs and hosted models have access to. Contents include "SecurityGroupIds" and "Subnets". enable_network_isolation (bool): Isolates the training container. No inbound or outbound network calls can be made, except for calls between peers within a training cluster for distributed training. Default: False model_kms_key (str): KMS key ARN used to encrypt the repacked model archive file if the model is repacked predictor_cls (callable[string, sagemaker.session.Session]): A function to call to create a predictor (default: None). If specified, ``deploy()`` returns the result of invoking this function on the created endpoint name. inference_response_keys (list): List of keys for response content. The order of the keys will dictate the content order in the response. Returns: PipelineModel object """ sagemaker_session = sagemaker_session or self.sagemaker_session if candidate is None: candidate_dict = self.best_candidate() candidate = CandidateEstimator(candidate_dict, sagemaker_session=sagemaker_session) elif isinstance(candidate, dict): candidate = CandidateEstimator(candidate, sagemaker_session=sagemaker_session) inference_containers = candidate.containers self.validate_and_update_inference_response(inference_containers, inference_response_keys) # construct Model objects models = [] for container in inference_containers: image_uri = container["Image"] model_data = container["ModelDataUrl"] env = container["Environment"] model = Model( image_uri=image_uri, model_data=model_data, role=self.role, env=env, vpc_config=vpc_config, sagemaker_session=sagemaker_session or self.sagemaker_session, enable_network_isolation=enable_network_isolation, model_kms_key=model_kms_key, ) models.append(model) pipeline = PipelineModel( models=models, role=self.role, predictor_cls=predictor_cls, name=name, vpc_config=vpc_config, sagemaker_session=sagemaker_session or self.sagemaker_session, ) return pipeline
def test_conditional_pytorch_training_model_registration( sagemaker_session, role, cpu_instance_type, pipeline_name, region_name, ): base_dir = os.path.join(DATA_DIR, "pytorch_mnist") entry_point = os.path.join(base_dir, "mnist.py") input_path = sagemaker_session.upload_data( path=os.path.join(base_dir, "training"), key_prefix="integ-test-data/pytorch_mnist/training", ) inputs = TrainingInput(s3_data=input_path) instance_count = ParameterInteger(name="InstanceCount", default_value=1) instance_type = ParameterString(name="InstanceType", default_value="ml.m5.xlarge") good_enough_input = ParameterInteger(name="GoodEnoughInput", default_value=1) in_condition_input = ParameterString(name="Foo", default_value="Foo") pytorch_estimator = PyTorch( entry_point=entry_point, role=role, framework_version="1.5.0", py_version="py3", instance_count=instance_count, instance_type=instance_type, sagemaker_session=sagemaker_session, ) step_train = TrainingStep( name="pytorch-train", estimator=pytorch_estimator, inputs=inputs, ) step_register = RegisterModel( name="pytorch-register-model", estimator=pytorch_estimator, model_data=step_train.properties.ModelArtifacts.S3ModelArtifacts, content_types=["*"], response_types=["*"], inference_instances=["*"], transform_instances=["*"], description="test-description", ) model = Model( image_uri=pytorch_estimator.training_image_uri(), model_data=step_train.properties.ModelArtifacts.S3ModelArtifacts, sagemaker_session=sagemaker_session, role=role, ) model_inputs = CreateModelInput( instance_type="ml.m5.large", accelerator_type="ml.eia1.medium", ) step_model = CreateModelStep( name="pytorch-model", model=model, inputs=model_inputs, ) step_cond = ConditionStep( name="cond-good-enough", conditions=[ ConditionGreaterThanOrEqualTo(left=good_enough_input, right=1), ConditionIn(value=in_condition_input, in_values=["foo", "bar"]), ], if_steps=[step_train, step_register], else_steps=[step_model], ) pipeline = Pipeline( name=pipeline_name, parameters=[ in_condition_input, good_enough_input, instance_count, instance_type, ], steps=[step_cond], sagemaker_session=sagemaker_session, ) try: response = pipeline.create(role) create_arn = response["PipelineArn"] assert re.match( rf"arn:aws:sagemaker:{region_name}:\d{{12}}:pipeline/{pipeline_name}", create_arn, ) execution = pipeline.start(parameters={}) assert re.match( rf"arn:aws:sagemaker:{region_name}:\d{{12}}:pipeline/{pipeline_name}/execution/", execution.arn, ) execution = pipeline.start(parameters={"GoodEnoughInput": 0}) assert re.match( rf"arn:aws:sagemaker:{region_name}:\d{{12}}:pipeline/{pipeline_name}/execution/", execution.arn, ) finally: try: pipeline.delete() except Exception: pass
def test_tuning_single_algo( sagemaker_session, role, cpu_instance_type, pipeline_name, region_name, ): base_dir = os.path.join(DATA_DIR, "pytorch_mnist") entry_point = os.path.join(base_dir, "mnist.py") input_path = sagemaker_session.upload_data( path=os.path.join(base_dir, "training"), key_prefix="integ-test-data/pytorch_mnist/training", ) inputs = TrainingInput(s3_data=input_path) instance_count = ParameterInteger(name="InstanceCount", default_value=1) instance_type = ParameterString(name="InstanceType", default_value="ml.m5.xlarge") pytorch_estimator = PyTorch( entry_point=entry_point, role=role, framework_version="1.5.0", py_version="py3", instance_count=instance_count, instance_type=instance_type, sagemaker_session=sagemaker_session, enable_sagemaker_metrics=True, max_retry_attempts=3, ) min_batch_size = ParameterInteger(name="MinBatchSize", default_value=64) max_batch_size = ParameterInteger(name="MaxBatchSize", default_value=128) hyperparameter_ranges = { "batch-size": IntegerParameter(min_batch_size, max_batch_size), } tuner = HyperparameterTuner( estimator=pytorch_estimator, objective_metric_name="test:acc", objective_type="Maximize", hyperparameter_ranges=hyperparameter_ranges, metric_definitions=[{ "Name": "test:acc", "Regex": "Overall test accuracy: (.*?);" }], max_jobs=2, max_parallel_jobs=2, ) step_tune = TuningStep( name="my-tuning-step", tuner=tuner, inputs=inputs, ) best_model = Model( image_uri=pytorch_estimator.training_image_uri(), model_data=step_tune.get_top_model_s3_uri( top_k=0, s3_bucket=sagemaker_session.default_bucket(), ), sagemaker_session=sagemaker_session, role=role, ) model_inputs = CreateModelInput( instance_type="ml.m5.large", accelerator_type="ml.eia1.medium", ) step_best_model = CreateModelStep( name="1st-model", model=best_model, inputs=model_inputs, ) second_best_model = Model( image_uri=pytorch_estimator.training_image_uri(), model_data=step_tune.get_top_model_s3_uri( top_k=1, s3_bucket=sagemaker_session.default_bucket(), ), sagemaker_session=sagemaker_session, role=role, entry_point=entry_point, source_dir=base_dir, ) step_second_best_model = CreateModelStep( name="2nd-best-model", model=second_best_model, inputs=model_inputs, ) pipeline = Pipeline( name=pipeline_name, parameters=[ instance_count, instance_type, min_batch_size, max_batch_size ], steps=[step_tune, step_best_model, step_second_best_model], sagemaker_session=sagemaker_session, ) try: response = pipeline.create(role) create_arn = response["PipelineArn"] assert re.match( rf"arn:aws:sagemaker:{region_name}:\d{{12}}:pipeline/{pipeline_name}", create_arn, ) for _ in retries( max_retry_count=5, exception_message_prefix= "Waiting for a successful execution of pipeline", seconds_to_sleep=10, ): execution = pipeline.start(parameters={}) assert re.match( rf"arn:aws:sagemaker:{region_name}:\d{{12}}:pipeline/{pipeline_name}/execution/", execution.arn, ) try: execution.wait(delay=30, max_attempts=60) except WaiterError: pass execution_steps = execution.list_steps() assert len(execution_steps) == 3 for step in execution_steps: assert step["StepStatus"] == "Succeeded" break finally: try: pipeline.delete() except Exception: pass