Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators

By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.

Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.

Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.

Expand Down
16 changes: 3 additions & 13 deletions doc/using_tf.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
estimator to create a SageMaker Endpoint.

SageMaker provides two different options for deploying TensorFlow models to a SageMaker
Endpoint:
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.

- The first option uses a Python-based server that allows you to specify your own custom
input and output handling functions in a Python script. This is the default option.

See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.


- The second option uses a TensorFlow Serving-based server to provide a super-set of the
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
does not require (or allow) a custom python script.

See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.


SageMaker TensorFlow Docker containers
Expand Down
199 changes: 0 additions & 199 deletions src/sagemaker/tensorflow/deploying_python.rst

This file was deleted.

21 changes: 17 additions & 4 deletions src/sagemaker/tensorflow/estimator.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@
from sagemaker.tensorflow.defaults import TF_VERSION
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.tensorflow.serving import Model
from sagemaker.utils import get_config_value
from sagemaker import utils
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT

logger = logging.getLogger("sagemaker")
Expand DownExpand Up@@ -190,9 +190,11 @@ class TensorFlow(Framework):

__framework_name__ = "tensorflow"

LATEST_VERSION = "1.12"
LATEST_VERSION = "1.13"
"""The latest version of TensorFlow included in the SageMaker pre-built Docker images."""

_LOWEST_SCRIPT_MODE_ONLY_VERSION = [1, 13]

def __init__(
self,
training_steps=None,
Expand DownExpand Up@@ -321,6 +323,17 @@ def _validate_args(
)
)

if (not self._script_mode_enabled()) and self._only_script_mode_supported():
logger.warning(
"Legacy mode is deprecated in versions 1.13 and higher. Using script mode instead."
)
self.script_mode = True

def _only_script_mode_supported(self):
return [
int(s) for s in self.framework_version.split(".")
] >= self._LOWEST_SCRIPT_MODE_ONLY_VERSION
Comment thread
mvsusp marked this conversation as resolved.

def _validate_requirements_file(self, requirements_file):
if not requirements_file:
return
Expand DownExpand Up@@ -489,7 +502,7 @@ def _create_tfs_model(self, role=None, vpc_config_override=VPC_CONFIG_DEFAULT):
image=self.image_name,
name=self._current_job_name,
container_log_level=self.container_log_level,
framework_version=self.framework_version,
framework_version=utils.get_short_version(self.framework_version),
sagemaker_session=self.sagemaker_session,
vpc_config=self.get_vpc_config(vpc_config_override),
)
Expand DownExpand Up@@ -553,7 +566,7 @@ def hyperparameters(self):
return hyperparameters

def _default_s3_path(self, directory, mpi=False):
local_code = get_config_value("local.local_code", self.sagemaker_session.config)
local_code = utils.get_config_value("local.local_code", self.sagemaker_session.config)
if self.sagemaker_session.local_mode and local_code:
return "/opt/ml/shared/{}".format(directory)
elif mpi:
Expand Down
12 changes: 12 additions & 0 deletions src/sagemaker/utils.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,18 @@ def get_config_value(key_path, config):
return current_section


def get_short_version(framework_version):
Comment thread
laurenyu marked this conversation as resolved.
"""Return short version in the format of x.x

Args:
framework_version: The version string to be shortened.

Returns:
str: The short version string
"""
return ".".join(framework_version.split(".")[:2])


def to_str(value):
"""Convert the input to a string, unless it is a unicode string in Python 2.

Expand Down
8 changes: 0 additions & 8 deletions tests/data/tensorflow_mnist/mnist.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,17 +14,11 @@

import argparse
import json
import logging as _logging
import numpy as np
import os
import sys as _sys
import tensorflow as tf
from tensorflow.python.platform import tf_logging

tf.logging.set_verbosity(tf.logging.DEBUG)
_handler = _logging.StreamHandler(_sys.stdout)
tf_logger = tf_logging._get_logger()
tf_logger.handlers = [_handler]


def cnn_model_fn(features, labels, mode):
Expand DownExpand Up@@ -179,5 +173,3 @@ def serving_input_fn():

if args.current_host == args.hosts[0]:
mnist_classifier.export_savedmodel("/opt/ml/model", serving_input_fn)

tf_logger.info("====== Training finished =========")
7 changes: 5 additions & 2 deletions tests/integ/test_local_mode.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,14 +85,14 @@ def _create_model(output_path):

@pytest.mark.local_mode
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
def test_tf_local_mode(tf_full_version, sagemaker_local_session):
def test_tf_local_mode(sagemaker_local_session):
with timeout(minutes=5):
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")

estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version=tf_full_version,
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -135,6 +135,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -176,6 +177,7 @@ def test_tf_local_data(sagemaker_local_session):
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand DownExpand Up@@ -216,6 +218,7 @@ def test_tf_local_data_local_script():
estimator = TensorFlow(
entry_point=script_path,
role="SageMakerRole",
framework_version="1.12",
training_steps=1,
evaluation_steps=1,
hyperparameters={"input_tensor_name": "inputs"},
Expand Down
Loading