

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS Neuron에서 DLAMI 사용
<a name="tutorial-inferentia-using"></a>

 AWS Neuron SDK의 일반적인 워크플로는 컴파일 서버에서 이전에 훈련된 기계 학습 모델을 컴파일하는 것입니다. 그런 다음 실행을 위해 아티팩트를 Inf1 인스턴스에 배포합니다. AWS Deep Learning AMIs (DLAMI)에는 Inferentia를 사용하는 Inf1 인스턴스에서 추론을 컴파일하고 실행하는 데 필요한 모든 것이 사전 설치되어 있습니다.

 다음 섹션에서는 Inferentia DLAMI를 사용하는 방법을 설명합니다.

**Topics**
+ [TensorFlow-Neuron 및 AWS Neuron 컴파일러 사용](tutorial-inferentia-tf-neuron.md)
+ [AWS Neuron TensorFlow Serving 사용](tutorial-inferentia-tf-neuron-serving.md)
+ [MXNet-Neuron 및 AWS Neuron 컴파일러 사용](tutorial-inferentia-mxnet-neuron.md)
+ [MXNet-Neuron 모델 제공 사용](tutorial-inferentia-mxnet-neuron-serving.md)
+ [PyTorch-Neuron 및 AWS Neuron 컴파일러 사용](tutorial-inferentia-pytorch-neuron.md)

# TensorFlow-Neuron 및 AWS Neuron 컴파일러 사용
<a name="tutorial-inferentia-tf-neuron"></a>

 이 자습서에서는 AWS Neuron 컴파일러를 사용하여 Keras ResNet-50 모델을 컴파일하고 SavedModel 형식으로 저장된 모델로 내보내는 방법을 보여줍니다. 이 형식은 일반 TensorFlow 모델에서 서로 바꿔 사용할 수 있는 형식입니다. 또한 예제 입력을 사용하여 Inf1 인스턴스에서 추론을 실행하는 방법을 알아봅니다.  

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/tensorflow-neuron/index.html)를 참조하세요.

**Topics**
+ [사전 조건](#tutorial-inferentia-tf-neuron-prerequisites)
+ [Conda 환경 활성화](#tutorial-inferentia-tf-neuron-activate)
+ [Resnet50 컴파일](#tutorial-inferentia-tf-neuron-compilation)
+ [ResNet50 추론](#tutorial-inferentia-tf-neuron-inference)

## 사전 조건
<a name="tutorial-inferentia-tf-neuron-prerequisites"></a>

 이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-tf-neuron-activate"></a>

 다음 명령을 사용하여 TensorFlow-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_tensorflow_p36
```

 현재 conda 환경을 종료하려면 다음 명령을 실행합니다.

```
source deactivate
```

## Resnet50 컴파일
<a name="tutorial-inferentia-tf-neuron-compilation"></a>

다음 콘텐츠를 가진 **tensorflow\$1compile\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 Python 스크립트는 Keras ResNet50 모델을 컴파일하고 저장된 모델로 내보냅니다.

```
import os
import time
import shutil
import tensorflow as tf
import tensorflow.neuron as tfn
import tensorflow.compat.v1.keras as keras
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.applications.resnet50 import preprocess_input

# Create a workspace
WORKSPACE = './ws_resnet50'
os.makedirs(WORKSPACE, exist_ok=True)

# Prepare export directory (old one removed)
model_dir = os.path.join(WORKSPACE, 'resnet50')
compiled_model_dir = os.path.join(WORKSPACE, 'resnet50_neuron')
shutil.rmtree(model_dir, ignore_errors=True)
shutil.rmtree(compiled_model_dir, ignore_errors=True)

# Instantiate Keras ResNet50 model
keras.backend.set_learning_phase(0)
model = ResNet50(weights='imagenet')

# Export SavedModel
tf.saved_model.simple_save(
 session            = keras.backend.get_session(),
 export_dir         = model_dir,
 inputs             = {'input': model.inputs[0]},
 outputs            = {'output': model.outputs[0]})

# Compile using Neuron
tfn.saved_model.compile(model_dir, compiled_model_dir)

# Prepare SavedModel for uploading to Inf1 instance
shutil.make_archive(compiled_model_dir, 'zip', WORKSPACE, 'resnet50_neuron')
```

 다음 명령을 사용하여 모델을 컴파일합니다.

```
python tensorflow_compile_resnet50.py
```

컴파일 프로세스는 몇 분 정도 걸립니다. 완료되면 출력은 다음과 같아야 합니다.

```
...
INFO:tensorflow:fusing subgraph neuron_op_d6f098c01c780733 with neuron-cc
INFO:tensorflow:Number of operations in TensorFlow session: 4638
INFO:tensorflow:Number of operations after tf.neuron optimizations: 556
INFO:tensorflow:Number of operations placed on Neuron runtime: 554
INFO:tensorflow:Successfully converted ./ws_resnet50/resnet50 to ./ws_resnet50/resnet50_neuron
...
```

 ​ 

 컴파일 후 저장된 모델은 **ws\$1resnet50/resnet50\$1neuron.zip**에서 압축됩니다. 다음 명령을 사용하여 모델의 압축을 풀고 추론을 위해 샘플 이미지를 다운로드합니다.

```
unzip ws_resnet50/resnet50_neuron.zip -d .
curl -O https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg
```

## ResNet50 추론
<a name="tutorial-inferentia-tf-neuron-inference"></a>

다음 콘텐츠를 가진 **tensorflow\$1infer\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 이전에 컴파일된 추론 모델을 사용하여 다운로드한 모델에 대한 추론을 실행합니다.

```
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications import resnet50

# Create input from image
img_sgl = image.load_img('kitten_small.jpg', target_size=(224, 224))
img_arr = image.img_to_array(img_sgl)
img_arr2 = np.expand_dims(img_arr, axis=0)
img_arr3 = resnet50.preprocess_input(img_arr2)
# Load model
COMPILED_MODEL_DIR = './ws_resnet50/resnet50_neuron/'
predictor_inferentia = tf.contrib.predictor.from_saved_model(COMPILED_MODEL_DIR)
# Run inference
model_feed_dict={'input': img_arr3}
infa_rslts = predictor_inferentia(model_feed_dict);
# Display results
print(resnet50.decode_predictions(infa_rslts["output"], top=5)[0])
```

 다음 명령을 사용하여 모델에 대한 추론을 실행합니다.

```
python tensorflow_infer_resnet50.py
```

 출력은 다음과 같아야 합니다.

```
...
[('n02123045', 'tabby', 0.6918919), ('n02127052', 'lynx', 0.12770271), ('n02123159', 'tiger_cat', 0.08277027), ('n02124075', 'Egyptian_cat', 0.06418919), ('n02128757', 'snow_leopard', 0.009290541)]
```

**다음 단계**  
[AWS Neuron TensorFlow Serving 사용](tutorial-inferentia-tf-neuron-serving.md)

# AWS Neuron TensorFlow Serving 사용
<a name="tutorial-inferentia-tf-neuron-serving"></a>

이 자습서에서는 TensorFlow Serving에 사용할 저장된 모델을 내보내기 전에 그래프를 구성하고 AWS Neuron 컴파일 단계를 추가하는 방법을 보여줍니다. TensorFlow Serving은 네트워크를 통해 추론을 확장할 수 있는 지원 시스템입니다. Neuron TensorFlow Serving은 일반적인 TensorFlow Serving과 동일한 API를 사용합니다. 유일한 차이점은 저장된 모델을 AWS Inferentia용으로 컴파일해야 하며 진입점은 라는 다른 바이너리라는 것입니다 `tensorflow_model_server_neuron`. 이진 파일은 `/usr/local/bin/tensorflow_model_server_neuron`에 있으며 DLAMI에 사전 설치되어 있습니다.

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/tensorflow-neuron/index.html)를 참조하세요.

**Topics**
+ [사전 조건](#tutorial-inferentia-tf-neuron--serving-prerequisites)
+ [Conda 환경 활성화](#tutorial-inferentia-tf-neuron-serving-activate)
+ [저장된 모델 컴파일 및 내보내기](#tutorial-inferentia-tf-neuron-serving-compile)
+ [저장된 모델 제공](#tutorial-inferentia-tf-neuron-serving-serving)
+ [모델 서버에 대한 추론 요청 생성](#tutorial-inferentia-tf-neuron-serving-inference)

## 사전 조건
<a name="tutorial-inferentia-tf-neuron--serving-prerequisites"></a>

이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-tf-neuron-serving-activate"></a>

 다음 명령을 사용하여 TensorFlow-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_tensorflow_p36
```

 현재 conda 환경을 종료해야 하는 경우 다음을 실행합니다.

```
source deactivate
```

## 저장된 모델 컴파일 및 내보내기
<a name="tutorial-inferentia-tf-neuron-serving-compile"></a>

다음 콘텐츠를 통해 `tensorflow-model-server-compile.py` 이름으로 Python 스크립트를 생성합니다. 이 스크립트는 그래프를 구성하고 Neuron을 사용하여 컴파일합니다. 그런 다음 컴파일된 그래프를 저장된 모델로 내보냅니다.  

```
import tensorflow as tf
import tensorflow.neuron
import os

tf.keras.backend.set_learning_phase(0)
model = tf.keras.applications.ResNet50(weights='imagenet')
sess = tf.keras.backend.get_session()
inputs = {'input': model.inputs[0]}
outputs = {'output': model.outputs[0]}

# save the model using tf.saved_model.simple_save
modeldir = "./resnet50/1"
tf.saved_model.simple_save(sess, modeldir, inputs, outputs)

# compile the model for Inferentia
neuron_modeldir = os.path.join(os.path.expanduser('~'), 'resnet50_inf1', '1')
tf.neuron.saved_model.compile(modeldir, neuron_modeldir, batch_size=1)
```

 다음 명령을 사용하여 모델을 컴파일합니다.

```
python tensorflow-model-server-compile.py
```

 출력은 다음과 같아야 합니다.

```
...
INFO:tensorflow:fusing subgraph neuron_op_d6f098c01c780733 with neuron-cc
INFO:tensorflow:Number of operations in TensorFlow session: 4638
INFO:tensorflow:Number of operations after tf.neuron optimizations: 556
INFO:tensorflow:Number of operations placed on Neuron runtime: 554
INFO:tensorflow:Successfully converted ./resnet50/1 to /home/ubuntu/resnet50_inf1/1
```

## 저장된 모델 제공
<a name="tutorial-inferentia-tf-neuron-serving-serving"></a>

모델이 컴파일되면 다음 명령을 사용하여 저장된 모델을 tensorflow\$1model\$1server\$1neuron 이진 파일로 제공할 수 있습니다.

```
tensorflow_model_server_neuron --model_name=resnet50_inf1 \
    --model_base_path=$HOME/resnet50_inf1/ --port=8500 &
```

 출력은 다음과 같아야 합니다. 컴파일된 모델은 추론을 준비하기 위해 서버에 의해 Inferentia 디바이스의 DRAM에 준비됩니다.

```
...
2019-11-22 01:20:32.075856: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:311] SavedModel load for tags { serve }; Status: success. Took 40764 microseconds.
2019-11-22 01:20:32.075888: I tensorflow_serving/servables/tensorflow/saved_model_warmup.cc:105] No warmup data file found at /home/ubuntu/resnet50_inf1/1/assets.extra/tf_serving_warmup_requests
2019-11-22 01:20:32.075950: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: resnet50_inf1 version: 1}
2019-11-22 01:20:32.077859: I tensorflow_serving/model_servers/server.cc:353] Running gRPC ModelServer at 0.0.0.0:8500 ...
```

## 모델 서버에 대한 추론 요청 생성
<a name="tutorial-inferentia-tf-neuron-serving-inference"></a>

다음 콘텐츠를 통해 `tensorflow-model-server-infer.py`라는 Python 스크립트를 생성합니다. 이 스크립트는 서비스 프레임워크인 gRPC를 통해 추론을 실행합니다.

```
import numpy as np
import grpc
import tensorflow as tf
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.resnet50 import preprocess_input
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
from tensorflow.keras.applications.resnet50 import decode_predictions

if __name__ == '__main__':
    channel = grpc.insecure_channel('localhost:8500')
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    img_file = tf.keras.utils.get_file(
        "./kitten_small.jpg",
        "https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg")
    img = image.load_img(img_file, target_size=(224, 224))
    img_array = preprocess_input(image.img_to_array(img)[None, ...])
    request = predict_pb2.PredictRequest()
    request.model_spec.name = 'resnet50_inf1'
    request.inputs['input'].CopyFrom(
        tf.contrib.util.make_tensor_proto(img_array, shape=img_array.shape))
    result = stub.Predict(request)
    prediction = tf.make_ndarray(result.outputs['output'])
    print(decode_predictions(prediction))
```

 다음 명령에서 gRPC를 사용하여 모델에 대한 추론을 실행합니다.

```
python tensorflow-model-server-infer.py
```

 출력은 다음과 같아야 합니다.

```
[[('n02123045', 'tabby', 0.6918919), ('n02127052', 'lynx', 0.12770271), ('n02123159', 'tiger_cat', 0.08277027), ('n02124075', 'Egyptian_cat', 0.06418919), ('n02128757', 'snow_leopard', 0.009290541)]]
```

# MXNet-Neuron 및 AWS Neuron 컴파일러 사용
<a name="tutorial-inferentia-mxnet-neuron"></a>

MXNet-Neuron 컴파일 API는 AWS Inferentia 디바이스에서 실행할 수 있는 모델 그래프를 컴파일하는 방법을 제공합니다.

 이 예에서는 API를 사용하여 ResNet-50 모델을 컴파일하고 추론을 실행하는 데 사용합니다.

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/mxnet-neuron/index.html)를 참조하세요.

**Topics**
+ [사전 조건](#tutorial-inferentia-mxnet-neuron-prerequisites)
+ [Conda 환경 활성화](#tutorial-inferentia-mxnet-neuron-activate)
+ [Resnet50 컴파일](#tutorial-inferentia-mxnet-neuron-compilation)
+ [ResNet50 추론](#tutorial-inferentia-mxnet-neuron-inference)

## 사전 조건
<a name="tutorial-inferentia-mxnet-neuron-prerequisites"></a>

 이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-mxnet-neuron-activate"></a>

 다음 명령을 사용하여 MXNet-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_mxnet_p36
```

현재 conda 환경을 종료하려면 다음을 실행합니다.

```
source deactivate
```

## Resnet50 컴파일
<a name="tutorial-inferentia-mxnet-neuron-compilation"></a>

다음 콘텐츠를 통해 **mxnet\$1compile\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 MXNet-Neuron 컴파일 Python API를 사용하여 ResNet-50 모델을 컴파일합니다.

```
import mxnet as mx
import numpy as np

print("downloading...")
path='http://data.mxnet.io/models/imagenet/'
mx.test_utils.download(path+'resnet/50-layers/resnet-50-0000.params')
mx.test_utils.download(path+'resnet/50-layers/resnet-50-symbol.json')
print("download finished.")

sym, args, aux = mx.model.load_checkpoint('resnet-50', 0)

print("compile for inferentia using neuron... this will take a few minutes...")
inputs = { "data" : mx.nd.ones([1,3,224,224], name='data', dtype='float32') }

sym, args, aux = mx.contrib.neuron.compile(sym, args, aux, inputs)

print("save compiled model...")
mx.model.save_checkpoint("compiled_resnet50", 0, sym, args, aux)
```

 다음 명령을 사용하여 모델을 컴파일합니다.

```
python mxnet_compile_resnet50.py
```

 컴파일이 끝날 때까지 몇 분 정도 소요될 수 있습니다. 컴파일이 완료되면 다음 파일이 현재 디렉터리에 저장됩니다.

```
resnet-50-0000.params
resnet-50-symbol.json
compiled_resnet50-0000.params
compiled_resnet50-symbol.json
```

## ResNet50 추론
<a name="tutorial-inferentia-mxnet-neuron-inference"></a>

다음 콘텐츠를 통해 **mxnet\$1infer\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 샘플 이미지를 다운로드하고 이를 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
import mxnet as mx
import numpy as np

path='http://data.mxnet.io/models/imagenet/'
mx.test_utils.download(path+'synset.txt')

fname = mx.test_utils.download('https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg')
img = mx.image.imread(fname)

# convert into format (batch, RGB, width, height)
img = mx.image.imresize(img, 224, 224) 
# resize
img = img.transpose((2, 0, 1)) 
# Channel first
img = img.expand_dims(axis=0) 
# batchify
img = img.astype(dtype='float32')

sym, args, aux = mx.model.load_checkpoint('compiled_resnet50', 0)
softmax = mx.nd.random_normal(shape=(1,))
args['softmax_label'] = softmax
args['data'] = img
# Inferentia context
ctx = mx.neuron()

exe = sym.bind(ctx=ctx, args=args, aux_states=aux, grad_req='null')
with open('synset.txt', 'r') as f:
    labels = [l.rstrip() for l in f]

exe.forward(data=img)
prob = exe.outputs[0].asnumpy()
# print the top-5
prob = np.squeeze(prob)
a = np.argsort(prob)[::-1] 
for i in a[0:5]:
    print('probability=%f, class=%s' %(prob[i], labels[i]))
```

 다음 명령을 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
python mxnet_infer_resnet50.py
```

 출력은 다음과 같아야 합니다.

```
probability=0.642454, class=n02123045 tabby, tabby cat
probability=0.189407, class=n02123159 tiger cat
probability=0.100798, class=n02124075 Egyptian cat
probability=0.030649, class=n02127052 lynx, catamount
probability=0.016278, class=n02129604 tiger, Panthera tigris
```

**다음 단계**  
[MXNet-Neuron 모델 제공 사용](tutorial-inferentia-mxnet-neuron-serving.md)

# MXNet-Neuron 모델 제공 사용
<a name="tutorial-inferentia-mxnet-neuron-serving"></a>

이 자습서에서는 사전 교육된 MXNet 모델을 사용하여 다중 모델 서버(MMS)로 실시간 이미지를 분류하는 방법을 알아봅니다. MMS는 기계 학습 또는 딥 러닝 프레임워크를 사용하여 교육 받은 딥 러닝 모델을 제공하기 위한 유연하고 사용하기 쉬운 도구입니다. 이 자습서에는 AWS Neuron을 사용한 컴파일 단계와 MXNet을 사용한 MMS 구현이 포함되어 있습니다.

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/mxnet-neuron/index.html)를 참조하세요.

**Topics**
+ [사전 조건](#tutorial-inferentia-mxnet-neuron-serving-prerequisites)
+ [Conda 환경 활성화](#tutorial-inferentia-mxnet-neuron-serving-activate)
+ [예제 코드 다운로드](#tutorial-inferentia-mxnet-neuron-serving-download)
+ [모델 컴파일](#tutorial-inferentia-mxnet-neuron-serving-compile)
+ [추론 실행](#tutorial-inferentia-mxnet-neuron-serving-inference)

## 사전 조건
<a name="tutorial-inferentia-mxnet-neuron-serving-prerequisites"></a>

 이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-mxnet-neuron-serving-activate"></a>

 다음 명령을 사용하여 MXNet-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_mxnet_p36
```

 현재 conda 환경을 종료하려면 다음을 실행합니다.

```
source deactivate
```

## 예제 코드 다운로드
<a name="tutorial-inferentia-mxnet-neuron-serving-download"></a>

 이 예제를 실행하려면 다음 명령을 사용하여 예제 코드를 다운로드합니다.

```
git clone https://github.com/awslabs/multi-model-server
cd multi-model-server/examples/mxnet_vision
```

## 모델 컴파일
<a name="tutorial-inferentia-mxnet-neuron-serving-compile"></a>

다음 콘텐츠를 통해 `multi-model-server-compile.py`라는 Python 스크립트를 생성합니다. 이 스크립트는 ResNet50 모델을 Inferentia 디바이스 대상으로 컴파일합니다.

```
import mxnet as mx
from mxnet.contrib import neuron
import numpy as np

path='http://data.mxnet.io/models/imagenet/'
mx.test_utils.download(path+'resnet/50-layers/resnet-50-0000.params')
mx.test_utils.download(path+'resnet/50-layers/resnet-50-symbol.json')
mx.test_utils.download(path+'synset.txt')

nn_name = "resnet-50"

#Load a model
sym, args, auxs = mx.model.load_checkpoint(nn_name, 0)

#Define compilation parameters#  - input shape and dtype
inputs = {'data' : mx.nd.zeros([1,3,224,224], dtype='float32') }

# compile graph to inferentia target
csym, cargs, cauxs = neuron.compile(sym, args, auxs, inputs)

# save compiled model
mx.model.save_checkpoint(nn_name + "_compiled", 0, csym, cargs, cauxs)
```

 모델을 컴파일하려면 다음 명령을 사용합니다.

```
python multi-model-server-compile.py
```

 출력은 다음과 같아야 합니다.

```
...
[21:18:40] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v0.8.0. Attempting to upgrade...
[21:18:40] src/nnvm/legacy_json_util.cc:217: Symbol successfully upgraded!
[21:19:00] src/operator/subgraph/build_subgraph.cc:698: start to execute partition graph.
[21:19:00] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v0.8.0. Attempting to upgrade...
[21:19:00] src/nnvm/legacy_json_util.cc:217: Symbol successfully upgraded!
```

 다음 콘텐츠를 통해 `signature.json`이라는 파일을 생성하여 입력 이름과 셰이프를 구성합니다.

```
{
  "inputs": [
    {
      "data_name": "data",
      "data_shape": [
        1,
        3,
        224,
        224
      ]
    }
  ]
}
```

다음 명령을 사용하여 `synset.txt` 파일을 다운로드합니다. 이 파일은 ImageNet 예측 클래스의 이름 목록입니다.

```
curl -O https://s3.amazonaws.com/model-server/model_archive_1.0/examples/squeezenet_v1.1/synset.txt
```

`model_server_template` 폴더의 템플릿에 따라 사용자 지정 서비스 클래스를 생성합니다. 다음 명령을 사용하여 템플릿을 현재 작업 디렉터리에 복사합니다.

```
cp -r ../model_service_template/* .
```

 `mxnet_model_service.py` 모듈을 편집하여 `mx.cpu()` 컨텍스트를 다음과 같이 `mx.neuron()` 컨텍스트로 바꿉니다. 또한 MXNet-Neuron은 NDARray 및 Gluon API를 지원하지 않으므로 `model_input`에 불필요한 데이터 복사본을 주석 처리해야 합니다.

```
...
self.mxnet_ctx = mx.neuron() if gpu_id is None else mx.gpu(gpu_id)
...
#model_input = [item.as_in_context(self.mxnet_ctx) for item in model_input]
```

 다음 명령을 사용하여 model-archiver로 모델을 패키징합니다.

```
cd ~/multi-model-server/examples
model-archiver --force --model-name resnet-50_compiled --model-path mxnet_vision --handler mxnet_vision_service:handle
```

## 추론 실행
<a name="tutorial-inferentia-mxnet-neuron-serving-inference"></a>

다중 모델 서버를 시작하고 다음 명령을 사용하여 RESTful API를 사용하는 모델을 로드합니다. **neuron-rtd**가 기본 설정으로 실행 중인지 확인합니다.

```
cd ~/multi-model-server/
multi-model-server --start --model-store examples > /dev/null # Pipe to log file if you want to keep a log of MMS
curl -v -X POST "http://localhost:8081/models?initial_workers=1&max_workers=4&synchronous=true&url=resnet-50_compiled.mar"
sleep 10 # allow sufficient time to load model
```

 다음 명령을 사용하여 예제 이미지로 추론을 실행합니다.

```
curl -O https://raw.githubusercontent.com/awslabs/multi-model-server/master/docs/images/kitten_small.jpg
curl -X POST http://127.0.0.1:8080/predictions/resnet-50_compiled -T kitten_small.jpg
```

 출력은 다음과 같아야 합니다.

```
[
  {
    "probability": 0.6388034820556641,
    "class": "n02123045 tabby, tabby cat"
  },
  {
    "probability": 0.16900072991847992,
    "class": "n02123159 tiger cat"
  },
  {
    "probability": 0.12221276015043259,
    "class": "n02124075 Egyptian cat"
  },
  {
    "probability": 0.028706775978207588,
    "class": "n02127052 lynx, catamount"
  },
  {
    "probability": 0.01915954425930977,
    "class": "n02129604 tiger, Panthera tigris"
  }
]
```

 테스트 후 정리하려면 RESTful API를 통해 delete 명령을 실행하고 다음 명령을 사용하여 모델 서버를 중지합니다.

```
curl -X DELETE http://127.0.0.1:8081/models/resnet-50_compiled

multi-model-server --stop
```

 다음 결과가 표시됩니다.

```
{
  "status": "Model \"resnet-50_compiled\" unregistered"
}
Model server stopped.
Found 1 models and 1 NCGs.
Unloading 10001 (MODEL_STATUS_STARTED) :: success
Destroying NCG 1 :: success
```

# PyTorch-Neuron 및 AWS Neuron 컴파일러 사용
<a name="tutorial-inferentia-pytorch-neuron"></a>

PyTorch-Neuron 컴파일 API는 AWS Inferentia 디바이스에서 실행할 수 있는 모델 그래프를 컴파일하는 방법을 제공합니다.

훈련된 모델은 Inf1 인스턴스에서 배포하기 전에 Inferentia 대상에 컴파일되어야 합니다. 다음 자습서에서는 torchvision ResNet50 모델을 컴파일하고 저장된 TorchScript 모듈로 내보냅니다. 이러한 모델은 추론을 실행하는 데 사용됩니다.

편의상 이 자습서에서는 컴파일 및 추론 모두에 Inf1 인스턴스를 사용합니다. 실제로는 c5 인스턴스 패밀리와 같은 다른 인스턴스 유형을 사용하여 모델을 컴파일할 수 있습니다. 그런 다음 컴파일된 모델을 Inf1 추론 서버에 배포해야 합니다. 자세한 내용은 [AWS Neuron PyTorch SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/pytorch-neuron/index.html)를 참조하세요.

**Topics**
+ [사전 조건](#tutorial-inferentia-pytorch-neuron-prerequisites)
+ [Conda 환경 활성화](#tutorial-inferentia-pytorch-neuron-activate)
+ [Resnet50 컴파일](#tutorial-inferentia-pytorch-neuron-compilation)
+ [ResNet50 추론](#tutorial-inferentia-pytorch-neuron-inference)

## 사전 조건
<a name="tutorial-inferentia-pytorch-neuron-prerequisites"></a>

이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-pytorch-neuron-activate"></a>

다음 명령을 사용하여 PyTorch-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_pytorch_p36
```

현재 conda 환경을 종료하려면 다음을 실행합니다.

```
source deactivate
```

## Resnet50 컴파일
<a name="tutorial-inferentia-pytorch-neuron-compilation"></a>

다음 콘텐츠를 통해 **pytorch\$1trace\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 PyTorch-Neuron 컴파일 Python API를 사용하여 ResNet-50 모델을 컴파일합니다.

**참고**  
토치비전 모델과 토치 패키지 버전 간에는 종속성이 있으며, 토치비전 모델을 컴파일할 때 이 점을 알고 있어야 합니다. 이러한 종속성 규칙은 pip를 통해 관리할 수 있습니다. Torchvision==0.6.1은 torch==1.5.1 릴리스와 일치하고, torchvision==0.8.2는 torch==1.7.1 릴리스와 일치합니다.

```
import torch
import numpy as np
import os
import torch_neuron
from torchvision import models

image = torch.zeros([1, 3, 224, 224], dtype=torch.float32)

## Load a pretrained ResNet50 model
model = models.resnet50(pretrained=True)

## Tell the model we are using it for evaluation (not training)
model.eval()
model_neuron = torch.neuron.trace(model, example_inputs=[image])

## Export to saved model
model_neuron.save("resnet50_neuron.pt")
```

컴파일 스크립트를 실행합니다.

```
python pytorch_trace_resnet50.py
```

컴파일이 끝날 때까지 몇 분 정도 소요될 수 있습니다. 컴파일이 완료되면 컴파일된 모델이 로컬 디렉터리에 `resnet50_neuron.pt`로 저장됩니다.

## ResNet50 추론
<a name="tutorial-inferentia-pytorch-neuron-inference"></a>

다음 콘텐츠를 통해 **pytorch\$1infer\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 샘플 이미지를 다운로드하고 이를 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
import os
import time
import torch
import torch_neuron
import json
import numpy as np

from urllib import request

from torchvision import models, transforms, datasets

## Create an image directory containing a small kitten
os.makedirs("./torch_neuron_test/images", exist_ok=True)
request.urlretrieve("https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg",
                    "./torch_neuron_test/images/kitten_small.jpg")


## Fetch labels to output the top classifications
request.urlretrieve("https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json","imagenet_class_index.json")
idx2label = []

with open("imagenet_class_index.json", "r") as read_file:
    class_idx = json.load(read_file)
    idx2label = [class_idx[str(k)][1] for k in range(len(class_idx))]

## Import a sample image and normalize it into a tensor
normalize = transforms.Normalize(
    mean=[0.485, 0.456, 0.406],
    std=[0.229, 0.224, 0.225])

eval_dataset = datasets.ImageFolder(
    os.path.dirname("./torch_neuron_test/"),
    transforms.Compose([
    transforms.Resize([224, 224]),
    transforms.ToTensor(),
    normalize,
    ])
)

image, _ = eval_dataset[0]
image = torch.tensor(image.numpy()[np.newaxis, ...])

## Load model
model_neuron = torch.jit.load( 'resnet50_neuron.pt' )

## Predict
results = model_neuron( image )

# Get the top 5 results
top5_idx = results[0].sort()[1][-5:]

# Lookup and print the top 5 labels
top5_labels = [idx2label[idx] for idx in top5_idx]

print("Top 5 labels:\n {}".format(top5_labels) )
```

다음 명령을 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
python pytorch_infer_resnet50.py
```

출력은 다음과 같아야 합니다.

```
Top 5 labels:
 ['tiger', 'lynx', 'tiger_cat', 'Egyptian_cat', 'tabby']
```