Skip to content

Commit 657faa4

Browse files
authored
feature: Remove unnecessary dependencies. (#44)
1 parent 1024411 commit 657faa4

34 files changed

+195
-635
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ __pycache__/
88
.DS_Store
99
**/*.pyc
1010
**.pyc
11+
**/*.tar.gz

setup.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,14 @@ def read(fname):
4747
'Programming Language :: Python :: 3.6',
4848
],
4949

50-
install_requires=['numpy==1.16.4', 'Pillow>=6.2.0', 'retrying==1.3.3', 'sagemaker-containers>=2.5.4',
51-
'six==1.12.0', 'requests_mock==1.6.0', 'sagemaker-inference>=1.2.2',
52-
'retrying==1.3.3'],
50+
# We don't declare our dependency on torch here because we build with
51+
# different packages for different variants
52+
install_requires=['numpy', 'retrying', 'sagemaker-inference>=1.2.2'],
5353
extras_require={
5454
'test': ['boto3==1.10.32', 'coverage==4.5.3', 'docker-compose==1.23.2', 'flake8==3.7.7', 'Flask==1.1.1',
5555
'mock==2.0.0', 'pytest==4.4.0', 'pytest-cov==2.7.1', 'pytest-xdist==1.28.0', 'PyYAML==3.10',
56-
'sagemaker==1.48.0', 'requests==2.20.0', 'torchvision==0.5.0', 'tox==3.7.0', 'requests_mock==1.6.0']
56+
'sagemaker==1.48.0', 'sagemaker-containers>=2.5.4', 'six==1.12.0', 'requests==2.20.0',
57+
'requests_mock==1.6.0', 'torch==1.4.0', 'torchvision==0.5.0', 'tox==3.7.0']
5758
},
5859

5960
entry_points={

test-toolkit/integration/__init__.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import os
1616

17+
from utils import file_utils
18+
1719
resources_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resources'))
1820
mnist_path = os.path.join(resources_path, 'mnist')
1921
data_dir = os.path.join(mnist_path, 'data')
@@ -24,14 +26,33 @@
2426

2527
model_cpu_dir = os.path.join(mnist_path, cpu_sub_dir)
2628
mnist_cpu_script = os.path.join(model_cpu_dir, 'mnist.py')
29+
model_cpu_tar = file_utils.make_tarfile(mnist_cpu_script,
30+
os.path.join(model_cpu_dir, "model.pth"),
31+
model_cpu_dir)
32+
2733
model_cpu_1d_dir = os.path.join(model_cpu_dir, '1d')
2834
mnist_1d_script = os.path.join(model_cpu_1d_dir, 'mnist_1d.py')
35+
model_cpu_1d_tar = file_utils.make_tarfile(mnist_1d_script,
36+
os.path.join(model_cpu_1d_dir, "model.pth"),
37+
model_cpu_1d_dir)
38+
2939
model_gpu_dir = os.path.join(mnist_path, gpu_sub_dir)
3040
mnist_gpu_script = os.path.join(model_gpu_dir, 'mnist.py')
31-
model_gpu_1d_dir = os.path.join(model_gpu_dir, '1d')
41+
model_gpu_tar = file_utils.make_tarfile(mnist_gpu_script,
42+
os.path.join(model_gpu_dir, "model.pth"),
43+
model_gpu_dir)
44+
3245
model_eia_dir = os.path.join(mnist_path, eia_sub_dir)
3346
mnist_eia_script = os.path.join(model_eia_dir, 'mnist.py')
47+
model_eia_tar = file_utils.make_tarfile(mnist_eia_script,
48+
os.path.join(model_eia_dir, "model.pth"),
49+
model_eia_dir)
50+
3451
call_model_fn_once_script = os.path.join(model_cpu_dir, 'call_model_fn_once.py')
52+
call_model_fn_once_tar = file_utils.make_tarfile(call_model_fn_once_script,
53+
os.path.join(model_cpu_dir, "model.pth"),
54+
model_cpu_dir,
55+
"model_call_model_fn_once.tar.gz")
3556

3657
ROLE = 'dummy/unused-role'
3758
DEFAULT_TIMEOUT = 20

test-toolkit/integration/local/test_serving.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
from sagemaker_containers.beta.framework import content_types
2626
from torchvision import datasets, transforms
2727

28-
from integration import training_dir, mnist_1d_script, model_cpu_dir, mnist_cpu_script, \
29-
model_gpu_dir, mnist_gpu_script, model_cpu_1d_dir, call_model_fn_once_script, ROLE
28+
from integration import training_dir, mnist_1d_script, model_cpu_tar, mnist_cpu_script, \
29+
model_gpu_tar, mnist_gpu_script, model_cpu_1d_tar, call_model_fn_once_script, ROLE, \
30+
call_model_fn_once_tar
3031
from utils import local_mode_utils
3132

3233
CONTENT_TYPE_TO_SERIALIZER_MAP = {
@@ -49,31 +50,31 @@ def fixture_test_loader():
4950

5051

5152
def test_serve_json_npy(test_loader, use_gpu, image_uri, sagemaker_local_session, instance_type):
52-
model_dir = model_gpu_dir if use_gpu else model_cpu_dir
53+
model_tar = model_gpu_tar if use_gpu else model_cpu_tar
5354
mnist_script = mnist_gpu_script if use_gpu else mnist_cpu_script
54-
with _predictor(model_dir, mnist_script, image_uri, sagemaker_local_session,
55+
with _predictor(model_tar, mnist_script, image_uri, sagemaker_local_session,
5556
instance_type) as predictor:
5657
for content_type in (content_types.JSON, content_types.NPY):
5758
for accept in (content_types.JSON, content_types.CSV, content_types.NPY):
5859
_assert_prediction_npy_json(predictor, test_loader, content_type, accept)
5960

6061

6162
def test_serve_csv(test_loader, use_gpu, image_uri, sagemaker_local_session, instance_type):
62-
with _predictor(model_cpu_1d_dir, mnist_1d_script, image_uri, sagemaker_local_session,
63+
with _predictor(model_cpu_1d_tar, mnist_1d_script, image_uri, sagemaker_local_session,
6364
instance_type) as predictor:
6465
for accept in (content_types.JSON, content_types.CSV, content_types.NPY):
6566
_assert_prediction_csv(predictor, test_loader, accept)
6667

6768

6869
@pytest.mark.skip_cpu
6970
def test_serve_cpu_model_on_gpu(test_loader, image_uri, sagemaker_local_session, instance_type):
70-
with _predictor(model_cpu_1d_dir, mnist_1d_script, image_uri, sagemaker_local_session,
71+
with _predictor(model_cpu_1d_tar, mnist_1d_script, image_uri, sagemaker_local_session,
7172
instance_type) as predictor:
7273
_assert_prediction_npy_json(predictor, test_loader, content_types.NPY, content_types.JSON)
7374

7475

7576
def test_serving_calls_model_fn_once(image_uri, sagemaker_local_session, instance_type):
76-
with _predictor(model_cpu_dir, call_model_fn_once_script, image_uri, sagemaker_local_session,
77+
with _predictor(call_model_fn_once_tar, call_model_fn_once_script, image_uri, sagemaker_local_session,
7778
instance_type, model_server_workers=2) as predictor:
7879
predictor.accept = None
7980
predictor.deserializer = BytesDeserializer()
@@ -86,9 +87,9 @@ def test_serving_calls_model_fn_once(image_uri, sagemaker_local_session, instanc
8687

8788

8889
@contextmanager
89-
def _predictor(model_dir, script, image, sagemaker_local_session, instance_type,
90+
def _predictor(model_tar, script, image, sagemaker_local_session, instance_type,
9091
model_server_workers=None):
91-
model = PyTorchModel('file://{}'.format(model_dir),
92+
model = PyTorchModel('file://{}'.format(model_tar),
9293
ROLE,
9394
script,
9495
image=image,

test-toolkit/integration/sagemaker/test_mnist.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,47 +12,43 @@
1212
# language governing permissions and limitations under the License.
1313
from __future__ import absolute_import
1414

15-
import os
16-
1715
import numpy as np
1816
import pytest
1917
import sagemaker
2018
from sagemaker.pytorch import PyTorchModel
2119

22-
from integration import model_cpu_dir, mnist_cpu_script, mnist_gpu_script, model_eia_dir, mnist_eia_script
20+
from integration import model_cpu_tar, model_gpu_tar, mnist_cpu_script, mnist_gpu_script, \
21+
model_eia_tar, mnist_eia_script
2322
from integration.sagemaker.timeout import timeout_and_delete_endpoint
2423

2524

2625
@pytest.mark.cpu_test
2726
def test_mnist_cpu(sagemaker_session, image_uri, instance_type):
2827
instance_type = instance_type or 'ml.c4.xlarge'
29-
model_dir = os.path.join(model_cpu_dir, 'model_mnist.tar.gz')
30-
_test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_dir, mnist_cpu_script)
28+
_test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_cpu_tar, mnist_cpu_script)
3129

3230

3331
@pytest.mark.gpu_test
3432
def test_mnist_gpu(sagemaker_session, image_uri, instance_type):
3533
instance_type = instance_type or 'ml.p2.xlarge'
36-
model_dir = os.path.join(model_cpu_dir, 'model_mnist.tar.gz')
37-
_test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_dir, mnist_gpu_script)
34+
_test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_gpu_tar, mnist_gpu_script)
3835

3936

4037
@pytest.mark.eia_test
4138
def test_mnist_eia(sagemaker_session, image_uri, instance_type, accelerator_type):
4239
instance_type = instance_type or 'ml.c4.xlarge'
4340
# Scripted model is serialized with torch.jit.save().
4441
# Inference test for EIA doesn't need to instantiate model definition then load state_dict
45-
model_dir = os.path.join(model_eia_dir, 'model_mnist.tar.gz')
46-
_test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_dir, mnist_eia_script,
42+
_test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_eia_tar, mnist_eia_script,
4743
accelerator_type=accelerator_type)
4844

4945

50-
def _test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_dir, mnist_script,
46+
def _test_mnist_distributed(sagemaker_session, image_uri, instance_type, model_tar, mnist_script,
5147
accelerator_type=None):
5248
endpoint_name = sagemaker.utils.unique_name_from_base("sagemaker-pytorch-serving")
5349

5450
model_data = sagemaker_session.upload_data(
55-
path=model_dir,
51+
path=model_tar,
5652
key_prefix="sagemaker-pytorch-serving/models",
5753
)
5854

-80.3 KB
Binary file not shown.
-80.1 KB
Binary file not shown.
-84 KB
Binary file not shown.

test-toolkit/resources/mnist/model_eia/mnist.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,39 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13-
# This file is intentionally left blank to utilize default_model_fn and default_predict_fn
13+
from __future__ import absolute_import
14+
import logging
15+
import os
16+
import sys
17+
18+
import torch
19+
20+
logger = logging.getLogger(__name__)
21+
logger.setLevel(logging.DEBUG)
22+
logger.addHandler(logging.StreamHandler(sys.stdout))
23+
24+
25+
def predict_fn(input_data, model):
26+
logger.info('Performing EIA inference with Torch JIT context with input of size {}'.format(input_data.shape))
27+
# With EI, client instance should be CPU for cost-efficiency. Subgraphs with unsupported arguments run locally. Server runs with CUDA
28+
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
29+
mdoel = model.to(device)
30+
input_data = input_data.to(device)
31+
with torch.no_grad():
32+
# Set the target device to the accelerator ordinal
33+
with torch.jit.optimized_execution(True, {'target_device': 'eia:0'}):
34+
return model(input_data)
35+
36+
37+
def model_fn(model_dir):
38+
logger.info('model_fn: Loading model with TorchScript from {}'.format(model_dir))
39+
# Scripted model is serialized with torch.jit.save().
40+
# No need to instantiate model definition then load state_dict
41+
model = torch.jit.load('model.pth')
42+
return model
43+
44+
45+
def save_model(model, model_dir):
46+
logger.info("Saving the model to {}.".format(model_dir))
47+
path = os.path.join(model_dir, 'model.pth')
48+
torch.jit.save(model, path)
139 KB
Binary file not shown.

0 commit comments

Comments
 (0)