Skip to content

Commit e6108b7

Browse files
authored
Merge branch 'master' into custom_image_name
2 parents 1ecf93d + 54b6660 commit e6108b7

37 files changed

+1898
-98
lines changed

CHANGELOG.rst

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,30 @@
22
CHANGELOG
33
=========
44

5+
1.5.1dev
6+
========
7+
8+
* enhancement: Let Framework models reuse code uploaded by Framework estimators
9+
* enhancement: Unify generation of model uploaded code location
10+
* feature: Change minimum required scipy from 1.0.0 to 0.19.0
11+
* feature: Allow Chainer, Tensorflow and MXNet estimators to use a custom docker image.
12+
13+
1.5.0
14+
=====
15+
16+
* feature: Add Support for PyTorch Framework
17+
* feature: Estimators: add support for TensorFlow 1.7.0
18+
* feature: Estimators: add support for TensorFlow 1.8.0
19+
* feature: Allow Local Serving of Models in S3
20+
* enhancement: Allow option for ``HyperparameterTuner`` to not include estimator metadata in job
21+
* bug-fix: Estimators: Join tensorboard thread after fitting
22+
523
1.4.2
624
=====
725

826
* bug-fix: Estimators: Fix attach for LDA
927
* bug-fix: Estimators: allow code_location to have no key prefix
1028
* bug-fix: Local Mode: Fix s3 training data download when there is a trailing slash
11-
* feature: Allow Local Serving of Models in S3
12-
* feature: Allow Chainer, Tensorflow and MXNet estimators to use a custom docker image.
13-
1429

1530
1.4.1
1631
=====

README.rst

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ Table of Contents
2828
3. `MXNet SageMaker Estimators <#mxnet-sagemaker-estimators>`__
2929
4. `TensorFlow SageMaker Estimators <#tensorflow-sagemaker-estimators>`__
3030
5. `Chainer SageMaker Estimators <#chainer-sagemaker-estimators>`__
31-
6. `AWS SageMaker Estimators <#aws-sagemaker-estimators>`__
32-
7. `BYO Docker Containers with SageMaker Estimators <#byo-docker-containers-with-sagemaker-estimators>`__
33-
8. `SageMaker Automatic Model Tuning <#sagemaker-automatic-model-tuning>`__
34-
9. `BYO Model <#byo-model>`__
31+
6. `PyTorch SageMaker Estimators <#pytorch-sagemaker-estimators>`__
32+
7. `AWS SageMaker Estimators <#aws-sagemaker-estimators>`__
33+
8. `BYO Docker Containers with SageMaker Estimators <#byo-docker-containers-with-sagemaker-estimators>`__
34+
9. `SageMaker Automatic Model Tuning <#sagemaker-automatic-model-tuning>`__
35+
10. `BYO Model <#byo-model>`__
3536

3637

3738
Getting SageMaker Python SDK
@@ -49,7 +50,7 @@ You can install from source by cloning this repository and issuing a pip install
4950

5051
git clone https://github.com/aws/sagemaker-python-sdk.git
5152
python setup.py sdist
52-
pip install dist/sagemaker-1.4.2.tar.gz
53+
pip install dist/sagemaker-1.5.0.tar.gz
5354

5455
Supported Python versions
5556
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -64,19 +65,26 @@ http://aws.amazon.com/apache2.0/
6465
Running tests
6566
~~~~~~~~~~~~~
6667

67-
SageMaker Python SDK uses tox for running Python tests. You can run the tests by running tox:
68+
SageMaker Python SDK has unit tests and integration tests.
6869

69-
::
70-
71-
tox
70+
**Unit tests**
7271

73-
Tests are defined in ``tests/`` and includes unit and integ tests. If you just want to run unit tests, then you can issue:
72+
tox is a prerequisite for running unit tests so you need to make sure you have it installed. To run the unit tests:
7473

7574
::
7675

7776
tox tests/unit
7877

79-
To just run integ tests, issue the following command:
78+
**Integrations tests**
79+
80+
To be able to run the integration tests, the following prerequisites must be met
81+
82+
1. Access to an AWS account to run the tests on
83+
2. Make the AWS account credentials available to boto3 clients used in the tests
84+
3. Ensure the AWS account has an IAM role named :code:`SageMakerRole`
85+
4. Ensure the libraries mentioned in setup.py extra_require for test are installed which can be achieved using :code:`pip install --upgrade .[test]`
86+
87+
You can run integ tests by issuing the following command:
8088

8189
::
8290

@@ -117,6 +125,7 @@ Later sections of this document explain how to use the different Estimators and
117125
* `MXNet SageMaker Estimators and Models <#mxnet-sagemaker-estimators>`__
118126
* `TensorFlow SageMaker Estimators and Models <#tensorflow-sagemaker-estimators>`__
119127
* `Chainer SageMaker Estimators and Models <#chainer-sagemaker-estimators>`__
128+
* `PyTorch SageMaker Estimators <#pytorch-sagemaker-estimators>`__
120129
* `AWS SageMaker Estimators and Models <#aws-sagemaker-estimators>`__
121130
* `Custom SageMaker Estimators and Models <#byo-docker-containers-with-sagemaker-estimators>`__
122131

@@ -215,7 +224,7 @@ TensorFlow SageMaker Estimators allow you to run your own TensorFlow
215224
training algorithms on SageMaker Learner, and to host your own TensorFlow
216225
models on SageMaker Hosting.
217226

218-
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``.
227+
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``.
219228

220229
More details at `TensorFlow SageMaker Estimators and Models`_.
221230

@@ -236,6 +245,20 @@ More details at `Chainer SageMaker Estimators and Models`_.
236245
.. _Chainer SageMaker Estimators and Models: src/sagemaker/chainer/README.rst
237246

238247

248+
PyTorch SageMaker Estimators
249+
-------------------------------
250+
251+
With PyTorch Estimators, you can train and host PyTorch models on Amazon SageMaker.
252+
253+
Supported versions of PyTorch: ``0.4.0``
254+
255+
You can visit the PyTorch repository at https://github.com/pytorch/pytorch.
256+
257+
More details at `PyTorch SageMaker Estimators and Models`_.
258+
259+
.. _PyTorch SageMaker Estimators and Models: src/sagemaker/pytorch/README.rst
260+
261+
239262
AWS SageMaker Estimators
240263
------------------------
241264
Amazon SageMaker provides several built-in machine learning algorithms that you can use for a variety of problem types.
@@ -321,6 +344,14 @@ In addition, the ``fit()`` call uses a list of ``RecordSet`` objects instead of
321344
# Start hyperparameter tuning job
322345
my_tuner.fit([train_records, test_records])
323346
347+
To aid with attaching a previously-started hyperparameter tuning job with a ``HyperparameterTuner`` instance, ``fit()`` injects metadata in the hyperparameters by default.
348+
If the algorithm you are using cannot handle unknown hyperparameters (e.g. an Amazon ML algorithm that does not have a custom estimator in the Python SDK), then you can set ``include_cls_metadata`` to ``False`` when calling fit:
349+
350+
.. code:: python
351+
352+
my_tuner.fit({'train': 's3://my_bucket/my_training_data', 'test': 's3://my_bucket_my_testing_data'},
353+
include_cls_metadata=False)
354+
324355
There is also an analytics object associated with each ``HyperparameterTuner`` instance that presents useful information about the hyperparameter tuning job.
325356
For example, the ``dataframe`` method gets a pandas dataframe summarizing the associated training jobs:
326357

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def read(fname):
2323

2424

2525
setup(name="sagemaker",
26-
version="1.4.2",
26+
version="1.5.0",
2727
description="Open source library for training and deploying models on Amazon SageMaker.",
2828
packages=find_packages('src'),
2929
package_dir={'': 'src'},
@@ -44,7 +44,7 @@ def read(fname):
4444
],
4545

4646
# Declare minimal set for installation
47-
install_requires=['boto3>=1.4.8', 'numpy>=1.9.0', 'protobuf>=3.1', 'scipy>=1.0.0', 'urllib3>=1.2',
47+
install_requires=['boto3>=1.4.8', 'numpy>=1.9.0', 'protobuf>=3.1', 'scipy>=0.19.0', 'urllib3>=1.2',
4848
'PyYAML>=3.2'],
4949

5050
extras_require={

src/sagemaker/chainer/README.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,11 @@ Saving models
243243
In order to save your trained Chainer model for deployment on SageMaker, your training script should save your model
244244
to a certain filesystem path called `model_dir`. This value is accessible through the environment variable
245245
``SM_MODEL_DIR``. The following code demonstrates how to save a trained Chainer model named ``model`` as
246-
``model.npz`` at the :
246+
``model.npz`` at the end of training:
247247

248248
.. code:: python
249-
import chainer
249+
250+
import chainer
250251
import argparse
251252
import os
252253
@@ -255,7 +256,7 @@ import chainer
255256
parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
256257
args, _ = parser.parse_known_args()
257258
258-
# ... train `model`, then save it to `model_dir`
259+
# ... train `model`, then save it to `model_dir` as file 'model.npz'
259260
chainer.serializers.save_npz(os.path.join(args.model_dir, 'model.npz'), model)
260261
261262
After your training job is complete, SageMaker will compress and upload the serialized model to S3, and your model data

src/sagemaker/chainer/estimator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def create_model(self, model_server_workers=None):
109109
sagemaker.chainer.model.ChainerModel: A SageMaker ``ChainerModel`` object.
110110
See :func:`~sagemaker.chainer.model.ChainerModel` for full details.
111111
"""
112-
return ChainerModel(self.model_data, self.role, self.entry_point, source_dir=self.source_dir,
112+
return ChainerModel(self.model_data, self.role, self.entry_point, source_dir=self._model_source_dir(),
113113
enable_cloudwatch_metrics=self.enable_cloudwatch_metrics, name=self._current_job_name,
114114
container_log_level=self.container_log_level, code_location=self.code_location,
115115
py_version=self.py_version, framework_version=self.framework_version,

src/sagemaker/chainer/model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313
from __future__ import absolute_import
1414

1515
import sagemaker
16-
from sagemaker.fw_utils import create_image_uri
16+
from sagemaker.fw_utils import create_image_uri, model_code_key_prefix
1717
from sagemaker.model import FrameworkModel, MODEL_SERVER_WORKERS_PARAM_NAME
1818
from sagemaker.chainer.defaults import CHAINER_VERSION
1919
from sagemaker.predictor import RealTimePredictor, npy_serializer, numpy_deserializer
20-
from sagemaker.utils import name_from_image
2120

2221

2322
class ChainerPredictor(RealTimePredictor):
@@ -85,7 +84,8 @@ def prepare_container_def(self, instance_type):
8584
region_name = self.sagemaker_session.boto_session.region_name
8685
deploy_image = create_image_uri(region_name, self.__framework_name__, instance_type,
8786
self.framework_version, self.py_version)
88-
deploy_key_prefix = self.key_prefix or self.name or name_from_image(deploy_image)
87+
88+
deploy_key_prefix = model_code_key_prefix(self.key_prefix, self.name, deploy_image)
8989
self._upload_code(deploy_key_prefix)
9090
deploy_env = dict(self.env)
9191
deploy_env.update(self._framework_env_vars())

src/sagemaker/estimator.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ def _prepare_for_training(self, job_name=None):
566566
self._hyperparameters[SAGEMAKER_REGION_PARAM_NAME] = self.sagemaker_session.boto_region_name
567567

568568
def _stage_user_code_in_s3(self):
569-
""" Upload the user training script to s3 and return the location.
569+
"""Upload the user training script to s3 and return the location.
570570
571571
Returns: s3 uri
572572
@@ -584,6 +584,14 @@ def _stage_user_code_in_s3(self):
584584
script=self.entry_point,
585585
directory=self.source_dir)
586586

587+
def _model_source_dir(self):
588+
"""Get the appropriate value to pass as source_dir to model constructor on deploying
589+
590+
Returns:
591+
str: Either a local or an S3 path pointing to the source_dir to be used for code by the model to be deployed
592+
"""
593+
return self.source_dir if self.sagemaker_session.local_mode else self.uploaded_code.s3_prefix
594+
587595
def hyperparameters(self):
588596
"""Return the hyperparameters as a dictionary to use for training.
589597

src/sagemaker/fw_utils.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from collections import namedtuple
2020
from six.moves.urllib.parse import urlparse
2121

22+
from sagemaker.utils import name_from_image
23+
2224
"""This module contains utility functions shared across ``Framework`` components."""
2325

2426

@@ -156,7 +158,7 @@ def framework_name_from_image(image_name):
156158
else:
157159
# extract framework, python version and image tag
158160
# We must support both the legacy and current image name format.
159-
name_pattern = re.compile('^sagemaker-(tensorflow|mxnet|chainer):(.*?)-(.*?)-(py2|py3)$')
161+
name_pattern = re.compile('^sagemaker-(tensorflow|mxnet|chainer|pytorch):(.*?)-(.*?)-(py2|py3)$')
160162
legacy_name_pattern = re.compile('^sagemaker-(tensorflow|mxnet)-(py2|py3)-(cpu|gpu):(.*)$')
161163
name_match = name_pattern.match(sagemaker_match.group(8))
162164
legacy_match = legacy_name_pattern.match(sagemaker_match.group(8))
@@ -199,3 +201,21 @@ def parse_s3_url(url):
199201
if parsed_url.scheme != "s3":
200202
raise ValueError("Expecting 's3' scheme, got: {} in {}".format(parsed_url.scheme, url))
201203
return parsed_url.netloc, parsed_url.path.lstrip('/')
204+
205+
206+
def model_code_key_prefix(code_location_key_prefix, model_name, image):
207+
"""Returns the s3 key prefix for uploading code during model deployment
208+
209+
The location returned is a potential concatenation of 2 parts
210+
1. code_location_key_prefix if it exists
211+
2. model_name or a name derived from the image
212+
213+
Args:
214+
code_location_key_prefix (str): the s3 key prefix from code_location
215+
model_name (str): the name of the model
216+
image (str): the image from which a default name can be extracted
217+
218+
Returns:
219+
str: the key prefix to be used in uploading code
220+
"""
221+
return '/'.join(filter(None, [code_location_key_prefix, model_name or name_from_image(image)]))

src/sagemaker/model.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import sagemaker
1818

1919
from sagemaker.local import LocalSession
20-
from sagemaker.fw_utils import tar_and_upload_dir, parse_s3_url
20+
from sagemaker.fw_utils import tar_and_upload_dir, parse_s3_url, model_code_key_prefix
2121
from sagemaker.session import Session
2222
from sagemaker.utils import name_from_image, get_config_value
2323

@@ -132,6 +132,7 @@ def __init__(self, model_data, image, role, entry_point, source_dir=None, predic
132132
source_dir (str): Path (absolute or relative) to a directory with any other training
133133
source code dependencies aside from tne entry point file (default: None). Structure within this
134134
directory will be preserved when training on SageMaker.
135+
If the directory points to S3, no code will be uploaded and the S3 location will be used instead.
135136
predictor_cls (callable[string, sagemaker.session.Session]): A function to call to create
136137
a predictor (default: None). If not None, ``deploy`` will return the result of invoking
137138
this function on the created endpoint name.
@@ -169,7 +170,8 @@ def prepare_container_def(self, instance_type):
169170
Returns:
170171
dict[str, str]: A container definition object usable with the CreateModel API.
171172
"""
172-
self._upload_code(self.key_prefix or self.name or name_from_image(self.image))
173+
deploy_key_prefix = model_code_key_prefix(self.key_prefix, self.name, self.image)
174+
self._upload_code(deploy_key_prefix)
173175
deploy_env = dict(self.env)
174176
deploy_env.update(self._framework_env_vars())
175177
return sagemaker.container_def(self.image, self.model_data, deploy_env)

src/sagemaker/mxnet/estimator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ def create_model(self, model_server_workers=None):
8181
if self.image_name:
8282
kwargs['image'] = self.image_name
8383

84-
return MXNetModel(self.model_data, self.role, self.entry_point, source_dir=self.source_dir,
84+
return MXNetModel(self.model_data, self.role, self.entry_point, source_dir=self._model_source_dir(),
8585
enable_cloudwatch_metrics=self.enable_cloudwatch_metrics, name=self._current_job_name,
86-
container_log_level=self.container_log_level, code_location=self.code_location,
86+
container_log_level=self.container_log_level, code_location=self.code_location, image=self.image_name,
8787
py_version=self.py_version, framework_version=self.framework_version,
8888
model_server_workers=model_server_workers, sagemaker_session=self.sagemaker_session, **kwargs)
8989

src/sagemaker/mxnet/model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313
from __future__ import absolute_import
1414

1515
import sagemaker
16-
from sagemaker.fw_utils import create_image_uri
16+
from sagemaker.fw_utils import create_image_uri, model_code_key_prefix
1717
from sagemaker.model import FrameworkModel, MODEL_SERVER_WORKERS_PARAM_NAME
1818
from sagemaker.mxnet.defaults import MXNET_VERSION
1919
from sagemaker.predictor import RealTimePredictor, json_serializer, json_deserializer
20-
from sagemaker.utils import name_from_image
2120

2221

2322
class MXNetPredictor(RealTimePredictor):
@@ -85,7 +84,8 @@ def prepare_container_def(self, instance_type):
8584
region_name = self.sagemaker_session.boto_session.region_name
8685
deploy_image = create_image_uri(region_name, self.__framework_name__, instance_type,
8786
self.framework_version, self.py_version)
88-
deploy_key_prefix = self.key_prefix or self.name or name_from_image(deploy_image)
87+
88+
deploy_key_prefix = model_code_key_prefix(self.key_prefix, self.name, deploy_image)
8989
self._upload_code(deploy_key_prefix)
9090
deploy_env = dict(self.env)
9191
deploy_env.update(self._framework_env_vars())

0 commit comments

Comments
 (0)