モデル・アンサンブル・パイプラインのデモ¶
このガイドでは、DAG スケジューラーを使用してモデル・アンサンブルを実装する方法を説明します。
画像分類を実行するアプリケーションを開発することを前提としています。このタスクに使用できるさまざまなモデルが多数あります。目標は、2 つの異なるモデルで実行された推論の結果を結合し、argmax を計算して最も可能性の高い分類ラベルを選択することです。
このタスクでは、googlenet-v2 と resnet-50 の 2 つのモデルを選択します。さらに、独自モデル argmax を作成して、上位の結果を組み合わせて選択します。それはネットワーク経由で中間結果を渡さずに、このタスクをサーバー側で実行するためです。サーバーは、後続のモデルへの入力/出力の供給を処理する必要があります。googlenet 予測と resnet 予測は並行して実行する必要があります。
このパイプラインは次のようになります。
ステップ 1: リポジトリーの準備¶
リポジトリーのクローンを作成し、model_ensemble ディレクトリーに移動します。
git clone https://github.com/openvinotoolkit/model_server.git
cd model_server/demos/model_ensemble/python
リポジトリーの準備は make
スクリプトを使用することで簡素化され、このリポジトリーで make
を実行するだけです。
make
Makefile
の手順は次のとおりです。
Open Model Zoo からモデルをダウンロードして使用します。
このリポジトリーにある python スクリプトを使用します。tensorflow を使用して保存されたモデル形式でモデルを作成するには、tensorflow pip パッケージが必要です。
googlenet および resnet の出力形状の出力と一致するように、
(1, 1001)
の入力形状を持つ argmax モデルを準備します。生成されたモデルは入力を合計し、最も高値のインデックスを計算します。モデルの出力には、ImageNet* データセットから最も可能性の高い予測クラスが示されます。モデルを IR 形式に変換し、モデル・リポジトリーを準備します。
...
models
├── argmax
│ └── 1
│ ├── saved_model.bin
│ ├── saved_model.mapping
│ └── saved_model.xml
├── config.json
├── googlenet-v2-tf
│ └── 1
│ ├── googlenet-v2-tf.bin
│ ├── googlenet-v2-tf.mapping
│ └── googlenet-v2-tf.xml
└── resnet-50-tf
└── 1
├── resnet-50-tf.bin
├── resnet-50-tf.mapping
└── resnet-50-tf.xml
6 directories, 10 files
ステップ 2: 必要なモデルとパイプラインを定義¶
パイプラインを使用するには、構成ファイルでパイプラインを定義する必要があります。同じ構成ファイルを使用して、提供されるモデルと提供されるパイプラインを定義します。
ここにある config.json を使用します。内容は次のとおりです。
cat config.json
{
"model_config_list": [
{
"config": {
"name": "googlenet",
"base_path": "/models/googlenet-v2-tf"
}
},
{
"config": {
"name": "resnet",
"base_path": "/models/resnet-50-tf"
}
},
{
"config": {
"name": "argmax",
"base_path": "/models/argmax"
}
}
],
"pipeline_config_list": [
{
"name": "image_classification_pipeline",
"inputs": ["image"],
"nodes": [
{
"name": "googlenet_node",
"model_name": "googlenet",
"type": "DL model",
"inputs": [
{"input": {"node_name": "request",
"data_item": "image"}}
],
"outputs": [
{"data_item": "InceptionV2/Predictions/Softmax",
"alias": "probability"}
]
},
{
"name": "resnet_node",
"model_name": "resnet",
"type": "DL model",
"inputs": [
{"map/TensorArrayStack/TensorArrayGatherV3": {"node_name": "request",
"data_item": "image"}}
],
"outputs": [
{"data_item": "softmax_tensor",
"alias": "probability"}
]
},
{
"name": "argmax_node",
"model_name": "argmax",
"type": "DL model",
"inputs": [
{"input1": {"node_name": "googlenet_node",
"data_item": "probability"}},
{"input2": {"node_name": "resnet_node",
"data_item": "probability"}}
],
"outputs": [
{"data_item": "argmax:0",
"alias": "most_probable_label"}
]
}
],
"outputs": [
{"label": {"node_name": "argmax_node",
"data_item": "most_probable_label"}}
]
}
]
}
model_config_list
セクションでは、3 つのモデルが定義されています。パイプライン定義では名前参照できますが、それらに対する単一の推論を個別に要求することもできます。モデルとパイプラインの要求には、同じ推論 gRPC と REST API が使用されます。OpenVINO™ モデルサーバーは、まず、要求された名前を持つモデルを検索します。見つからない場合はパイプラインを検索します。
ステップ 3: モデルサーバーの開始¶
コマンドを実行してモデルサーバーを起動します。
docker run --rm -v $(pwd)/models/:/models:ro -p 9100:9100 -p 8100:8100 openvino/model_server:latest --config_path /models/config.json --port 9100 --rest_port 8100 --log_level DEBUG
ステップ 4: サービスの要求¶
入力画像は、リソース名 image_classification_pipeline
を要求するサービスに送信できます。以下にクライアントの例を示します。
別の端末でクライアントを実行して、パイプラインの精度を確認します。
cd ../../../client/python/tensorflow-serving-api/samples
virtualenv .venv
. .venv/bin/activate && pip3 install -r requirements.txt
python3 grpc_predict_resnet.py --pipeline_name image_classification_pipeline --images_numpy_path ../../imgs.npy \
--labels_numpy_path ../../lbs.npy --grpc_port 9100 --input_name image --output_name label --transpose_input True --transpose_method nchw2nhwc --iterations 10
Image data range: 0.0 : 255.0
Start processing:
Model name: image_classification_pipeline
Iterations: 10
Images numpy path: ../../imgs.npy
Numpy file shape: (10, 224, 224, 3)
Iteration 1; Processing time: 33.51 ms; speed 29.85 fps
imagenet top results in a single batch:
response shape (1,)
0 airliner 404 ; Correct match.
Iteration 2; Processing time: 42.52 ms; speed 23.52 fps
imagenet top results in a single batch:
response shape (1,)
0 Arctic fox, white fox, Alopex lagopus 279 ; Correct match.
Iteration 3; Processing time: 34.42 ms; speed 29.05 fps
imagenet top results in a single batch:
response shape (1,)
0 bee 309 ; Correct match.
Iteration 4; Processing time: 32.34 ms; speed 30.92 fps
imagenet top results in a single batch:
response shape (1,)
0 golden retriever 207 ; Correct match.
Iteration 5; Processing time: 35.92 ms; speed 27.84 fps
imagenet top results in a single batch:
response shape (1,)
0 gorilla, Gorilla gorilla 366 ; Correct match.
Iteration 6; Processing time: 33.63 ms; speed 29.74 fps
imagenet top results in a single batch:
response shape (1,)
0 magnetic compass 635 ; Correct match.
Iteration 7; Processing time: 37.22 ms; speed 26.86 fps
imagenet top results in a single batch:
response shape (1,)
0 peacock 84 ; Correct match.
Iteration 8; Processing time: 35.84 ms; speed 27.90 fps
imagenet top results in a single batch:
response shape (1,)
0 pelican 144 ; Correct match.
Iteration 9; Processing time: 33.69 ms; speed 29.68 fps
imagenet top results in a single batch:
response shape (1,)
0 snail 113 ; Correct match.
Iteration 10; Processing time: 46.54 ms; speed 21.49 fps
imagenet top results in a single batch:
response shape (1,)
0 zebra 340 ; Correct match.
processing time for all iterations
average time: 36.00 ms; average speed: 27.78 fps
median time: 34.50 ms; median speed: 28.99 fps
max time: 46.00 ms; min speed: 21.74 fps
min time: 32.00 ms; max speed: 31.25 fps
time percentile 90: 42.40 ms; speed percentile 90: 23.58 fps
time percentile 50: 34.50 ms; speed percentile 50: 28.99 fps
time standard deviation: 4.31
time variance: 18.60
Classification accuracy: 100.00
ステップ 5: サーバーログ内のパイプライン実行を分析¶
デバッグログとタイムスタンプを分析すると、GoogleNet と ResNet のモデル推論が並行して開始されたことが分かります。すべての入力の準備が整い、argmax ノードがジョブを開始しました。
docker logs <container_id>
[2022-02-28 11:30:20.159][485][serving][debug][prediction_service.cpp:69] Processing gRPC request for model: image_classification_pipeline; version: 0
[2022-02-28 11:30:20.159][485][serving][debug][prediction_service.cpp:80] Requested model: image_classification_pipeline does not exist. Searching for pipeline with that name...
[2022-02-28 11:30:20.160][485][dag_executor][debug][pipeline.cpp:83] Started execution of pipeline: image_classification_pipeline
[2022-02-28 11:30:20.160][485][serving][debug][modelmanager.cpp:1280] Requesting model: resnet; version: 0.
[2022-02-28 11:30:20.160][485][serving][debug][modelmanager.cpp:1280] Requesting model: googlenet; version: 0.
[2022-02-28 11:30:20.194][485][serving][debug][modelmanager.cpp:1280] Requesting model: argmax; version: 0.
ステップ 6: パイプラインメタデータの要求¶
モデルのメタデータの要求と同じ gRPC/REST サンプル・クライアントを使用できます。唯一の違いは、モデル名の代わりにパイプライン名を指定することです。
python3 grpc_get_model_metadata.py --grpc_port 9100 --model_name image_classification_pipeline
Getting model metadata for model: image_classification_pipeline
Inputs metadata:
Input name: image; shape: [1, 224, 224, 3]; dtype: DT_FLOAT
Outputs metadata:
Output name: label; shape: [1]; dtype: DT_INT64