

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 MXNet-Neuron 模型服務
<a name="tutorial-inferentia-mxnet-neuron-serving"></a>

在本教學課程中，您將學習如何使用預先培訓的 MXNet 模型來執行多模型伺服器 (MMS) 的即時影像分類。MMS 是一種靈活且易於使用的工具，可提供使用任何機器學習或深度學習架構培訓的深度學習模型。本教學課程包含使用 AWS Neuron 的編譯步驟，以及使用 MXNet 的 MMS 實作。

 如需 Neuron 開發套件的詳細資訊，請參閱 [AWS Neuron 開發套件文件](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()` 內容，如下所示。您還需要將 `model_input` 所使用、不必要的資料副本註釋掉，因為 MXNet-Neuron 不支援 NDArray 和 Gluon API。

```
...
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]
```

 使用下列指令，以模型歸檔程式封裝模型：

```
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
```