

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# モデルを管理する
<a name="edge-manage-model"></a>

Edge Manager エージェントは、一度に複数のモデルをロードし、エッジデバイスにロードされたモデルを使用して推論できます。エージェントがロードできるモデルの数は、デバイスが使用できるメモリによって決まります。エージェントはモデルの署名を検証し、エッジパッケージ化ジョブによって生成されたすべてのアーティファクトをメモリにロードします。このステップでは、他のバイナリファイルとともに、前のステップで説明した必要な証明書すべてをインストールする必要があります。モデルの署名を検証できない場合、それに応じたリターンコードと理由を返し、モデルのロードは失敗します。

SageMaker Edge Manager エージェントには、エッジデバイスにコントロールプレーン API とデータプレーン API を実装するさまざまなモデル管理 API が用意されています。このドキュメントを読み、以下で説明する API の基本的な使い方を示すクライアント実装のサンプルを確認することをお勧めします。

`proto` ファイルは、リリースアーティファクトの一部としてリリース tarball の中にあります。このドキュメントでは、この `proto` ファイルにリストされている API の使い方をリスト表示して説明します。

**注記**  
Windows リリースはこれらの API に対して 1 対 1 でマッピングされ、C\$1 でのアプリケーション実装のサンプルコードは Windows のリリースアーティファクトと共有されます。以下の手順は、エージェントをスタンドアロンプロセスとして実行するためのもので、Linux のリリースアーティファクトを対象としています。

OS に基づいてアーカイブを抽出します。`VERSION` は `<MAJOR_VERSION>.<YYYY-MM-DD>-<SHA-7>` の 3 つのコンポーネントに分かれています。リリースバージョン (`<MAJOR_VERSION>`)、リリースアーティファクトのタイムスタンプ (`<YYYY-MM-DD>`)、リポジトリコミット ID (`SHA-7`) を取得する方法については、「[Edge Manager エージェントをインストールする](edge-device-fleet-manual.md#edge-device-fleet-installation)」を参照してください。

------
#### [ Linux ]

zip アーカイブは、次のコマンドで抽出します。

```
tar -xvzf <VERSION>.tgz
```

------
#### [ Windows ]

zip アーカイブは、UI か次のコマンドを使用して抽出します。

```
unzip <VERSION>.tgz
```

------

リリースアーティファクトの階層 (`tar/zip` アーカイブ抽出後) を以下に示します。エージェントの `proto` ファイルは `api/` にあります。

```
0.20201205.7ee4b0b
├── bin
│         ├── sagemaker_edge_agent_binary
│         └── sagemaker_edge_agent_client_example
└── docs
├── api
│         └── agent.proto
├── attributions
│         ├── agent.txt
│         └── core.txt
└── examples
└── ipc_example
├── CMakeLists.txt
├── sagemaker_edge_client.cc
├── sagemaker_edge_client_example.cc
├── sagemaker_edge_client.hh
├── sagemaker_edge.proto
├── README.md
├── shm.cc
├── shm.hh
└── street_small.bmp
```

**Topics**
+ [モデルをロードする](#edge-manage-model-loadmodel)
+ [モデルをアンロードする](#edge-manage-model-unloadmodel)
+ [モデルをリスト表示する](#edge-manage-model-listmodels)
+ [モデルを記述する](#edge-manage-model-describemodel)
+ [データのキャプチャ](#edge-manage-model-capturedata)
+ [キャプチャステータスを取得する](#edge-manage-model-getcapturedata)
+ [予測する](#edge-manage-model-predict)

## モデルをロードする
<a name="edge-manage-model-loadmodel"></a>

Edge Manager エージェントは、複数モデルのロードをサポートしています。この API はモデルの署名を検証し、`EdgePackagingJob` の実行で生成されたすべてのアーティファクトをメモリにロードします。このステップでは、エージェントの他のバイナリファイルとともに、必要な証明書すべてをインストールする必要があります。モデルの署名を検証できない場合、それに応じたリターンコードとエラーメッセージをログに記録し、このステップは失敗します。

```
// perform load for a model
// Note:
// 1. currently only local filesystem paths are supported for loading models.
// 2. multiple models can be loaded at the same time, as limited by available device memory
// 3. users are required to unload any loaded model to load another model.
// Status Codes:
// 1. OK - load is successful
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
// 4. NOT_FOUND - model doesn't exist at the url
// 5. ALREADY_EXISTS - model with the same name is already loaded
// 6. RESOURCE_EXHAUSTED - memory is not available to load the model
// 7. FAILED_PRECONDITION - model is not compiled for the machine.
//
rpc LoadModel(LoadModelRequest) returns (LoadModelResponse);
```

------
#### [ Input ]

```
//
// request for LoadModel rpc call
//
message LoadModelRequest {
  string url = 1;
  string name = 2;  // Model name needs to match regex "^[a-zA-Z0-9](-*[a-zA-Z0-9])*$"
}
```

------
#### [ Output ]

```
//
//
// response for LoadModel rpc call
//
message LoadModelResponse {
  Model model = 1;
}

//
// Model represents the metadata of a model
//  url - url representing the path of the model
//  name - name of model
//  input_tensor_metadatas - TensorMetadata array for the input tensors
//  output_tensor_metadatas - TensorMetadata array for the output tensors
//
// Note:
//  1. input and output tensor metadata could empty for dynamic models.
//
message Model {
  string url = 1;
  string name = 2;
  repeated TensorMetadata input_tensor_metadatas = 3;
  repeated TensorMetadata output_tensor_metadatas = 4;
}
```

------

## モデルをアンロードする
<a name="edge-manage-model-unloadmodel"></a>

以前ロードしたモデルをアンロードします。モデルは、`loadModel` 中に提供されたモデルエイリアスを介して識別されます。エイリアスが見つからないか、モデルがロードされていない場合は、エラーが返されます。

```
//
// perform unload for a model
// Status Codes:
// 1. OK - unload is successful
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
// 4. NOT_FOUND - model doesn't exist
//
rpc UnLoadModel(UnLoadModelRequest) returns (UnLoadModelResponse);
```

------
#### [ Input ]

```
//
// request for UnLoadModel rpc call
//
message UnLoadModelRequest {
 string name = 1; // Model name needs to match regex "^[a-zA-Z0-9](-*[a-zA-Z0-9])*$"
}
```

------
#### [ Output ]

```
//
// response for UnLoadModel rpc call
//
message UnLoadModelResponse {}
```

------

## モデルをリスト表示する
<a name="edge-manage-model-listmodels"></a>

ロードされたすべてのモデルとそのエイリアスをリストします。

```
//
// lists the loaded models
// Status Codes:
// 1. OK - unload is successful
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
//
rpc ListModels(ListModelsRequest) returns (ListModelsResponse);
```

------
#### [ Input ]

```
//
// request for ListModels rpc call
//
message ListModelsRequest {}
```

------
#### [ Output ]

```
//
// response for ListModels rpc call
//
message ListModelsResponse {
 repeated Model models = 1;
}
```

------

## モデルを記述する
<a name="edge-manage-model-describemodel"></a>

エージェントにロードされたモデルについて記述します。

```
//
// Status Codes:
// 1. OK - load is successful
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
// 4. NOT_FOUND - model doesn't exist at the url
//
rpc DescribeModel(DescribeModelRequest) returns (DescribeModelResponse);
```

------
#### [ Input ]

```
//
// request for DescribeModel rpc call
//
message DescribeModelRequest {
  string name = 1;
}
```

------
#### [ Output ]

```
//
// response for DescribeModel rpc call
//
message DescribeModelResponse {
  Model model = 1;
}
```

------

## データのキャプチャ
<a name="edge-manage-model-capturedata"></a>

クライアントアプリケーションが Amazon S3 バケット内の入出力テンソル、補助テンソル (任意) をキャプチャできるようにします。クライアントアプリケーションは、この API を呼び出すたびに一意のキャプチャ ID を渡す必要があります。これは、後にキャプチャのステータスを照会するときに使用できます。

```
//
// allows users to capture input and output tensors along with auxiliary data.
// Status Codes:
// 1. OK - data capture successfully initiated
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
// 5. ALREADY_EXISTS - capture initiated for the given capture_id
// 6. RESOURCE_EXHAUSTED - buffer is full cannot accept any more requests.
// 7. OUT_OF_RANGE - timestamp is in the future.
// 8. INVALID_ARGUMENT - capture_id is not of expected format.
//
rpc CaptureData(CaptureDataRequest) returns (CaptureDataResponse);
```

------
#### [ Input ]

```
enum Encoding {
 CSV = 0;
 JSON = 1;
 NONE = 2;
 BASE64 = 3;
}

//
// AuxilaryData represents a payload of extra data to be capture along with inputs and outputs of inference
// encoding - supports the encoding of the data
// data - represents the data of shared memory, this could be passed in two ways:
// a. send across the raw bytes of the multi-dimensional tensor array
// b. send a SharedMemoryHandle which contains the posix shared memory segment id and
// offset in bytes to location of multi-dimensional tensor array.
//
message AuxilaryData {
 string name = 1;
 Encoding encoding = 2;
 oneof data {
 bytes byte_data = 3;
 SharedMemoryHandle shared_memory_handle = 4;
 }
}

//
// Tensor represents a tensor, encoded as contiguous multi-dimensional array.
// tensor_metadata - represents metadata of the shared memory segment
// data_or_handle - represents the data of shared memory, this could be passed in two ways:
// a. send across the raw bytes of the multi-dimensional tensor array
// b. send a SharedMemoryHandle which contains the posix shared memory segment
// id and offset in bytes to location of multi-dimensional tensor array.
//
message Tensor {
 TensorMetadata tensor_metadata = 1; //optional in the predict request
 oneof data {
 bytes byte_data = 4;
 // will only be used for input tensors
 SharedMemoryHandle shared_memory_handle = 5;
 }
}

//
// request for CaptureData rpc call
//
message CaptureDataRequest {
 string model_name = 1;
 string capture_id = 2; //uuid string
 Timestamp inference_timestamp = 3;
 repeated Tensor input_tensors = 4;
 repeated Tensor output_tensors = 5;
 repeated AuxilaryData inputs = 6;
 repeated AuxilaryData outputs = 7;
}
```

------
#### [ Output ]

```
//
// response for CaptureData rpc call
//
message CaptureDataResponse {}
```

------

## キャプチャステータスを取得する
<a name="edge-manage-model-getcapturedata"></a>

ロードされたモデルによっては、入力テンソルと出力テンソルが多くのエッジデバイスに存在し、大きくなる場合があります。この大きなモデルのキャプチャには、時間がかかる場合があります。そのため、非同期オペレーションとして `CaptureData()` が実装されています。キャプチャ ID は、キャプチャデータ呼び出しでクライアントが指定する一意の識別子です。この ID は、非同期呼び出しのステータスを照会するために使用できます。

```
//
// allows users to query status of capture data operation
// Status Codes:
// 1. OK - data capture successfully initiated
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
// 4. NOT_FOUND - given capture id doesn't exist.
//
rpc GetCaptureDataStatus(GetCaptureDataStatusRequest) returns (GetCaptureDataStatusResponse);
```

------
#### [ Input ]

```
//
// request for GetCaptureDataStatus rpc call
//
message GetCaptureDataStatusRequest {
  string capture_id = 1;
}
```

------
#### [ Output ]

```
enum CaptureDataStatus {
  FAILURE = 0;
  SUCCESS = 1;
  IN_PROGRESS = 2;
  NOT_FOUND = 3;
}

//
// response for GetCaptureDataStatus rpc call
//
message GetCaptureDataStatusResponse {
  CaptureDataStatus status = 1;
}
```

------

## 予測する
<a name="edge-manage-model-predict"></a>

`predict` API は、ロード済みのモデルで推論を実行します。この API はニューラルネットワークに直接入力されるテンソル形式のリクエストを受け入れ、出力はモデルからの出力テンソル (またはスカラー) です。これはブロック呼び出しです。

```
//
// perform inference on a model.
//
// Note:
// 1. users can chose to send the tensor data in the protobuf message or
// through a shared memory segment on a per tensor basis, the Predict
// method with handle the decode transparently.
// 2. serializing large tensors into the protobuf message can be quite expensive,
// based on our measurements it is recommended to use shared memory of
// tenors larger than 256KB.
// 3. SMEdge IPC server will not use shared memory for returning output tensors,
// i.e., the output tensor data will always send in byte form encoded
// in the tensors of PredictResponse.
// 4. currently SMEdge IPC server cannot handle concurrent predict calls, all
// these call will be serialized under the hood. this shall be addressed
// in a later release.
// Status Codes:
// 1. OK - prediction is successful
// 2. UNKNOWN - unknown error has occurred
// 3. INTERNAL - an internal error has occurred
// 4. NOT_FOUND - when model not found
// 5. INVALID_ARGUMENT - when tenors types mismatch
//
rpc Predict(PredictRequest) returns (PredictResponse);
```

------
#### [ Input ]

```
// request for Predict rpc call
//
message PredictRequest {
string name = 1;
repeated Tensor tensors = 2;
}

//
// Tensor represents a tensor, encoded as contiguous multi-dimensional array.
//    tensor_metadata - represents metadata of the shared memory segment
//    data_or_handle - represents the data of shared memory, this could be passed in two ways:
//                        a. send across the raw bytes of the multi-dimensional tensor array
//                        b. send a SharedMemoryHandle which contains the posix shared memory segment
//                            id and offset in bytes to location of multi-dimensional tensor array.
//
message Tensor {
  TensorMetadata tensor_metadata = 1; //optional in the predict request
  oneof data {
    bytes byte_data = 4;
    // will only be used for input tensors
    SharedMemoryHandle shared_memory_handle = 5;
  }
}

//
// Tensor represents a tensor, encoded as contiguous multi-dimensional array.
//    tensor_metadata - represents metadata of the shared memory segment
//    data_or_handle - represents the data of shared memory, this could be passed in two ways:
//                        a. send across the raw bytes of the multi-dimensional tensor array
//                        b. send a SharedMemoryHandle which contains the posix shared memory segment
//                            id and offset in bytes to location of multi-dimensional tensor array.
//
message Tensor {
  TensorMetadata tensor_metadata = 1; //optional in the predict request
  oneof data {
    bytes byte_data = 4;
    // will only be used for input tensors
    SharedMemoryHandle shared_memory_handle = 5;
  }
}

//
// TensorMetadata represents the metadata for a tensor
//    name - name of the tensor
//    data_type  - data type of the tensor
//    shape - array of dimensions of the tensor
//
message TensorMetadata {
  string name = 1;
  DataType data_type = 2;
  repeated int32 shape = 3;
}

//
// SharedMemoryHandle represents a posix shared memory segment
//    offset - offset in bytes from the start of the shared memory segment.
//    segment_id - shared memory segment id corresponding to the posix shared memory segment.
//    size - size in bytes of shared memory segment to use from the offset position.
//
message SharedMemoryHandle {
  uint64 size = 1;
  uint64 offset = 2;
  uint64 segment_id = 3;
}
```

------
#### [ Output ]

**注記**  
`PredictResponse` は `Tensors` のみを返します (`SharedMemoryHandle` は返しません)。

```
// response for Predict rpc call
//
message PredictResponse {
   repeated Tensor tensors = 1;
}
```

------