Skip to content

Commit dce2c12

Browse files
committed
CR
Use new inference containers for both uncompiled and compiled flows.
1 parent 3263d29 commit dce2c12

File tree

5 files changed

+99
-175
lines changed

5 files changed

+99
-175
lines changed

sagemaker_neo_compilation_jobs/pytorch_torchvision/pytorch_torchvision_neo.ipynb

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,6 @@
158158
" )"
159159
]
160160
},
161-
{
162-
"cell_type": "code",
163-
"execution_count": null,
164-
"metadata": {},
165-
"outputs": [],
166-
"source": [
167-
"# TODO(kkoppolu): Delete after new SDK version sets the image URI correctly\n",
168-
"compiled_model.image_uri = compiled_model.image_uri.replace(\"neo\", \"inference\")"
169-
]
170-
},
171161
{
172162
"cell_type": "markdown",
173163
"metadata": {},
@@ -251,13 +241,6 @@
251241
"source": [
252242
"sess.delete_endpoint(predictor.endpoint_name)"
253243
]
254-
},
255-
{
256-
"cell_type": "code",
257-
"execution_count": null,
258-
"metadata": {},
259-
"outputs": [],
260-
"source": []
261244
}
262245
],
263246
"metadata": {

sagemaker_neo_compilation_jobs/pytorch_vgg19_bn/code/vgg19_bn.py renamed to sagemaker_neo_compilation_jobs/pytorch_vgg19_bn/code/vgg19_bn_compiled.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def transform_fn(model, payload, request_content_type,
4646
result = model.forward(batchified)
4747

4848
# Softmax (assumes batch size 1)
49-
result = np.squeeze(result.cpu().numpy())
49+
result = np.squeeze(result.cpu().detach().numpy())
5050
result_exp = np.exp(result - np.max(result))
5151
result = result_exp / np.sum(result_exp)
5252

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import io
2+
import json
3+
import logging
4+
import os
5+
import pickle
6+
7+
import numpy as np
8+
import torch
9+
import torchvision.transforms as transforms
10+
from PIL import Image # Training container doesn't have this package
11+
12+
logger = logging.getLogger(__name__)
13+
logger.setLevel(logging.DEBUG)
14+
15+
16+
# ------------------------------------------------------------ #
17+
# Neo host methods #
18+
# ------------------------------------------------------------ #
19+
20+
def transform_fn(model, payload, request_content_type,
21+
response_content_type):
22+
23+
logger.info('Invoking user-defined transform function')
24+
25+
if request_content_type != 'application/octet-stream':
26+
raise RuntimeError(
27+
'Content type must be application/octet-stream. Provided: {0}'.format(request_content_type))
28+
29+
# preprocess
30+
decoded = Image.open(io.BytesIO(payload))
31+
preprocess = transforms.Compose([
32+
transforms.Resize(256),
33+
transforms.CenterCrop(224),
34+
transforms.ToTensor(),
35+
transforms.Normalize(
36+
mean=[
37+
0.485, 0.456, 0.406], std=[
38+
0.229, 0.224, 0.225]),
39+
])
40+
normalized = preprocess(decoded)
41+
batchified = normalized.unsqueeze(0)
42+
43+
# predict
44+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
45+
batchified = batchified.to(device)
46+
result = model.forward(batchified)
47+
48+
# Softmax (assumes batch size 1)
49+
result = np.squeeze(result.cpu().detach().numpy())
50+
result_exp = np.exp(result - np.max(result))
51+
result = result_exp / np.sum(result_exp)
52+
53+
response_body = json.dumps(result.tolist())
54+
content_type = 'application/json'
55+
56+
return response_body, content_type
57+
58+
59+
# ------------------------------------------------------------ #
60+
# Sagemaker Hosting methods #
61+
# ------------------------------------------------------------ #
62+
63+
64+
def model_fn(model_dir):
65+
66+
logger.info('model_fn')
67+
with torch.neo.config(model_dir=model_dir, neo_runtime=True):
68+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
69+
# The compiled model is saved as "compiled.pt"
70+
model = torch.jit.load(os.path.join(model_dir, 'model.pth'))
71+
model = model.to(device)
72+
73+
return model

sagemaker_neo_compilation_jobs/pytorch_vgg19_bn/pytorch-vgg19-bn.ipynb

Lines changed: 25 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
"import sagemaker\n",
9494
"import time\n",
9595
"from sagemaker.utils import name_from_base\n",
96+
"from sagemaker import image_uris\n",
9697
"\n",
9798
"role = sagemaker.get_execution_role()\n",
9899
"sess = sagemaker.Session()\n",
@@ -106,9 +107,11 @@
106107
"\n",
107108
"data_shape = '{\"input0\":[1,3,224,224]}'\n",
108109
"target_device = 'ml_c5'\n",
109-
"framework = 'PYTORCH'\n",
110-
"framework_version = '1.2.0'\n",
111-
"compiled_model_path = 's3://{}/{}/output'.format(bucket, compilation_job_name)"
110+
"framework = 'pytorch'\n",
111+
"framework_version = '1.4.0'\n",
112+
"compiled_model_path = 's3://{}/{}/output'.format(bucket, compilation_job_name)\n",
113+
"\n",
114+
"inference_image_uri = image_uris.retrieve(f'neo-{framework}', region, framework_version, instance_type=target_device)"
112115
]
113116
},
114117
{
@@ -125,13 +128,17 @@
125128
"outputs": [],
126129
"source": [
127130
"from sagemaker.pytorch.model import PyTorchModel\n",
131+
"from sagemaker.predictor import Predictor\n",
128132
"\n",
129133
"pt_vgg = PyTorchModel(model_data=model_path,\n",
130134
" framework_version=framework_version,\n",
131-
" role=role, \n",
132-
" entry_point='vgg19_bn_old.py',\n",
135+
" predictor_cls=Predictor,\n",
136+
" role=role, \n",
133137
" sagemaker_session=sess,\n",
134-
" py_version='py3'\n",
138+
" entry_point='vgg19_bn_uncompiled.py',\n",
139+
" source_dir='code',\n",
140+
" py_version='py3',\n",
141+
" image_uri=inference_image_uri\n",
135142
" )"
136143
]
137144
},
@@ -176,7 +183,7 @@
176183
"cell_type": "markdown",
177184
"metadata": {},
178185
"source": [
179-
"#### Image Pre-processing"
186+
"#### Read the image payload"
180187
]
181188
},
182189
{
@@ -185,19 +192,11 @@
185192
"metadata": {},
186193
"outputs": [],
187194
"source": [
188-
"import torch\n",
189-
"from PIL import Image\n",
190-
"from torchvision import transforms\n",
191-
"import numpy as np\n",
192-
"input_image = Image.open('cat.jpg')\n",
193-
"preprocess = transforms.Compose([\n",
194-
" transforms.Resize(256),\n",
195-
" transforms.CenterCrop(224),\n",
196-
" transforms.ToTensor(),\n",
197-
" transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n",
198-
"])\n",
199-
"input_tensor = preprocess(input_image)\n",
200-
"input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model"
195+
"import json\n",
196+
"\n",
197+
"with open('cat.jpg', 'rb') as f:\n",
198+
" payload = f.read()\n",
199+
" payload = bytearray(payload) "
201200
]
202201
},
203202
{
@@ -216,7 +215,7 @@
216215
"import time\n",
217216
"start = time.time()\n",
218217
"for _ in range(1000):\n",
219-
" output = vgg_predictor.predict(input_batch)\n",
218+
" output = vgg_predictor.predict(payload)\n",
220219
"inference_time = (time.time()-start)\n",
221220
"print('Inference time is ' + str(inference_time) + 'millisecond')"
222221
]
@@ -227,7 +226,9 @@
227226
"metadata": {},
228227
"outputs": [],
229228
"source": [
230-
"_, predicted = torch.max(torch.from_numpy(np.array(output)), 1)"
229+
"import numpy as np\n",
230+
"result = json.loads(output.decode())\n",
231+
"predicted = np.argmax(result)"
231232
]
232233
},
233234
{
@@ -250,7 +251,7 @@
250251
"metadata": {},
251252
"outputs": [],
252253
"source": [
253-
"print(\"Result: label - \" + object_categories[str(predicted.item())])"
254+
"print(\"Result: label - \" + object_categories[str(predicted)])"
254255
]
255256
},
256257
{
@@ -277,39 +278,6 @@
277278
"## Neo optimization"
278279
]
279280
},
280-
{
281-
"cell_type": "markdown",
282-
"metadata": {},
283-
"source": [
284-
"### Update framework version"
285-
]
286-
},
287-
{
288-
"cell_type": "code",
289-
"execution_count": null,
290-
"metadata": {},
291-
"outputs": [],
292-
"source": [
293-
"framework_version = '1.4.0'"
294-
]
295-
},
296-
{
297-
"cell_type": "markdown",
298-
"metadata": {},
299-
"source": [
300-
"### Re-create the model archive"
301-
]
302-
},
303-
{
304-
"cell_type": "code",
305-
"execution_count": null,
306-
"metadata": {},
307-
"outputs": [],
308-
"source": [
309-
"with tarfile.open('model.tar.gz', 'w:gz') as f:\n",
310-
" f.add('model.pth')"
311-
]
312-
},
313281
{
314282
"cell_type": "markdown",
315283
"metadata": {},
@@ -331,7 +299,7 @@
331299
" framework_version = framework_version,\n",
332300
" role=role,\n",
333301
" sagemaker_session=sess,\n",
334-
" entry_point='vgg19_bn.py',\n",
302+
" entry_point='vgg19_bn_compiled.py',\n",
335303
" source_dir='code',\n",
336304
" py_version='py3',\n",
337305
" env={'MMS_DEFAULT_RESPONSE_TIMEOUT': '500'}\n",
@@ -361,16 +329,6 @@
361329
" )"
362330
]
363331
},
364-
{
365-
"cell_type": "code",
366-
"execution_count": null,
367-
"metadata": {},
368-
"outputs": [],
369-
"source": [
370-
"# TODO(kkoppolu): Delete after new SDK version sets the image URI correctly\n",
371-
"compiled_model.image_uri = compiled_model.image_uri.replace(\"neo\", \"inference\")"
372-
]
373-
},
374332
{
375333
"cell_type": "code",
376334
"execution_count": null,
@@ -382,19 +340,6 @@
382340
" )"
383341
]
384342
},
385-
{
386-
"cell_type": "code",
387-
"execution_count": null,
388-
"metadata": {},
389-
"outputs": [],
390-
"source": [
391-
"import json\n",
392-
"\n",
393-
"with open('cat.jpg', 'rb') as f:\n",
394-
" payload = f.read()\n",
395-
" payload = bytearray(payload) "
396-
]
397-
},
398343
{
399344
"cell_type": "markdown",
400345
"metadata": {},
@@ -435,13 +380,6 @@
435380
"source": [
436381
"sess.delete_endpoint(predictor.endpoint_name)"
437382
]
438-
},
439-
{
440-
"cell_type": "code",
441-
"execution_count": null,
442-
"metadata": {},
443-
"outputs": [],
444-
"source": []
445383
}
446384
],
447385
"metadata": {

sagemaker_neo_compilation_jobs/pytorch_vgg19_bn/vgg19_bn_old.py

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)