Skip to content

Commit 09aa5b0

Browse files
authored
Merge branch 'master' into amtviz
2 parents 24c21bd + aa00d6d commit 09aa5b0

27 files changed

+341
-146
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## v2.239.2 (2025-02-18)
4+
5+
### Bug Fixes and Other Changes
6+
7+
* Add warning about not supporting torch.nn.SyncBatchNorm
8+
* pass in inference_ami_version to model_based endpoint type
9+
* Fix hyperparameter strategy docs
10+
* Add framework_version to all TensorFlowModel examples
11+
* Move RecordSerializer and RecordDeserializer to sagemaker.serializers and sagemaker.deserialzers
12+
313
## v2.239.1 (2025-02-14)
414

515
### Bug Fixes and Other Changes

CONTRIBUTING.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ Before sending us a pull request, please ensure that:
6161
1. Follow the instructions at [Modifying an EBS Volume Using Elastic Volumes (Console)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/requesting-ebs-volume-modifications.html#modify-ebs-volume) to increase the EBS volume size associated with the newly created EC2 instance.
6262
1. Wait 5-10min for the new EBS volume increase to finalize.
6363
1. Allow EC2 to claim the additional space by stopping and then starting your EC2 host.
64+
2. Set up a venv to manage dependencies:
65+
1. `python -m venv ~/.venv/myproject-env` to create the venv
66+
2. `source ~/.venv/myproject-env/bin/activate` to activate the venv
67+
3. `deactivate` to exit the venv
6468

6569

6670
### Pull Down the Code
@@ -74,8 +78,8 @@ Before sending us a pull request, please ensure that:
7478
### Run the Unit Tests
7579

7680
1. Install tox using `pip install tox`
77-
1. Install coverage using `pip install .[test]`
78-
1. cd into the sagemaker-python-sdk folder: `cd sagemaker-python-sdk` or `cd /environment/sagemaker-python-sdk`
81+
1. cd into the github project sagemaker-python-sdk folder: `cd sagemaker-python-sdk` or `cd /environment/sagemaker-python-sdk`
82+
1. Install coverage using `pip install '.[test]'`
7983
1. Run the following tox command and verify that all code checks and unit tests pass: `tox tests/unit`
8084
1. You can also run a single test with the following command: `tox -e py310 -- -s -vv <path_to_file><file_name>::<test_function_name>`
8185
1. You can run coverage via runcvoerage env : `tox -e runcoverage -- tests/unit` or `tox -e py310 -- tests/unit --cov=sagemaker --cov-append --cov-report xml`

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.239.2.dev0
1+
2.239.3.dev0

doc/frameworks/pytorch/using_pytorch.rst

+3
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,9 @@ To initialize distributed training in your script, call
375375
`torch.distributed.init_process_group
376376
<https://pytorch.org/docs/master/distributed.html#torch.distributed.init_process_group>`_
377377
with the desired backend and the rank of the current host.
378+
Warning: Some torch features, such as (and likely not limited to) ``torch.nn.SyncBatchNorm``
379+
is not supported and its existence in ``init_process_group`` will cause an exception during
380+
distributed training.
378381
379382
.. code:: python
380383

doc/frameworks/tensorflow/deploying_tensorflow_serving.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ If you already have existing model artifacts in S3, you can skip training and de
6464
6565
from sagemaker.tensorflow import TensorFlowModel
6666
67-
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')
67+
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole', framework_version='x.x.x')
6868
6969
predictor = model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge')
7070
@@ -74,7 +74,7 @@ Python-based TensorFlow serving on SageMaker has support for `Elastic Inference
7474
7575
from sagemaker.tensorflow import TensorFlowModel
7676
77-
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')
77+
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole', framework_version='x.x.x')
7878
7979
predictor = model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge', accelerator_type='ml.eia1.medium')
8080

doc/frameworks/tensorflow/using_tf.rst

+8-5
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ If you already have existing model artifacts in S3, you can skip training and de
468468
469469
from sagemaker.tensorflow import TensorFlowModel
470470
471-
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')
471+
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole', framework_version='x.x.x')
472472
473473
predictor = model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge')
474474
@@ -478,7 +478,7 @@ Python-based TensorFlow serving on SageMaker has support for `Elastic Inference
478478
479479
from sagemaker.tensorflow import TensorFlowModel
480480
481-
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')
481+
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole', framework_version='x.x.x')
482482
483483
predictor = model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge', accelerator_type='ml.eia1.medium')
484484
@@ -767,7 +767,8 @@ This customized Python code must be named ``inference.py`` and is specified thro
767767
768768
model = TensorFlowModel(entry_point='inference.py',
769769
model_data='s3://mybucket/model.tar.gz',
770-
role='MySageMakerRole')
770+
role='MySageMakerRole',
771+
framework_version='x.x.x')
771772
772773
In the example above, ``inference.py`` is assumed to be a file inside ``model.tar.gz``. If you want to use a local file instead, you must add the ``source_dir`` argument. See the documentation on `TensorFlowModel <https://sagemaker.readthedocs.io/en/stable/frameworks/tensorflow/sagemaker.tensorflow.html#sagemaker.tensorflow.model.TensorFlowModel>`_.
773774

@@ -923,7 +924,8 @@ processing. There are 2 ways to do this:
923924
model = TensorFlowModel(entry_point='inference.py',
924925
dependencies=['requirements.txt'],
925926
model_data='s3://mybucket/model.tar.gz',
926-
role='MySageMakerRole')
927+
role='MySageMakerRole',
928+
framework_version='x.x.x')
927929
928930
929931
2. If you are working in a network-isolation situation or if you don't
@@ -941,7 +943,8 @@ processing. There are 2 ways to do this:
941943
model = TensorFlowModel(entry_point='inference.py',
942944
dependencies=['/path/to/folder/named/lib'],
943945
model_data='s3://mybucket/model.tar.gz',
944-
role='MySageMakerRole')
946+
role='MySageMakerRole',
947+
framework_version='x.x.x')
945948
946949
For more information, see: https://github.com/aws/sagemaker-tensorflow-serving-container#prepost-processing
947950

doc/v2.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,9 @@ The follow serializer/deserializer classes have been renamed and/or moved:
324324
+--------------------------------------------------------+-------------------------------------------------------+
325325
| ``sagemaker.predictor._NPYSerializer`` | ``sagemaker.serializers.NumpySerializer`` |
326326
+--------------------------------------------------------+-------------------------------------------------------+
327-
| ``sagemaker.amazon.common.numpy_to_record_serializer`` | ``sagemaker.amazon.common.RecordSerializer`` |
327+
| ``sagemaker.amazon.common.numpy_to_record_serializer`` | ``sagemaker.serializers.RecordSerializer`` |
328328
+--------------------------------------------------------+-------------------------------------------------------+
329-
| ``sagemaker.amazon.common.record_deserializer`` | ``sagemaker.amazon.common.RecordDeserializer`` |
329+
| ``sagemaker.amazon.common.record_deserializer`` | ``sagemaker.deserializers.RecordDeserializer`` |
330330
+--------------------------------------------------------+-------------------------------------------------------+
331331
| ``sagemaker.predictor._JsonDeserializer`` | ``sagemaker.deserializers.JSONDeserializer`` |
332332
+--------------------------------------------------------+-------------------------------------------------------+

src/sagemaker/amazon/common.py

-72
Original file line numberDiff line numberDiff line change
@@ -13,84 +13,16 @@
1313
"""Placeholder docstring"""
1414
from __future__ import absolute_import
1515

16-
import io
1716
import logging
1817
import struct
1918
import sys
2019

2120
import numpy as np
2221

2322
from sagemaker.amazon.record_pb2 import Record
24-
from sagemaker.deprecations import deprecated_class
25-
from sagemaker.deserializers import SimpleBaseDeserializer
26-
from sagemaker.serializers import SimpleBaseSerializer
2723
from sagemaker.utils import DeferredError
2824

2925

30-
class RecordSerializer(SimpleBaseSerializer):
31-
"""Serialize a NumPy array for an inference request."""
32-
33-
def __init__(self, content_type="application/x-recordio-protobuf"):
34-
"""Initialize a ``RecordSerializer`` instance.
35-
36-
Args:
37-
content_type (str): The MIME type to signal to the inference endpoint when sending
38-
request data (default: "application/x-recordio-protobuf").
39-
"""
40-
super(RecordSerializer, self).__init__(content_type=content_type)
41-
42-
def serialize(self, data):
43-
"""Serialize a NumPy array into a buffer containing RecordIO records.
44-
45-
Args:
46-
data (numpy.ndarray): The data to serialize.
47-
48-
Returns:
49-
io.BytesIO: A buffer containing the data serialized as records.
50-
"""
51-
if len(data.shape) == 1:
52-
data = data.reshape(1, data.shape[0])
53-
54-
if len(data.shape) != 2:
55-
raise ValueError(
56-
"Expected a 1D or 2D array, but got a %dD array instead." % len(data.shape)
57-
)
58-
59-
buffer = io.BytesIO()
60-
write_numpy_to_dense_tensor(buffer, data)
61-
buffer.seek(0)
62-
63-
return buffer
64-
65-
66-
class RecordDeserializer(SimpleBaseDeserializer):
67-
"""Deserialize RecordIO Protobuf data from an inference endpoint."""
68-
69-
def __init__(self, accept="application/x-recordio-protobuf"):
70-
"""Initialize a ``RecordDeserializer`` instance.
71-
72-
Args:
73-
accept (union[str, tuple[str]]): The MIME type (or tuple of allowable MIME types) that
74-
is expected from the inference endpoint (default:
75-
"application/x-recordio-protobuf").
76-
"""
77-
super(RecordDeserializer, self).__init__(accept=accept)
78-
79-
def deserialize(self, data, content_type):
80-
"""Deserialize RecordIO Protobuf data from an inference endpoint.
81-
82-
Args:
83-
data (object): The protobuf message to deserialize.
84-
content_type (str): The MIME type of the data.
85-
Returns:
86-
list: A list of records.
87-
"""
88-
try:
89-
return read_records(data)
90-
finally:
91-
data.close()
92-
93-
9426
def _write_feature_tensor(resolved_type, record, vector):
9527
"""Placeholder Docstring"""
9628
if resolved_type == "Int32":
@@ -288,7 +220,3 @@ def _resolve_type(dtype):
288220
if dtype == np.dtype("float32"):
289221
return "Float32"
290222
raise ValueError("Unsupported dtype {} on array".format(dtype))
291-
292-
293-
numpy_to_record_serializer = deprecated_class(RecordSerializer, "numpy_to_record_serializer")
294-
record_deserializer = deprecated_class(RecordDeserializer, "record_deserializer")

src/sagemaker/amazon/factorization_machines.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
from sagemaker import image_uris
1919
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
20-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
2120
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2221
from sagemaker.amazon.validation import gt, isin, ge
22+
from sagemaker.deserializers import RecordDeserializer
2323
from sagemaker.predictor import Predictor
2424
from sagemaker.model import Model
25+
from sagemaker.serializers import RecordSerializer
2526
from sagemaker.session import Session
2627
from sagemaker.utils import pop_out_unused_kwarg
2728
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/kmeans.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
from sagemaker import image_uris
1919
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
20-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
2120
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2221
from sagemaker.amazon.validation import gt, isin, ge, le
22+
from sagemaker.deserializers import RecordDeserializer
2323
from sagemaker.predictor import Predictor
2424
from sagemaker.model import Model
25+
from sagemaker.serializers import RecordSerializer
2526
from sagemaker.session import Session
2627
from sagemaker.utils import pop_out_unused_kwarg
2728
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/knn.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
from sagemaker import image_uris
1919
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
20-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
2120
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2221
from sagemaker.amazon.validation import ge, isin
22+
from sagemaker.deserializers import RecordDeserializer
2323
from sagemaker.predictor import Predictor
2424
from sagemaker.model import Model
25+
from sagemaker.serializers import RecordSerializer
2526
from sagemaker.session import Session
2627
from sagemaker.utils import pop_out_unused_kwarg
2728
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/lda.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818

1919
from sagemaker import image_uris
2020
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
21-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
21+
from sagemaker.deserializers import RecordDeserializer
2222
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2323
from sagemaker.amazon.validation import gt
2424
from sagemaker.predictor import Predictor
2525
from sagemaker.model import Model
26+
from sagemaker.serializers import RecordSerializer
2627
from sagemaker.session import Session
2728
from sagemaker.utils import pop_out_unused_kwarg
2829
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/linear_learner.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818

1919
from sagemaker import image_uris
2020
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
21-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
21+
from sagemaker.deserializers import RecordDeserializer
2222
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2323
from sagemaker.amazon.validation import isin, gt, lt, ge, le
2424
from sagemaker.predictor import Predictor
2525
from sagemaker.model import Model
26+
from sagemaker.serializers import RecordSerializer
2627
from sagemaker.session import Session
2728
from sagemaker.utils import pop_out_unused_kwarg
2829
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/ntm.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
from sagemaker import image_uris
1919
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
20-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
2120
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2221
from sagemaker.amazon.validation import ge, le, isin
22+
from sagemaker.deserializers import RecordDeserializer
2323
from sagemaker.predictor import Predictor
2424
from sagemaker.model import Model
25+
from sagemaker.serializers import RecordSerializer
2526
from sagemaker.session import Session
2627
from sagemaker.utils import pop_out_unused_kwarg
2728
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/pca.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
from sagemaker import image_uris
1919
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
20-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
2120
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2221
from sagemaker.amazon.validation import gt, isin
22+
from sagemaker.deserializers import RecordDeserializer
2323
from sagemaker.predictor import Predictor
2424
from sagemaker.model import Model
25+
from sagemaker.serializers import RecordSerializer
2526
from sagemaker.session import Session
2627
from sagemaker.utils import pop_out_unused_kwarg
2728
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/amazon/randomcutforest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
from sagemaker import image_uris
1919
from sagemaker.amazon.amazon_estimator import AmazonAlgorithmEstimatorBase
20-
from sagemaker.amazon.common import RecordSerializer, RecordDeserializer
2120
from sagemaker.amazon.hyperparameter import Hyperparameter as hp # noqa
2221
from sagemaker.amazon.validation import ge, le
22+
from sagemaker.deserializers import RecordDeserializer
2323
from sagemaker.predictor import Predictor
2424
from sagemaker.model import Model
25+
from sagemaker.serializers import RecordSerializer
2526
from sagemaker.session import Session
2627
from sagemaker.utils import pop_out_unused_kwarg
2728
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

src/sagemaker/base_deserializers.py

+29
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import numpy as np
2424
from six import with_metaclass
2525

26+
from sagemaker.amazon.common import read_records
2627
from sagemaker.utils import DeferredError
2728

2829
try:
@@ -388,3 +389,31 @@ def deserialize(self, stream, content_type="tensor/pt"):
388389
"Unable to deserialize your data to torch.Tensor.\
389390
Please provide custom deserializer in InferenceSpec."
390391
)
392+
393+
394+
class RecordDeserializer(SimpleBaseDeserializer):
395+
"""Deserialize RecordIO Protobuf data from an inference endpoint."""
396+
397+
def __init__(self, accept="application/x-recordio-protobuf"):
398+
"""Initialize a ``RecordDeserializer`` instance.
399+
400+
Args:
401+
accept (union[str, tuple[str]]): The MIME type (or tuple of allowable MIME types) that
402+
is expected from the inference endpoint (default:
403+
"application/x-recordio-protobuf").
404+
"""
405+
super(RecordDeserializer, self).__init__(accept=accept)
406+
407+
def deserialize(self, data, content_type):
408+
"""Deserialize RecordIO Protobuf data from an inference endpoint.
409+
410+
Args:
411+
data (object): The protobuf message to deserialize.
412+
content_type (str): The MIME type of the data.
413+
Returns:
414+
list: A list of records.
415+
"""
416+
try:
417+
return read_records(data)
418+
finally:
419+
data.close()

0 commit comments

Comments
 (0)