Skip to content

Commit 4e02b12

Browse files
committed
PR comments
1 parent e63e6d5 commit 4e02b12

File tree

16 files changed

+130
-139
lines changed

16 files changed

+130
-139
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ CHANGELOG
55
1.15.1dev
66
=========
77

8-
* feature: Estimators: lib_dirs attribute allows export of additional libraries into the container
8+
* feature: Estimators: dependencies attribute allows export of additional libraries into the container
99
* feature: Add APIs to export Airflow transform and deploy config
1010

1111
1.15.0

src/sagemaker/chainer/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,14 @@ The following are optional arguments. When you create a ``Chainer`` object, you
149149
other training source code dependencies including the entry point
150150
file. Structure within this directory will be preserved when training
151151
on SageMaker.
152-
- ``lib_dirs (list[str])`` A list of paths to directories (absolute or relative) with
152+
- ``dependencies (list[str])`` A list of paths to directories (absolute or relative) with
153153
any additional libraries that will be exported to the container (default: []).
154154
The library folders will be copied to SageMaker in the same folder where the entrypoint is copied.
155155
If the ```source_dir``` points to S3, code will be uploaded and the S3 location will be used
156156
instead. Example:
157157

158158
The following call
159-
>>> Estimator(entry_point='train.py', lib_dirs=['my/libs/common', 'virtual-env'])
159+
>>> Chainer(entry_point='train.py', dependencies=['my/libs/common', 'virtual-env'])
160160
results in the following inside the container:
161161

162162
>>> $ ls

src/sagemaker/chainer/estimator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def create_model(self, model_server_workers=None, role=None, vpc_config_override
133133
py_version=self.py_version, framework_version=self.framework_version,
134134
model_server_workers=model_server_workers, image=self.image_name,
135135
sagemaker_session=self.sagemaker_session,
136-
vpc_config=self.get_vpc_config(vpc_config_override), lib_dirs=self.lib_dirs)
136+
vpc_config=self.get_vpc_config(vpc_config_override), dependencies=self.dependencies)
137137

138138
@classmethod
139139
def _prepare_init_params_from_job_description(cls, job_details, model_channel_name=None):

src/sagemaker/estimator.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ class Framework(EstimatorBase):
637637
LAUNCH_PS_ENV_NAME = 'sagemaker_parameter_server_enabled'
638638

639639
def __init__(self, entry_point, source_dir=None, hyperparameters=None, enable_cloudwatch_metrics=False,
640-
container_log_level=logging.INFO, code_location=None, image_name=None, lib_dirs=None, **kwargs):
640+
container_log_level=logging.INFO, code_location=None, image_name=None, dependencies=None, **kwargs):
641641
"""Base class initializer. Subclasses which override ``__init__`` should invoke ``super()``
642642
643643
Args:
@@ -646,13 +646,13 @@ def __init__(self, entry_point, source_dir=None, hyperparameters=None, enable_cl
646646
source_dir (str): Path (absolute or relative) to a directory with any other training
647647
source code dependencies aside from tne entry point file (default: None). Structure within this
648648
directory are preserved when training on Amazon SageMaker.
649-
lib_dirs (list[str]): A list of paths to directories (absolute or relative) with
649+
dependencies (list[str]): A list of paths to directories (absolute or relative) with
650650
any additional libraries that will be exported to the container (default: []).
651651
The library folders will be copied to SageMaker in the same folder where the entrypoint is copied.
652652
Example:
653653
654654
The following call
655-
>>> Estimator(entry_point='train.py', lib_dirs=['my/libs/common', 'virtual-env'])
655+
>>> Estimator(entry_point='train.py', dependencies=['my/libs/common', 'virtual-env'])
656656
results in the following inside the container:
657657
658658
>>> $ ls
@@ -679,7 +679,7 @@ def __init__(self, entry_point, source_dir=None, hyperparameters=None, enable_cl
679679
"""
680680
super(Framework, self).__init__(**kwargs)
681681
self.source_dir = source_dir
682-
self.lib_dirs = lib_dirs or []
682+
self.dependencies = dependencies or []
683683
self.entry_point = entry_point
684684
if enable_cloudwatch_metrics:
685685
warnings.warn('enable_cloudwatch_metrics is now deprecated and will be removed in the future.',
@@ -747,7 +747,7 @@ def _stage_user_code_in_s3(self):
747747
s3_key_prefix=code_s3_prefix,
748748
script=self.entry_point,
749749
directory=self.source_dir,
750-
lib_dirs=self.lib_dirs)
750+
dependencies=self.dependencies)
751751

752752
def _model_source_dir(self):
753753
"""Get the appropriate value to pass as source_dir to model constructor on deploying

src/sagemaker/fw_utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def validate_source_dir(script, directory):
111111
return True
112112

113113

114-
def tar_and_upload_dir(session, bucket, s3_key_prefix, script, directory, lib_dirs=None):
114+
def tar_and_upload_dir(session, bucket, s3_key_prefix, script, directory, dependencies=None):
115115
"""Pack and upload source files to S3 only if directory is empty or local.
116116
117117
Note:
@@ -124,14 +124,14 @@ def tar_and_upload_dir(session, bucket, s3_key_prefix, script, directory, lib_di
124124
script (str): Script filename.
125125
directory (str or None): Directory containing the source file. If it starts with
126126
"s3://", no action is taken.
127-
lib_dirs (List[str]): A list of paths to directories (absolute or relative)
127+
dependencies (List[str]): A list of paths to directories (absolute or relative)
128128
containing additional libraries that will be copied into
129129
/opt/ml/lib
130130
131131
Returns:
132132
sagemaker.fw_utils.UserCode: An object with the S3 bucket and key (S3 prefix) and script name.
133133
"""
134-
lib_dirs = lib_dirs or []
134+
dependencies = dependencies or []
135135
key = '%s/sourcedir.tar.gz' % s3_key_prefix
136136

137137
if directory and directory.lower().startswith('s3://'):
@@ -140,7 +140,7 @@ def tar_and_upload_dir(session, bucket, s3_key_prefix, script, directory, lib_di
140140
tmp = tempfile.mkdtemp()
141141

142142
try:
143-
source_files = _list_files_to_compress(script, directory) + lib_dirs
143+
source_files = _list_files_to_compress(script, directory) + dependencies
144144
tar_file = sagemaker.utils.create_tar_file(source_files, os.path.join(tmp, _TAR_SOURCE_FILENAME))
145145

146146
session.resource('s3').Object(bucket, key).upload_file(tar_file)

src/sagemaker/model.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
import sagemaker
1818

19-
from sagemaker.local import LocalSession
20-
from sagemaker.fw_utils import tar_and_upload_dir, parse_s3_url, model_code_key_prefix
21-
from sagemaker.session import Session
22-
from sagemaker.utils import name_from_image, get_config_value
19+
from sagemaker import local
20+
from sagemaker import fw_utils
21+
from sagemaker import session
22+
from sagemaker import utils
2323

2424

2525
class Model(object):
@@ -96,12 +96,12 @@ def deploy(self, initial_instance_count, instance_type, endpoint_name=None, tags
9696
"""
9797
if not self.sagemaker_session:
9898
if instance_type in ('local', 'local_gpu'):
99-
self.sagemaker_session = LocalSession()
99+
self.sagemaker_session = local.LocalSession()
100100
else:
101-
self.sagemaker_session = Session()
101+
self.sagemaker_session = session.Session()
102102

103103
container_def = self.prepare_container_def(instance_type)
104-
self.name = self.name or name_from_image(container_def['Image'])
104+
self.name = self.name or utils.name_from_image(container_def['Image'])
105105
self.sagemaker_session.create_model(self.name, self.role, container_def, vpc_config=self.vpc_config)
106106
production_variant = sagemaker.production_variant(self.name, instance_type, initial_instance_count)
107107
self.endpoint_name = endpoint_name or self.name
@@ -127,7 +127,7 @@ class FrameworkModel(Model):
127127

128128
def __init__(self, model_data, image, role, entry_point, source_dir=None, predictor_cls=None, env=None, name=None,
129129
enable_cloudwatch_metrics=False, container_log_level=logging.INFO, code_location=None,
130-
sagemaker_session=None, lib_dirs=None, **kwargs):
130+
sagemaker_session=None, dependencies=None, **kwargs):
131131
"""Initialize a ``FrameworkModel``.
132132
133133
Args:
@@ -140,14 +140,14 @@ def __init__(self, model_data, image, role, entry_point, source_dir=None, predic
140140
source code dependencies aside from tne entry point file (default: None). Structure within this
141141
directory will be preserved when training on SageMaker.
142142
If the directory points to S3, no code will be uploaded and the S3 location will be used instead.
143-
lib_dirs (list[str]): A list of paths to directories (absolute or relative) with
143+
dependencies (list[str]): A list of paths to directories (absolute or relative) with
144144
any additional libraries that will be exported to the container (default: []).
145145
The library folders will be copied to SageMaker in the same folder where the entrypoint is copied.
146146
If the ```source_dir``` points to S3, code will be uploaded and the S3 location will be used
147147
instead. Example:
148148
149149
The following call
150-
>>> Estimator(entry_point='train.py', lib_dirs=['my/libs/common', 'virtual-env'])
150+
>>> Estimator(entry_point='train.py', dependencies=['my/libs/common', 'virtual-env'])
151151
results in the following inside the container:
152152
153153
>>> $ ls
@@ -177,11 +177,11 @@ def __init__(self, model_data, image, role, entry_point, source_dir=None, predic
177177
sagemaker_session=sagemaker_session, **kwargs)
178178
self.entry_point = entry_point
179179
self.source_dir = source_dir
180-
self.lib_dirs = lib_dirs or []
180+
self.dependencies = dependencies or []
181181
self.enable_cloudwatch_metrics = enable_cloudwatch_metrics
182182
self.container_log_level = container_log_level
183183
if code_location:
184-
self.bucket, self.key_prefix = parse_s3_url(code_location)
184+
self.bucket, self.key_prefix = fw_utils.parse_s3_url(code_location)
185185
else:
186186
self.bucket, self.key_prefix = None, None
187187
self.uploaded_code = None
@@ -197,23 +197,24 @@ def prepare_container_def(self, instance_type): # pylint disable=unused-argumen
197197
Returns:
198198
dict[str, str]: A container definition object usable with the CreateModel API.
199199
"""
200-
deploy_key_prefix = model_code_key_prefix(self.key_prefix, self.name, self.image)
200+
deploy_key_prefix = fw_utils.model_code_key_prefix(self.key_prefix, self.name, self.image)
201201
self._upload_code(deploy_key_prefix)
202202
deploy_env = dict(self.env)
203203
deploy_env.update(self._framework_env_vars())
204204
return sagemaker.container_def(self.image, self.model_data, deploy_env)
205205

206206
def _upload_code(self, key_prefix):
207-
local_code = get_config_value('local.local_code', self.sagemaker_session.config)
207+
local_code = utils.get_config_value('local.local_code', self.sagemaker_session.config)
208208
if self.sagemaker_session.local_mode and local_code:
209209
self.uploaded_code = None
210210
else:
211-
self.uploaded_code = tar_and_upload_dir(session=self.sagemaker_session.boto_session,
212-
bucket=self.bucket or self.sagemaker_session.default_bucket(),
213-
s3_key_prefix=key_prefix,
214-
script=self.entry_point,
215-
directory=self.source_dir,
216-
lib_dirs=self.lib_dirs)
211+
bucket = self.bucket or self.sagemaker_session.default_bucket()
212+
self.uploaded_code = fw_utils.tar_and_upload_dir(session=self.sagemaker_session.boto_session,
213+
bucket=bucket,
214+
s3_key_prefix=key_prefix,
215+
script=self.entry_point,
216+
directory=self.source_dir,
217+
dependencies=self.dependencies)
217218

218219
def _framework_env_vars(self):
219220
if self.uploaded_code:

src/sagemaker/mxnet/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,14 @@ The following are optional arguments. When you create an ``MXNet`` object, you c
271271
other training source code dependencies including the entry point
272272
file. Structure within this directory will be preserved when training
273273
on SageMaker.
274-
- ``lib_dirs (list[str])`` A list of paths to directories (absolute or relative) with
274+
- ``dependencies (list[str])`` A list of paths to directories (absolute or relative) with
275275
any additional libraries that will be exported to the container (default: []).
276276
The library folders will be copied to SageMaker in the same folder where the entrypoint is copied.
277277
If the ```source_dir``` points to S3, code will be uploaded and the S3 location will be used
278278
instead. Example:
279279

280280
The following call
281-
>>> Estimator(entry_point='train.py', lib_dirs=['my/libs/common', 'virtual-env'])
281+
>>> MXNet(entry_point='train.py', dependencies=['my/libs/common', 'virtual-env'])
282282
results in the following inside the container:
283283

284284
>>> $ ls

src/sagemaker/mxnet/estimator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def create_model(self, model_server_workers=None, role=None, vpc_config_override
115115
container_log_level=self.container_log_level, code_location=self.code_location,
116116
py_version=self.py_version, framework_version=self.framework_version, image=self.image_name,
117117
model_server_workers=model_server_workers, sagemaker_session=self.sagemaker_session,
118-
vpc_config=self.get_vpc_config(vpc_config_override), lib_dirs=self.lib_dirs)
118+
vpc_config=self.get_vpc_config(vpc_config_override), dependencies=self.dependencies)
119119

120120
@classmethod
121121
def _prepare_init_params_from_job_description(cls, job_details, model_channel_name=None):

src/sagemaker/pytorch/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,14 @@ The following are optional arguments. When you create a ``PyTorch`` object, you
175175
other training source code dependencies including the entry point
176176
file. Structure within this directory will be preserved when training
177177
on SageMaker.
178-
- ``lib_dirs (list[str])`` A list of paths to directories (absolute or relative) with
178+
- ``dependencies (list[str])`` A list of paths to directories (absolute or relative) with
179179
any additional libraries that will be exported to the container (default: []).
180180
The library folders will be copied to SageMaker in the same folder where the entrypoint is copied.
181181
If the ```source_dir``` points to S3, code will be uploaded and the S3 location will be used
182182
instead. Example:
183183

184184
The following call
185-
>>> Estimator(entry_point='train.py', lib_dirs=['my/libs/common', 'virtual-env'])
185+
>>> PyTorch(entry_point='train.py', dependencies=['my/libs/common', 'virtual-env'])
186186
results in the following inside the container:
187187

188188
>>> $ ls

src/sagemaker/pytorch/estimator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def create_model(self, model_server_workers=None, role=None, vpc_config_override
9696
container_log_level=self.container_log_level, code_location=self.code_location,
9797
py_version=self.py_version, framework_version=self.framework_version, image=self.image_name,
9898
model_server_workers=model_server_workers, sagemaker_session=self.sagemaker_session,
99-
vpc_config=self.get_vpc_config(vpc_config_override), lib_dirs=self.lib_dirs)
99+
vpc_config=self.get_vpc_config(vpc_config_override), dependencies=self.dependencies)
100100

101101
@classmethod
102102
def _prepare_init_params_from_job_description(cls, job_details, model_channel_name=None):

src/sagemaker/tensorflow/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,14 +409,14 @@ you can specify these as keyword arguments.
409409
other training source code dependencies including the entry point
410410
file. Structure within this directory will be preserved when training
411411
on SageMaker.
412-
- ``lib_dirs (list[str])`` A list of paths to directories (absolute or relative) with
412+
- ``dependencies (list[str])`` A list of paths to directories (absolute or relative) with
413413
any additional libraries that will be exported to the container (default: []).
414414
The library folders will be copied to SageMaker in the same folder where the entrypoint is copied.
415415
If the ```source_dir``` points to S3, code will be uploaded and the S3 location will be used
416416
instead. Example:
417417

418418
The following call
419-
>>> Estimator(entry_point='train.py', lib_dirs=['my/libs/common', 'virtual-env'])
419+
>>> TensorFlow(entry_point='train.py', dependencies=['my/libs/common', 'virtual-env'])
420420
results in the following inside the container:
421421

422422
>>> $ ls

src/sagemaker/tensorflow/estimator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ def _create_default_model(self, model_server_workers, role, vpc_config_override)
412412
model_server_workers=model_server_workers,
413413
sagemaker_session=self.sagemaker_session,
414414
vpc_config=self.get_vpc_config(vpc_config_override),
415-
lib_dirs=self.lib_dirs)
415+
dependencies=self.dependencies)
416416

417417
def hyperparameters(self):
418418
"""Return hyperparameters used by your custom TensorFlow code during model training."""

tests/data/pytorch_source_dirs/train.py

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,21 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13-
# import os
14-
# import sys
15-
# import tarfile
16-
#
17-
# lib_dir = '/opt/ml/lib'
18-
#
19-
# if not os.path.exists(lib_dir):
20-
# os.makedirs(lib_dir)
21-
#
22-
# with tarfile.open(name=os.path.join(os.path.dirname(__file__), 'opt_ml_lib.tar.gz'), mode='r:gz') as t:
23-
# t.extractall(path=lib_dir)
24-
#
25-
# sys.path.insert(0, lib_dir)
26-
2713
import alexa
14+
import json
15+
16+
MODEL = '/opt/ml/model/answer'
2817

2918

3019
def model_fn(anything):
31-
return alexa
20+
with open(MODEL) as model:
21+
return json.load(model)
3222

3323

3424
def predict_fn(input_object, model):
35-
return input_object
25+
return input_object + model
3626

3727

3828
if __name__ == '__main__':
39-
with open('/opt/ml/model/answer', 'w') as model:
40-
model.write(str(alexa.question('How many roads must a man walk down?')))
29+
with open(MODEL, 'w') as model:
30+
json.dump(alexa.question('How many roads must a man walk down?'), model)

tests/integ/test_source_dirs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ def test_source_dirs(sagemaker_session, tmpdir):
2525
with open(lib, 'w') as f:
2626
f.write('def question(to_anything): return 42')
2727

28-
estimator = PyTorch(entry_point='train.py', role='SageMakerRole', source_dir=source_dir, lib_dirs=[lib],
28+
estimator = PyTorch(entry_point='train.py', role='SageMakerRole', source_dir=source_dir, dependencies=[lib],
2929
py_version=PYTHON_VERSION, train_instance_count=1, train_instance_type='local')
3030
try:
3131

3232
estimator.fit()
3333

3434
predictor = estimator.deploy(initial_instance_count=1, instance_type='local')
3535

36-
predict_response = predictor.predict([24])
36+
predict_response = predictor.predict([7])
3737

38-
assert predict_response == [24]
38+
assert predict_response == [49]
3939
finally:
4040
estimator.delete_endpoint()

0 commit comments

Comments
 (0)