Skip to content

Commit 8c8d3e4

Browse files
authored
Merge pull request #1 from aws/master
merging from main repo to fork before re-submitting horovod PR again
2 parents 877c946 + 8e1ffb0 commit 8c8d3e4

File tree

9 files changed

+274
-308
lines changed

9 files changed

+274
-308
lines changed

README.rst

-8
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@
66
SageMaker Python SDK
77
====================
88

9-
.. image:: https://travis-ci.org/aws/sagemaker-python-sdk.svg?branch=master
10-
:target: https://travis-ci.org/aws/sagemaker-python-sdk
11-
:alt: Build Status
12-
13-
.. image:: https://codecov.io/gh/aws/sagemaker-python-sdk/branch/master/graph/badge.svg
14-
:target: https://codecov.io/gh/aws/sagemaker-python-sdk
15-
:alt: CodeCov
16-
179
.. image:: https://img.shields.io/pypi/v/sagemaker.svg
1810
:target: https://pypi.python.org/pypi/sagemaker
1911
:alt: Latest Version

doc/using_mxnet.rst

+194-295
Large diffs are not rendered by default.

doc/using_tf.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ is good practice.
9191
Note that SageMaker doesn't support argparse actions.
9292
For example, if you want to use a boolean hyperparameter, specify ``type`` as ``bool`` in your script and provide an explicit ``True`` or ``False`` value for this hyperparameter when you create the TensorFlow estimator.
9393

94-
For a complete example of a TensorFlow training script, see `mnist.py <https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-python-sdk/tensorflow_distributed_mnist/mnist.py>`__.
94+
For a complete example of a TensorFlow training script, see `mnist.py <https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-python-sdk/tensorflow_script_mode_training_and_serving/mnist.py>`__.
9595

9696

9797
Adapting your local TensorFlow script
@@ -360,7 +360,7 @@ Training with MKL-DNN disabled
360360
SageMaker TensorFlow CPU images use TensorFlow built with Intel® MKL-DNN optimization.
361361

362362
In certain cases you might be able to get a better performance by disabling this optimization
363-
(`for example when using small models <https://github.com/awslabs/amazon-sagemaker-examples/blob/d88d1c19861fb7733941969f5a68821d9da2982e/sagemaker-python-sdk/tensorflow_iris_dnn_classifier_using_estimators/iris_dnn_classifier.py#L7-L9>`_)
363+
(for example when using small models).
364364

365365
You can disable MKL-DNN optimization for TensorFlow ``1.8.0`` and above by setting two following environment variables:
366366

src/sagemaker/local/local_session.py

+4
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ def invoke_endpoint(
341341
ContentType=None,
342342
Accept=None,
343343
CustomAttributes=None,
344+
TargetModel=None,
344345
):
345346
"""
346347
@@ -365,6 +366,9 @@ def invoke_endpoint(
365366
if CustomAttributes is not None:
366367
headers["X-Amzn-SageMaker-Custom-Attributes"] = CustomAttributes
367368

369+
if TargetModel is not None:
370+
headers["X-Amzn-SageMaker-Target-Model"] = TargetModel
371+
368372
r = self.http.request("POST", url, body=Body, preload_content=False, headers=headers)
369373

370374
return {"Body": r, "ContentType": Accept}

src/sagemaker/multidatamodel.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from six.moves.urllib.parse import urlparse
1818

1919
import sagemaker
20-
from sagemaker import s3
20+
from sagemaker import local, s3
2121
from sagemaker.model import Model
2222
from sagemaker.session import Session
2323

@@ -210,6 +210,9 @@ def deploy(
210210
if role is None:
211211
raise ValueError("Role can not be null for deploying a model")
212212

213+
if instance_type == "local" and not isinstance(self.sagemaker_session, local.LocalSession):
214+
self.sagemaker_session = local.LocalSession()
215+
213216
container_def = self.prepare_container_def(instance_type, accelerator_type=accelerator_type)
214217
self.sagemaker_session.create_model(
215218
self.name,

src/sagemaker/utils.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,8 @@ def _create_or_update_code_dir(
534534
if os.path.isdir(dependency):
535535
shutil.copytree(dependency, os.path.join(lib_dir, os.path.basename(dependency)))
536536
else:
537-
os.mkdir(lib_dir)
537+
if not os.path.exists(lib_dir):
538+
os.mkdir(lib_dir)
538539
shutil.copy2(dependency, lib_dir)
539540

540541

tests/integ/test_multidatamodel.py

+61
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,67 @@ def test_multi_data_model_deploy_pretrained_models(
177177
assert "Could not find endpoint" in str(exception.value)
178178

179179

180+
@pytest.mark.local_mode
181+
def test_multi_data_model_deploy_pretrained_models_local_mode(container_image, sagemaker_session):
182+
timestamp = sagemaker_timestamp()
183+
endpoint_name = "test-multimodel-endpoint-{}".format(timestamp)
184+
model_name = "test-multimodel-{}".format(timestamp)
185+
186+
# Define pretrained model local path
187+
pretrained_model_data_local_path = os.path.join(DATA_DIR, "sparkml_model", "mleap_model.tar.gz")
188+
189+
with timeout(minutes=30):
190+
model_data_prefix = os.path.join(
191+
"s3://", sagemaker_session.default_bucket(), "multimodel-{}/".format(timestamp)
192+
)
193+
multi_data_model = MultiDataModel(
194+
name=model_name,
195+
model_data_prefix=model_data_prefix,
196+
image=container_image,
197+
role=ROLE,
198+
sagemaker_session=sagemaker_session,
199+
)
200+
201+
# Add model before deploy
202+
multi_data_model.add_model(pretrained_model_data_local_path, PRETRAINED_MODEL_PATH_1)
203+
# Deploy model to an endpoint
204+
multi_data_model.deploy(1, "local", endpoint_name=endpoint_name)
205+
# Add models after deploy
206+
multi_data_model.add_model(pretrained_model_data_local_path, PRETRAINED_MODEL_PATH_2)
207+
208+
endpoint_models = []
209+
for model_path in multi_data_model.list_models():
210+
endpoint_models.append(model_path)
211+
assert PRETRAINED_MODEL_PATH_1 in endpoint_models
212+
assert PRETRAINED_MODEL_PATH_2 in endpoint_models
213+
214+
predictor = RealTimePredictor(
215+
endpoint=endpoint_name,
216+
sagemaker_session=multi_data_model.sagemaker_session,
217+
serializer=npy_serializer,
218+
deserializer=string_deserializer,
219+
)
220+
221+
data = numpy.zeros(shape=(1, 1, 28, 28))
222+
result = predictor.predict(data, target_model=PRETRAINED_MODEL_PATH_1)
223+
assert result == "Invoked model: {}".format(PRETRAINED_MODEL_PATH_1)
224+
225+
result = predictor.predict(data, target_model=PRETRAINED_MODEL_PATH_2)
226+
assert result == "Invoked model: {}".format(PRETRAINED_MODEL_PATH_2)
227+
228+
# Cleanup
229+
multi_data_model.sagemaker_session.sagemaker_client.delete_endpoint_config(
230+
EndpointConfigName=endpoint_name
231+
)
232+
multi_data_model.sagemaker_session.delete_endpoint(endpoint_name)
233+
multi_data_model.delete_model()
234+
with pytest.raises(Exception) as exception:
235+
sagemaker_session.sagemaker_client.describe_model(ModelName=multi_data_model.name)
236+
assert "Could not find model" in str(exception.value)
237+
sagemaker_session.sagemaker_client.describe_endpoint_config(name=endpoint_name)
238+
assert "Could not find endpoint" in str(exception.value)
239+
240+
180241
def test_multi_data_model_deploy_trained_model_from_framework_estimator(
181242
container_image, sagemaker_session, cpu_instance_type
182243
):

tests/scripts/run-notebook-test.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ echo "set SAGEMAKER_ROLE_ARN=$SAGEMAKER_ROLE_ARN"
1919
--region us-west-2 \
2020
--lifecycle-config-name install-python-sdk \
2121
--notebook-instance-role-arn $SAGEMAKER_ROLE_ARN \
22-
./amazon-sagemaker-examples/sagemaker-python-sdk/tensorflow_distributed_mnist/tensorflow_batch_transform_mnist.ipynb
22+
./amazon-sagemaker-examples/sagemaker-python-sdk/pytorch_cnn_cifar10/pytorch_local_mode_cifar10.ipynb

tests/unit/test_utils.py

+6
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ def test_repack_model_without_source_dir(tmp, fake_s3):
444444
"model-dir/model",
445445
"dependencies/a",
446446
"dependencies/some/dir/b",
447+
"aa",
448+
"bb",
447449
"source-dir/inference.py",
448450
"source-dir/this-file-should-not-be-included.py",
449451
],
@@ -457,6 +459,8 @@ def test_repack_model_without_source_dir(tmp, fake_s3):
457459
dependencies=[
458460
os.path.join(tmp, "dependencies/a"),
459461
os.path.join(tmp, "dependencies/some/dir"),
462+
os.path.join(tmp, "aa"),
463+
os.path.join(tmp, "bb"),
460464
],
461465
model_uri="s3://fake/location",
462466
repacked_model_uri="s3://destination-bucket/model.tar.gz",
@@ -466,6 +470,8 @@ def test_repack_model_without_source_dir(tmp, fake_s3):
466470
assert list_tar_files(fake_s3.fake_upload_path, tmp) == {
467471
"/model",
468472
"/code/lib/a",
473+
"/code/lib/aa",
474+
"/code/lib/bb",
469475
"/code/lib/dir/b",
470476
"/code/inference.py",
471477
}

0 commit comments

Comments
 (0)