Skip to content

Commit ada8b2a

Browse files
committed
Merge remote-tracking branch 'origin/master' into mvs-tfs
2 parents 82d5366 + 9abfce0 commit ada8b2a

File tree

16 files changed

+152
-51
lines changed

16 files changed

+152
-51
lines changed

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# Changelog
22

3+
## v1.20.3 (2019-05-15)
4+
5+
### Bug fixes and other changes
6+
7+
* run tests if buildspec.yml has been modified
8+
* skip local file check for TF requirements file when source_dir is an S3 URI
9+
10+
### Documentation changes
11+
12+
* fix docs in regards to transform_fn for mxnet
13+
14+
## v1.20.2 (2019-05-13)
15+
16+
### Bug fixes and other changes
17+
18+
* pin pytest version to 4.4.1 to avoid pluggy version conflict
19+
20+
## v1.20.1 (2019-05-09)
21+
22+
### Bug fixes and other changes
23+
24+
* update TrainingInputMode with s3_input InputMode
25+
26+
## v1.20.0 (2019-05-08)
27+
28+
### Features
29+
30+
* add RL Ray 0.6.5 support
31+
32+
### Bug fixes and other changes
33+
34+
* prevent false positive PR test results
35+
* adjust Ray test script for Ray 0.6.5
36+
337
## v1.19.1 (2019-05-06)
438

539
### Bug fixes and other changes

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.19.2.dev0
1+
1.20.4.dev0

buildspec.yml

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,21 @@ phases:
1717
# run unit tests
1818
- AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_SESSION_TOKEN=
1919
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI= AWS_DEFAULT_REGION=
20-
tox -e py27,py36 -- tests/unit
20+
tox -e py36,py27 -- tests/unit
2121

2222
# run notebook test
2323
- |
24-
if has-matching-changes "src/*.py" "setup.py" "setup.cfg"; then
24+
if has-matching-changes "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
2525
echo "running notebook test"
26-
python setup.py sdist
27-
aws s3 --region us-west-2 cp ./dist/sagemaker-*.tar.gz s3://sagemaker-python-sdk-pr/sagemaker.tar.gz
28-
aws s3 cp s3://sagemaker-mead-cli/mead-nb-test.tar.gz mead-nb-test.tar.gz
29-
tar -xzf mead-nb-test.tar.gz
30-
git clone --depth 1 https://github.com/awslabs/amazon-sagemaker-examples.git
31-
JAVA_HOME=$(get-java-home)
32-
echo "set JAVA_HOME=$JAVA_HOME"
33-
SAGEMAKER_ROLE_ARN=$(get-sagemaker-role-arn)
34-
echo "set SAGEMAKER_ROLE_ARN=$SAGEMAKER_ROLE_ARN"
35-
./runtime/bin/mead-run-nb-test \
36-
--instance-type ml.c4.8xlarge \
37-
--region us-west-2 \
38-
--lifecycle-config-name install-python-sdk \
39-
--notebook-instance-role-arn $SAGEMAKER_ROLE_ARN \
40-
./amazon-sagemaker-examples/sagemaker-python-sdk/tensorflow_distributed_mnist/tensorflow_batch_transform_mnist.ipynb
26+
./tests/scripts/run-notebook-test.sh
4127
else
4228
echo "skipping notebook test"
4329
fi
4430
4531
# run integration tests
4632
- |
47-
if has-matching-changes "tests/" "src/*.py" "setup.py" "setup.cfg"; then
48-
IGNORE_COVERAGE=- tox -e py36 -- tests/integ -n 24 --boxed --reruns 2
49-
IGNORE_COVERAGE=- tox -e py27 -- tests/integ -n 24 --boxed --reruns 2
33+
if has-matching-changes "tests/" "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
34+
IGNORE_COVERAGE=- tox -e py36,py27 -- tests/integ -n 24 --boxed --reruns 2
5035
else
5136
echo "skipping integration tests"
5237
fi

doc/using_mxnet.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,8 +688,7 @@ The default implementation expects ``prediction`` to be an ``NDArray`` and can s
688688
Using ``transform_fn``
689689
''''''''''''''''''''''
690690

691-
If you would rather not structure your code around the three methods described above, you can instead define your own ``transform_fn`` to handle inference requests.
692-
This will override any implementation of ``input_fn``, ``predict_fn``, or ``output_fn``.
691+
If you would rather not structure your code around the three methods described above, you can instead define your own ``transform_fn`` to handle inference requests. An error will be thrown if a ``transform_fn`` is present in conjunction with any ``input_fn``, ``predict_fn``, and/or ``output_fn``.
693692
``transform_fn`` has the following signature:
694693

695694
.. code:: python

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def read_version():
6060
install_requires=required_packages,
6161

6262
extras_require={
63-
'test': ['tox', 'flake8', 'pytest', 'pytest-cov', 'pytest-rerunfailures',
63+
'test': ['tox', 'flake8', 'pytest==4.4.1', 'pytest-cov', 'pytest-rerunfailures',
6464
'pytest-xdist', 'mock', 'tensorflow>=1.3.0', 'contextlib2',
6565
'awslogs', 'pandas']},
6666

src/sagemaker/estimator.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,12 @@ def start_new(cls, estimator, inputs):
569569
train_args['tags'] = estimator.tags
570570
train_args['metric_definitions'] = estimator.metric_definitions
571571

572+
if isinstance(inputs, s3_input):
573+
if 'InputMode' in inputs.config:
574+
logging.debug('Selecting s3_input\'s input_mode ({}) for TrainingInputMode.'
575+
.format(inputs.config['InputMode']))
576+
train_args['input_mode'] = inputs.config['InputMode']
577+
572578
if estimator.enable_network_isolation():
573579
train_args['enable_network_isolation'] = True
574580

src/sagemaker/rl/README.rst

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ With Reinforcement Learning (RL) Estimators, you can train reinforcement learnin
77
Supported versions of Coach: ``0.11.1``, ``0.10.1`` with TensorFlow, ``0.11.0`` with TensorFlow or MXNet.
88
For more information about Coach, see https://github.com/NervanaSystems/coach
99

10-
Supported versions of Ray: ``0.5.3`` with TensorFlow.
10+
Supported versions of Ray: ``0.6.5``, ``0.5.3`` with TensorFlow.
1111
For more information about Ray, see https://github.com/ray-project/ray
1212

1313
For information about using RL with the SageMaker Python SDK, see https://sagemaker.readthedocs.io/en/stable/using_rl.html.
@@ -23,19 +23,19 @@ SageMaker runs RL Estimator scripts in either Python 3.5 for MXNet or Python 3.6
2323

2424
The Docker images have the following dependencies installed:
2525

26-
+-------------------------+-------------------+-------------------+-------------------+
27-
| Dependencies | Coach 0.10.1 | Coach 0.11.0 | Ray 0.5.3 |
28-
+-------------------------+-------------------+-------------------+-------------------+
29-
| Python | 3.6 | 3.5(MXNet) or | 3.6 |
30-
| | | 3.6(TensorFlow) | |
31-
+-------------------------+-------------------+-------------------+-------------------+
32-
| CUDA (GPU image only) | 9.0 | 9.0 | 9.0 |
33-
+-------------------------+-------------------+-------------------+-------------------+
34-
| DL Framework | TensorFlow-1.11.0 | MXNet-1.3.0 or | TensorFlow-1.11.0 |
35-
| | | TensorFlow-1.11.0 | |
36-
+-------------------------+-------------------+-------------------+-------------------+
37-
| gym | 0.10.5 | 0.10.5 | 0.10.5 |
38-
+-------------------------+-------------------+-------------------+-------------------+
26+
+-------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
27+
| Dependencies | Coach 0.10.1 | Coach 0.11.0 | Coach 0.11.1 | Ray 0.5.3 | Ray 0.6.5 |
28+
+-------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
29+
| Python | 3.6 | 3.5 (MXNet) or | 3.6 | 3.6 | 3.6 |
30+
| | | 3.6 (TensorFlow) | | | |
31+
+-------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
32+
| CUDA (GPU image only) | 9.0 | 9.0 | 9.0 | 9.0 | 9.0 |
33+
+-------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
34+
| DL Framework | TensorFlow-1.11.0 | MXNet-1.3.0 or | TensorFlow-1.12.0 | TensorFlow-1.11.0 | TensorFlow-1.12.0 |
35+
| | | TensorFlow-1.11.0 | | | |
36+
+-------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
37+
| gym | 0.10.5 | 0.10.5 | 0.11.0 | 0.10.5 | 0.12.1 |
38+
+-------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
3939

4040
The Docker images extend Ubuntu 16.04.
4141

src/sagemaker/rl/estimator.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@
5353
},
5454
'0.5': {
5555
'tensorflow': '1.11'
56-
}
56+
},
57+
'0.6.5': {
58+
'tensorflow': '1.12'
59+
},
60+
'0.6': {
61+
'tensorflow': '1.12'
62+
},
5763
}
5864
}
5965

@@ -73,7 +79,7 @@ class RLEstimator(Framework):
7379

7480
COACH_LATEST_VERSION_TF = '0.11.1'
7581
COACH_LATEST_VERSION_MXNET = '0.11.0'
76-
RAY_LATEST_VERSION = '0.5.3'
82+
RAY_LATEST_VERSION = '0.6.5'
7783

7884
def __init__(self, entry_point, toolkit=None, toolkit_version=None, framework=None,
7985
source_dir=None, hyperparameters=None, image_name=None,

src/sagemaker/tensorflow/estimator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ def _validate_requirements_file(self, requirements_file):
283283
if not self.source_dir:
284284
raise ValueError('Must specify source_dir along with a requirements file.')
285285

286+
if self.source_dir.lower().startswith('s3://'):
287+
return
288+
286289
if os.path.isabs(requirements_file):
287290
raise ValueError('Requirements file {} is not a path relative to source_dir.'.format(
288291
requirements_file))

src/sagemaker/tuner.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import importlib
1616
import inspect
1717
import json
18+
import logging
1819
from enum import Enum
1920

2021
import sagemaker
@@ -26,6 +27,7 @@
2627
from sagemaker.parameter import (CategoricalParameter, ContinuousParameter,
2728
IntegerParameter, ParameterRange)
2829
from sagemaker.session import Session
30+
from sagemaker.session import s3_input
2931
from sagemaker.utils import base_name_from_image, name_from_base, to_str
3032

3133
AMAZON_ESTIMATOR_MODULE = 'sagemaker'
@@ -640,6 +642,12 @@ def start_new(cls, tuner, inputs):
640642
tuner_args['warm_start_config'] = warm_start_config_req
641643
tuner_args['early_stopping_type'] = tuner.early_stopping_type
642644

645+
if isinstance(inputs, s3_input):
646+
if 'InputMode' in inputs.config:
647+
logging.debug('Selecting s3_input\'s input_mode ({}) for TrainingInputMode.'
648+
.format(inputs.config['InputMode']))
649+
tuner_args['input_mode'] = inputs.config['InputMode']
650+
643651
if isinstance(tuner.estimator, sagemaker.algorithm.AlgorithmEstimator):
644652
tuner_args['algorithm_arn'] = tuner.estimator.algorithm_arn
645653
else:

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def rl_coach_mxnet_version(request):
140140
return request.param
141141

142142

143-
@pytest.fixture(scope='module', params=['0.5', '0.5.3'])
143+
@pytest.fixture(scope='module', params=['0.5', '0.5.3', '0.6', '0.6.5'])
144144
def rl_ray_version(request):
145145
return request.param
146146

tests/data/ray_cartpole/train_ray.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from ray.tune.logger import pretty_print
66

77
# Based on https://github.com/ray-project/ray/blob/master/doc/source/rllib-training.rst#python-api
8-
ray.init(redirect_output=False, redirect_worker_output=False)
8+
ray.init(log_to_driver=False)
99
config = ppo.DEFAULT_CONFIG.copy()
1010
config["num_gpus"] = int(os.environ.get("SM_NUM_GPUS", 0))
1111
checkpoint_dir = os.environ.get("SM_MODEL_DIR", '/Users/nadzeya/gym')

tests/integ/test_chainer_train.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
1+
# Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License"). You
44
# may not use this file except in compliance with the License. A copy of
@@ -21,7 +21,7 @@
2121
from sagemaker.chainer.defaults import CHAINER_VERSION
2222
from sagemaker.chainer.estimator import Chainer
2323
from sagemaker.chainer.model import ChainerModel
24-
from sagemaker.utils import sagemaker_timestamp
24+
from sagemaker.utils import unique_name_from_base
2525
import tests.integ
2626
from tests.integ import DATA_DIR, PYTHON_VERSION, TRAINING_DEFAULT_TIMEOUT_MINUTES
2727
from tests.integ.timeout import timeout, timeout_and_delete_endpoint_by_name
@@ -62,14 +62,15 @@ def test_training_with_additional_hyperparameters(sagemaker_session, chainer_ful
6262
test_input = chainer.sagemaker_session.upload_data(path=os.path.join(data_path, 'test'),
6363
key_prefix='integ-test-data/chainer_mnist/test')
6464

65-
chainer.fit({'train': train_input, 'test': test_input})
65+
job_name = unique_name_from_base('test-chainer-training')
66+
chainer.fit({'train': train_input, 'test': test_input}, job_name=job_name)
6667
return chainer.latest_training_job.name
6768

6869

6970
@pytest.mark.canary_quick
7071
@pytest.mark.regional_testing
7172
def test_attach_deploy(chainer_training_job, sagemaker_session):
72-
endpoint_name = 'test-chainer-attach-deploy-{}'.format(sagemaker_timestamp())
73+
endpoint_name = unique_name_from_base('test-chainer-attach-deploy')
7374

7475
with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
7576
estimator = Chainer.attach(chainer_training_job, sagemaker_session=sagemaker_session)
@@ -78,7 +79,7 @@ def test_attach_deploy(chainer_training_job, sagemaker_session):
7879

7980

8081
def test_deploy_model(chainer_training_job, sagemaker_session):
81-
endpoint_name = 'test-chainer-deploy-model-{}'.format(sagemaker_timestamp())
82+
endpoint_name = unique_name_from_base('test-chainer-deploy-model')
8283
with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
8384
desc = sagemaker_session.sagemaker_client.describe_training_job(TrainingJobName=chainer_training_job)
8485
model_data = desc['ModelArtifacts']['S3ModelArtifacts']
@@ -89,15 +90,14 @@ def test_deploy_model(chainer_training_job, sagemaker_session):
8990

9091

9192
def test_async_fit(sagemaker_session):
92-
endpoint_name = 'test-chainer-attach-deploy-{}'.format(sagemaker_timestamp())
93-
9493
with timeout(minutes=5):
9594
training_job_name = _run_mnist_training_job(sagemaker_session, "ml.c4.xlarge", 1,
9695
chainer_full_version=CHAINER_VERSION, wait=False)
9796

9897
print("Waiting to re-attach to the training job: %s" % training_job_name)
9998
time.sleep(20)
10099

100+
endpoint_name = unique_name_from_base('test-chainer-async-fit')
101101
with timeout_and_delete_endpoint_by_name(endpoint_name, sagemaker_session):
102102
print("Re-attaching now to: %s" % training_job_name)
103103
estimator = Chainer.attach(training_job_name=training_job_name, sagemaker_session=sagemaker_session)
@@ -115,7 +115,7 @@ def test_failed_training_job(sagemaker_session, chainer_full_version):
115115
sagemaker_session=sagemaker_session)
116116

117117
with pytest.raises(ValueError) as e:
118-
chainer.fit()
118+
chainer.fit(job_name=unique_name_from_base('test-chainer-training'))
119119
assert 'ExecuteUserScriptError' in str(e.value)
120120

121121

@@ -138,7 +138,8 @@ def _run_mnist_training_job(sagemaker_session, instance_type, instance_count,
138138
test_input = chainer.sagemaker_session.upload_data(path=os.path.join(data_path, 'test'),
139139
key_prefix='integ-test-data/chainer_mnist/test')
140140

141-
chainer.fit({'train': train_input, 'test': test_input}, wait=wait)
141+
job_name = unique_name_from_base('test-chainer-training')
142+
chainer.fit({'train': train_input, 'test': test_input}, wait=wait, job_name=job_name)
142143
return chainer.latest_training_job.name
143144

144145

tests/scripts/run-notebook-test.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
#
3+
# Run a test against a SageMaker notebook
4+
# Only runs within the SDK's CI/CD environment
5+
6+
set -euo pipefail
7+
8+
python setup.py sdist
9+
aws s3 --region us-west-2 cp ./dist/sagemaker-*.tar.gz s3://sagemaker-python-sdk-pr/sagemaker.tar.gz
10+
aws s3 cp s3://sagemaker-mead-cli/mead-nb-test.tar.gz mead-nb-test.tar.gz
11+
tar -xzf mead-nb-test.tar.gz
12+
git clone --depth 1 https://github.com/awslabs/amazon-sagemaker-examples.git
13+
export JAVA_HOME=$(get-java-home)
14+
echo "set JAVA_HOME=$JAVA_HOME"
15+
export SAGEMAKER_ROLE_ARN=$(get-sagemaker-role-arn)
16+
echo "set SAGEMAKER_ROLE_ARN=$SAGEMAKER_ROLE_ARN"
17+
./runtime/bin/mead-run-nb-test \
18+
--instance-type ml.c4.8xlarge \
19+
--region us-west-2 \
20+
--lifecycle-config-name install-python-sdk \
21+
--notebook-instance-role-arn $SAGEMAKER_ROLE_ARN \
22+
./amazon-sagemaker-examples/sagemaker-python-sdk/tensorflow_distributed_mnist/tensorflow_batch_transform_mnist.ipynb

tests/unit/test_estimator.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,17 @@ def test_augmented_manifest(sagemaker_session):
315315
assert s3_data_source['AttributeNames'] == ['foo', 'bar']
316316

317317

318+
def test_s3_input_mode(sagemaker_session):
319+
expected_input_mode = 'Pipe'
320+
fw = DummyFramework(entry_point=SCRIPT_PATH, role='DummyRole', sagemaker_session=sagemaker_session,
321+
train_instance_count=INSTANCE_COUNT, train_instance_type=INSTANCE_TYPE,
322+
enable_cloudwatch_metrics=True)
323+
fw.fit(inputs=s3_input('s3://mybucket/train_manifest', input_mode=expected_input_mode))
324+
325+
actual_input_mode = sagemaker_session.method_calls[1][2]['input_mode']
326+
assert actual_input_mode == expected_input_mode
327+
328+
318329
def test_shuffle_config(sagemaker_session):
319330
fw = DummyFramework(entry_point=SCRIPT_PATH, role='DummyRole', sagemaker_session=sagemaker_session,
320331
train_instance_count=INSTANCE_COUNT, train_instance_type=INSTANCE_TYPE,

tests/unit/test_tuner.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from sagemaker.tuner import (_TuningJob, create_identical_dataset_and_algorithm_tuner,
2929
create_transfer_learning_tuner, HyperparameterTuner, WarmStartConfig,
3030
WarmStartTypes)
31+
from sagemaker.session import s3_input
3132

3233
DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
3334
MODEL_DATA = "s3://bucket/model.tar.gz"
@@ -286,6 +287,31 @@ def test_fit_mxnet_with_vpc_config(sagemaker_session, tuner):
286287
assert tune_kwargs['vpc_config'] == {'Subnets': subnets, 'SecurityGroupIds': security_group_ids}
287288

288289

290+
def test_s3_input_mode(sagemaker_session, tuner):
291+
expected_input_mode = 'Pipe'
292+
293+
script_path = os.path.join(DATA_DIR, 'mxnet_mnist', 'failure_script.py')
294+
mxnet = MXNet(entry_point=script_path,
295+
role=ROLE,
296+
framework_version=FRAMEWORK_VERSION,
297+
train_instance_count=TRAIN_INSTANCE_COUNT,
298+
train_instance_type=TRAIN_INSTANCE_TYPE,
299+
sagemaker_session=sagemaker_session)
300+
tuner.estimator = mxnet
301+
302+
tags = [{'Name': 'some-tag-without-a-value'}]
303+
tuner.tags = tags
304+
305+
hyperparameter_ranges = {'num_components': IntegerParameter(2, 4),
306+
'algorithm_mode': CategoricalParameter(['regular', 'randomized'])}
307+
tuner._hyperparameter_ranges = hyperparameter_ranges
308+
309+
tuner.fit(inputs=s3_input('s3://mybucket/train_manifest', input_mode=expected_input_mode))
310+
311+
actual_input_mode = sagemaker_session.method_calls[1][2]['input_mode']
312+
assert actual_input_mode == expected_input_mode
313+
314+
289315
def test_fit_pca_with_inter_container_traffic_encryption_flag(sagemaker_session, tuner):
290316
pca = PCA(ROLE, TRAIN_INSTANCE_COUNT, TRAIN_INSTANCE_TYPE, NUM_COMPONENTS,
291317
base_job_name='pca', sagemaker_session=sagemaker_session,

0 commit comments

Comments
 (0)