Skip to content

doc: update TF documentation to reflect breaking changes and how to upgrade #1547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/frameworks/rl/using_rl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ which was run when you called ``fit``. This was the model you saved to ``model_d
In case if ``image_name`` was specified it would use provided image for the deployment.

``deploy`` returns a ``sagemaker.mxnet.MXNetPredictor`` for MXNet or
``sagemaker.tensorflow.serving.Predictor`` for TensorFlow.
``sagemaker.tensorflow.TensorFlowPredictor`` for TensorFlow.

``predict`` returns the result of inference against your model.

Expand All @@ -241,7 +241,7 @@ In case if ``image_name`` was specified it would use provided image for the depl
response = predictor.predict(data)

For more information please see `The SageMaker MXNet Model Server <https://sagemaker.readthedocs.io/en/stable/using_mxnet.html#the-sagemaker-mxnet-model-server>`_
and `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ documentation.
and `Deploying to TensorFlow Serving Endpoints <deploying_tensorflow_serving.html>`_ documentation.


Working with Existing Training Jobs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,19 @@ If you already have existing model artifacts in S3, you can skip training and de

.. code:: python

from sagemaker.tensorflow.serving import Model
from sagemaker.tensorflow import TensorFlowModel

model = Model(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')

predictor = model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge')

Python-based TensorFlow serving on SageMaker has support for `Elastic Inference <https://docs.aws.amazon.com/sagemaker/latest/dg/ei.html>`__, which allows for inference acceleration to a hosted endpoint for a fraction of the cost of using a full GPU instance. In order to attach an Elastic Inference accelerator to your endpoint provide the accelerator type to accelerator_type to your deploy call.

.. code:: python

from sagemaker.tensorflow.serving import Model
from sagemaker.tensorflow import TensorFlowModel

model = Model(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')
model = TensorFlowModel(model_data='s3://mybucket/model.tar.gz', role='MySageMakerRole')

predictor = model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge', accelerator_type='ml.eia1.medium')

Expand Down Expand Up @@ -276,7 +276,7 @@ This customized Python code must be named ``inference.py`` and specified through

.. code::

from sagemaker.tensorflow.serving import Model
from sagemaker.tensorflow import TensorFlowModel

model = Model(entry_point='inference.py',
model_data='s3://mybucket/model.tar.gz',
Expand Down Expand Up @@ -429,7 +429,7 @@ processing. There are 2 ways to do this:

.. code::

from sagemaker.tensorflow.serving import Model
from sagemaker.tensorflow import TensorFlowModel

model = Model(entry_point='inference.py',
source_dir='source/directory',
Expand All @@ -447,7 +447,7 @@ processing. There are 2 ways to do this:

.. code::

from sagemaker.tensorflow.serving import Model
from sagemaker.tensorflow import TensorFlowModel

model = Model(entry_point='inference.py',
dependencies=['/path/to/folder/named/lib'],
Expand Down Expand Up @@ -546,7 +546,7 @@ For the remaining steps, let's return to python code using the SageMaker Python

.. code:: python

from sagemaker.tensorflow.serving import Model, Predictor
from sagemaker.tensorflow import TensorFlowModel, TensorFlowPredictor

# change this to the name or ARN of your SageMaker execution role
role = 'SageMakerRole'
Expand Down
6 changes: 4 additions & 2 deletions doc/frameworks/tensorflow/index.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#############################
##########
TensorFlow
#############################
##########

A managed environment for TensorFlow training and hosting on Amazon SageMaker

.. toctree::
:maxdepth: 1

using_tf
deploying_tensorflow_serving
upgrade_from_legacy

.. toctree::
:maxdepth: 2
Expand Down
254 changes: 254 additions & 0 deletions doc/frameworks/tensorflow/upgrade_from_legacy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
######################################
Upgrade from Legacy TensorFlow Support
######################################

With v2 of the SageMaker Python SDK, support for legacy SageMaker TensorFlow images has been deprecated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "v2" how we are officially designating this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to suggestions. "v2.0.0" is more precise (since that'll be the release version), or could do something like "SageMaker Python SDK v2" or "SageMaker Python SDK 2"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can punt on this for now. Let's make a point to revisit it.

This guide explains how to upgrade your SageMaker Python SDK usage.

For more information about using TensorFlow with the SageMaker Python SDK, see `Use TensorFlow with the SageMaker Python SDK <using_tf.html>`_.

.. contents::

********************************************
What Constitutes "Legacy TensorFlow Support"
********************************************

This guide is relevant if one of the following applies:

#. You are using TensorFlow versions 1.4-1.10
#. You are using TensorFlow versions 1.11-1.12 with Python 2, and

- you do *not* have ``script_mode=True`` when creating your estimator
- you are using ``sagemaker.tensorflow.model.TensorFlowModel`` and/or ``sagemaker.tensorflow.model.TensorFlowPredictor``

#. You are using a pre-built SageMaker image whose URI looks like ``520713654638.dkr.ecr.<region>.amazonaws.com/sagemaker-tensorflow:<tag>``

If one of the above applies, then keep reading.

**************
How to Upgrade
**************

We recommend that you use the latest supported version of TensorFlow because that's where we focus our development efforts.
For information about supported versions of TensorFlow, see the `AWS documentation <https://aws.amazon.com/releasenotes/available-deep-learning-containers-images>`_.

For general information about using TensorFlow with the SageMaker Python SDK, see `Use TensorFlow with the SageMaker Python SDK <using_tf.html>`_.

Training Script
===============

Newer versions of TensorFlow require your training script to be runnable as a command-line script, similar to what you might run outside of SageMaker. For more information, including how to adapt a locally-runnable script, see `Prepare a Training Script <using_tf.html#id1>`_.

In addition, your training script needs to save your model. If you have your own ``serving_input_fn`` implementation, then that can be passed to an exporter:

.. code:: python

import tensorflow as tf

exporter = tf.estimator.LatestExporter("Servo", serving_input_receiver_fn=serving_input_fn)

For an example of how to repackage your legacy TensorFlow training script for use with a newer version of TensorFlow,
see `this example notebook <https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-python-sdk/tensorflow_moving_from_framework_mode_to_script_mode/tensorflow_moving_from_framework_mode_to_script_mode.ipynb>`_.

Inference Script
================

Newer versions of TensorFlow Serving require a different format for the inference script. Some key differences:

- The script must be named ``inference.py``.
- ``input_fn`` has been replaced by ``input_handler``.
- ``output_fn`` has been replaced by ``output_handler``.

Like with the legacy versions, the pre-built SageMaker TensorFlow Serving images do have default implementations for pre- and post-processing.

For more information about implementing your own handlers, see `How to implement the pre- and/or post-processing handler(s) <using_tf.html#how-to-implement-the-pre-and-or-post-processing-handler-s>`_.

*****************************
Continue with Legacy Versions
*****************************

While not recommended, you can still use a legacy TensorFlow version with v2 of the SageMaker Python SDK.
In order to do so, you need to change how a few parameters are defined.

Training
========

When creating an estimator, v2 requires the following changes:

#. Explicitly specify the ECR image URI via ``image_name``.
To determine the URI, you can use :func:`sagemaker.fw_utils.create_image_uri`.
#. Specify ``model_dir=False``.
#. Use hyperparameters for ``training_steps``, ``evaluation_steps``, ``checkpoint_path``, and ``requirements_file``.

For example, if using TF 1.10.0 with an ml.m4.xlarge instance in us-west-2,
the difference in code would be as follows:

.. code:: python

from sagemaker.tensorflow import TensorFlow

# v1
estimator = TensorFlow(
...
source_dir="code",
framework_version="1.10.0",
train_instance_type="ml.m4.xlarge",
training_steps=100,
evaluation_steps=10,
checkpoint_path="s3://bucket/path",
requirements_file="requirements.txt",
)

# v2
estimator = TensorFlow(
...
source_dir="code",
framework_version="1.10.0",
train_instance_type="ml.m4.xlarge",
image_name="520713654638.dkr.ecr.us-west-2.amazonaws.com/sagemaker-tensorflow:1.10.0-cpu-py2",
hyperparameters={
"training_steps": 100,
"evaluation_steps": 10,
"checkpoint_path": "s3://bucket/path",
"sagemaker_requirements": "requirements.txt",
},
model_dir=False,
)

Requirements File with Training
-------------------------------

To provide a requirements file, define a hyperparameter named "sagemaker_requirements" that contains the relative path to the requirements file from ``source_dir``.

Inference
=========

Using a legacy TensorFlow version for endpoints and batch transform can be achieved with v2 of the SageMaker Python SDK with some minor changes to your code.

From an Estimator
-----------------

If you are starting with a training job, you can call :func:`sagemaker.estimator.EstimatorBase.deploy` or :func:`sagemaker.tensorflow.estimator.Estimator.transformer` from your estimator for inference.

To specify the number of model server workers, you need to set it through an environment variable named ``MODEL_SERVER_WORKERS``:

.. code:: python

# v1
estimator.deploy(..., model_server_workers=4)

# v2
estimator.deploy(..., env={"MODEL_SERVER_WORKERS": 4})

From a Trained Model
--------------------

If you are starting with a trained model, v2 requires the following changes:

#. Use the the :class:`sagemaker.model.FrameworkModel` class.
#. Explicitly specify the ECR image URI via ``image``.
To determine the URI, you can use :func:`sagemaker.fw_utils.create_image_uri`.
#. Use an environment variable for ``model_server_workers``.

For example, if using TF 1.10.0 with a CPU instance in us-west-2,
the difference in code would be as follows:

.. code:: python

# v1
from sagemaker.tensorflow import TensorFlowModel

model = TensorFlowModel(
...
py_version="py2",
framework_version="1.10.0",
model_server_workers=4,
)

# v2
from sagemaker.model import FrameworkModel

model = FrameworkModel(
...
image="520713654638.dkr.ecr.us-west-2.amazonaws.com/sagemaker-tensorflow:1.10.0-cpu-py2",
env={"MODEL_SERVER_WORKERS": 4},
)

Requirements File with Inference
--------------------------------

To provide a requirements file, define an environment variable named ``SAGEMAKER_REQUIREMENTS`` that contains the relative path to the requirements file from ``source_dir``.

From an estimator:

.. code:: python

# for an endpoint
estimator.deploy(..., env={"SAGEMAKER_REQUIREMENTS": "requirements.txt"})

# for batch transform
estimator.transformer(..., env={"SAGEMAKER_REQUIREMENTS": "requirements.txt"})

From a model:

.. code:: python

from sagemaker.model import FrameworkModel

model = FrameworkModel(
...
source_dir="code",
env={"SAGEMAKER_REQUIREMENTS": "requirements.txt"},
)


Predictors
----------

If you want to use your model for endpoints, then you can use the :class:`sagemaker.predictor.RealTimePredictor` class instead of the legacy ``sagemaker.tensorflow.TensorFlowPredictor`` class:

.. code:: python

from sagemaker.model import FrameworkModel
from sagemaker.predictor import RealTimePredictor

model = FrameworkModel(
...
predictor_cls=RealTimePredictor,
)

predictor = model.deploy(...)

If you are using protobuf prediction data, then you need to serialize and deserialize the data yourself.

For example:

.. code:: python

from google.protobuf import json_format
from protobuf_to_dict import protobuf_to_dict
from tensorflow.core.framework import tensor_pb2

# Serialize the prediction data
json_format.MessageToJson(data)

# Get the prediction result
result = predictor.predict(data)

# Deserialize the prediction result
protobuf_to_dict(json_format.Parse(result, tensor_pb2.TensorProto()))

Otherwise, you can use the serializers and deserialzers available in the SageMaker Python SDK or write your own.

For example, if you want to use JSON serialization and deserialization:

.. code:: python

from sagemaker.predictor import json_deserializer, json_serializer

predictor.content_type = "application/json"
predictor.serializer = json_serializer
predictor.accept = "application/json"
predictor.deserializer = json_deserializer

predictor.predict(data)
Loading