ベンチマーク・クライアント (Python)

はじめに

ここで紹介されているベンチマーク・クライアントは Python 3 で記述されています。ベンチマーク・クライアントは、TFServing API および KServe API を使用してモデルサーバーと通信します。ベンチマーク・クライアントを Docker コンテナとして使用することを推奨します。送信前に、クライアントはサーバーからメタデータをダウンロードします。このメタデータには、利用可能なモデル、そのバージョン、および受け入れられた入力および出力形状のリストが含まれています。次に、サービスによって提供されるモデルに一致する形状を持つランダムデータを含むテンソルを生成します。データセットの長さとワークロード期間の両方を個別に指定できます。作成された合成データは、ワークロードの長さが満たされるまでデータセットを反復するループで提供されます。クライアントの主な役割はパフォーマンスの測定であるため、スループットやレイテンシーに関係のないものは無視されます。それらのアクティビティーは、クライアント側で測定されたパフォーマンス・メトリックに影響を及ぼす可能性があるため、クライアントは受信した応答を検証せず、精度も推定しません。

標準データ形式に加えて、クライアントはステートフル・モデル (連続する推論要求間の依存関係を認識する) および選択したファイル形式 (PNG および JPEG) のバイナリー入力もサポートします。

urandom generated input image xrandom generated input image

クライアントは複数の精度をサポートします: FP16FP32FP64INT8INT16INT32INT64UINT8UINT16UINT32UINT64。証明書ありなしの両方のチャネルタイプがサポートされています。シークレット/証明書は別のボリュームにマウントする必要があり、そのパスをコマンドラインで指定します。セキュアな接続は、ビルトインの Nginx 逆プロキシー・ロード・バランサーを使用してパブリックソースから構築できる Nginx OVMS プラグインのベンチマークに使用できます。

単一の Docker コンテナは、異なるプロセスで多数の並列クライアントを実行できます。測定されたメトリック (特にスループット、レイテンシー、カウンター) はすべてのクライアント・プロセスから収集され、それを組み合わせて並列ワークロード全体の JSON 形式/構文で出力できます。Docker コンテナがデーモンモードで実行されている場合、docker logs コマンドで最終的なログを表示できます。結果は Mongo データベースにエクスポートすることもできます。これには、適切な識別メタデータをコマンドラインで指定する必要があります。

2.7 アップデート以降、ベンチマーク・クライアントの測定オプションが導入されました。ビルトイン文字列データ入力による言語モデルのテストと、OVMS での MediaPipe グラフのテストがサポートされます。それぞれ入力データのメソッドを指定する必要があります。データメソッド -d string はサンプル・テキスト・データを作成します。

MediaPipe と統合された OVMS のベンチマークは、gRPC プロトコル経由で KServe API に対して可能です。この場合、numpy 配列で構成される事前に準備された numpy ファイルをクライアントに供給する必要もあります。

shape パラメーターを使用して動的モデルをテストするオプションもあります。

最後の 2 つの使用例については、このドキュメントでさらに説明します。

ベンチマーク・クライアント Docker イメージのビルド

Docker イメージをビルドし、benchmark_client としてタグ付けするには、次のコマンドを実行します。

git clone https://github.com/openvinotoolkit/model_server.git
cd model_server/demos/benchmark/python
docker build . -t benchmark_client

OVMS のデプロイ

モデルをダウンロードし、適切なディレクトリー・ツリーを作成します。例えば、インテルの Open Model Zoo の resnet50 バイナリーモデルでは次のようになります。

mkdir -p workspace/resnet50-binary-0001/1
cd workspace/resnet50-binary-0001/1
wget https://storage.openvinotoolkit.org/repositories/open_model_zoo/2022.1/models_bin/2/resnet50-binary-0001/FP32-INT1/resnet50-binary-0001.xml
wget https://storage.openvinotoolkit.org/repositories/open_model_zoo/2022.1/models_bin/2/resnet50-binary-0001/FP32-INT1/resnet50-binary-0001.bin
cd ../../..

モデルのディレクトリーは次のようになります。

workspace
└── resnet50-binary-0001
    └── 1
        ├── resnet50-binary-0001.bin
        └── resnet50-binary-0001.xml

ベンチマーク・クライアントをビルドして実行する前に、OVMS を起動します (詳細な展開オプションについてはドキュメントを参照してください)。

docker run -u $(id -u) -p 9000:9000 -p 8000:8000 -d -v ${PWD}/workspace:/workspace openvino/model_server --model_path \
                     /workspace/resnet50-binary-0001 --model_name resnet50-binary-0001 --port 9000 --rest_port 8000

選択されたコマンド

利用可能なオプションを確認するには、-h--help スイッチを使用します。

  docker run benchmark_client --help

usage: main.py [-h] [-i ID] [-c CONCURRENCY] [-a SERVER_ADDRESS]
               [-p GRPC_PORT] [-r REST_PORT] [-l] [-b [BS ...]]
               [-s [SHAPE ...]] [-d [DATA ...]] [-j] [-m MODEL_NAME]
               [-k DATASET_LENGTH] [-v MODEL_VERSION] [-n STEPS_NUMBER]
               [-t DURATION] [-u WARMUP] [-w WINDOW] [-e ERROR_LIMIT]
               [-x ERROR_EXPOSITION] [--max_throughput MAX_THROUGHPUT]
               [--max_value MAX_VALUE] [--min_value MIN_VALUE] [--xrand XRAND]
               [--dump_png] [--step_timeout STEP_TIMEOUT]
               [--metadata_timeout METADATA_TIMEOUT] [-Y DB_ENDPOINT]
               [-y [DB_METADATA ...]] [--print_all] [--print_time]
               [--report_warmup] [--certs_dir CERTS_DIR] [-q STATEFUL_LENGTH]
               [--stateful_id STATEFUL_ID] [--stateful_hop STATEFUL_HOP]
               [--sync_interval SYNC_INTERVAL]
               [--quantile_list [QUANTILE_LIST ...]]
               [--hist_factor HIST_FACTOR] [--hist_base HIST_BASE]
               [--internal_version] [--unbuffered] [--api {TFS,KFS,REST}]

This is benchmarking client which uses TFS/KFS API to communicate with
OVMS/TFS/KFS-based-services.

バージョンは、--internal_version スイッチで確認できます。

  docker run benchmark_client --internal_version

  2.7

クライアントは、提供されたモデルのメタデータをダウンロードできます。いずれのモデルとバージョンが提供されているか、またそのステータスが不明な場合は、--list_models スイッチをでこの情報を一覧表示できます (短縮形式の -l も使用できます)。

docker run --network host benchmark_client -a localhost -r 8000 --list_models

Client 2.7
NO_PROXY=localhost no_proxy=localhost python3 /ovms_benchmark_client/main.py -a localhost -r 8000 --list_models
XI worker: try to send request to endpoint: http://localhost:8000/v1/config
XI worker: received status code is 200.
XI worker: found models and their status:
XI worker:  model: resnet50-binary-0001, version: 1 - AVAILABLE

サンプル・ベンチマーク

名前、モデル形状、および入力と出力のデータタイプに関する情報も、同じリストスイッチを使用し、コマンドラインに -m <model-name>-v <model-version> を追加することで、利用可能なすべてのモデルにダウンロードできます。オプション -i は、アプリケーション・インスタンスの名前を持つプリフィクスを標準出力に追加するためにのみ使用されます。
例:

docker run --network host benchmark_client -a localhost -r 8000 -l -m resnet50-binary-0001 -p 9000 -i id

Client 2.7
NO_PROXY=localhost no_proxy=localhost python3 /ovms_benchmark_client/main.py -a localhost -r 8000 -l -m resnet50-binary-0001 -p 9000 -i id
XW id: Finished execution. If you want to run inference remove --list_models.
XI id: try to send request to endpoint: http://localhost:8000/v1/config
XI id: received status code is 200.
XI id: found models and their status:
XI id:  model: resnet50-binary-0001, version: 1 - AVAILABLE
XI id: request for metadata of model resnet50-binary-0001...
XI id: Metadata for model resnet50-binary-0001 is downloaded...
XI id: set version of model resnet50-binary-0001: 1
XI id: inputs:
XI id:  0:
XI id:   name: 0
XI id:   dtype: DT_FLOAT
XI id:   tensorShape: {'dim': [{'size': '1'}, {'size': '3'}, {'size': '224'}, {'size': '224'}]}
XI id: outputs:
XI id:  1463:
XI id:   name: 1463
XI id:   dtype: DT_FLOAT
XI id:   tensorShape: {'dim': [{'size': '1'}, {'size': '1000'}]}

指定したモデル名が、--list_models パラメーターを使用するときに表示されるモデル名と同じであることを確認してください。モデルバージョンは必須ではありませんが、特定のモデル名に対して複数のバージョンが利用可能な場合は追加できます。

導入されたベンチマーク・クライアントは、単一のワークロード内で複数の異なるバッチサイズでの要求の生成をサポートします。このパラメーターを指定するには、スイッチ -b--bs を使用できます。

ワークロードは、その長さが反復番号 -n--steps_number または期間の長さ -t--duration で指定される場合にのみ生成できます。ウォームアップ時間ウィンドウに関するレポートも表示するには、--report_warmup スイッチを使用します。8 つの要求の例は次のように生成されます (標準出力にメトリックを表示するには --print_all を忘れずに追加してください)。

docker run --network host benchmark_client -a localhost -r 8000 -m resnet50-binary-0001 -p 9000 -n 8 --report_warmup --print_all

Client 2.7
NO_PROXY=localhost no_proxy=localhost python3 /ovms_benchmark_client/main.py -a localhost -r 8000 -m resnet50-binary-0001 -p 9000 -n 8 --report_warmup --print_all
XI worker: request for metadata of model resnet50-binary-0001...
XI worker: Metadata for model resnet50-binary-0001 is downloaded...
XI worker: set version of model resnet50-binary-0001: 1
XI worker: inputs:
XI worker:  0:
XI worker:   name: 0
XI worker:   dtype: DT_FLOAT
XI worker:   tensorShape: {'dim': [{'size': '1'}, {'size': '3'}, {'size': '224'}, {'size': '224'}]}
XI worker: outputs:
XI worker:  1463:
XI worker:   name: 1463
XI worker:   dtype: DT_FLOAT
XI worker:   tensorShape: {'dim': [{'size': '1'}, {'size': '1000'}]}
XI worker: new random range: 0.0, 255.0
XI worker: batchsize sequence: [1]
XI worker: dataset length (0): 1
XI worker: --> dim: 1
XI worker: --> dim: 3
XI worker: --> dim: 224
XI worker: --> dim: 224
XI worker: Generated data shape: (1, 3, 224, 224)
XI worker: start workload...
XI worker: stop warmup: 374943.047975389
XI worker: stop window: inf
XI worker: Workload started!
XI worker: Warmup normally stopped: 374943.075028319
XI worker: Window normally start: 374943.07504102
XI worker: Window stopped: 374943.354446821
XI worker: total_duration: 0.3065074360347353
XI worker: total_batches: 8
XI worker: total_frames: 8
XI worker: start_timestamp: 374943.047975189
XI worker: stop_timestamp: 374943.354482625
XI worker: pass_batches: 8
XI worker: fail_batches: 0
XI worker: pass_frames: 8
XI worker: fail_frames: 0
XI worker: first_latency: 0.027021727000828832
XI worker: pass_max_latency: 0.0449919409584254
XI worker: fail_max_latency: 0.0
XI worker: brutto_batch_rate: 26.100508697261724
XI worker: brutto_frame_rate: 26.100508697261724
XI worker: netto_batch_rate: 26.127558971388062
XI worker: netto_frame_rate: 26.127558971388062
XI worker: frame_passrate: 1.0
XI worker: batch_passrate: 1.0
XI worker: mean_latency: 0.0382737630061456
XI worker: mean_latency2: 0.0015027467953827884
XI worker: stdev_latency: 0.006153524252994284
XI worker: cv_latency: 0.16077656780197483
XI worker: pass_mean_latency: 0.0382737630061456
XI worker: pass_mean_latency2: 0.0015027467953827884
XI worker: pass_stdev_latency: 0.006153524252994284
XI worker: pass_cv_latency: 0.16077656780197483
XI worker: fail_mean_latency: 0.0
XI worker: fail_mean_latency2: 0.0
XI worker: fail_stdev_latency: 0.0
XI worker: fail_cv_latency: 0.0
XI worker: window_total_duration: 0.27940580097492784
XI worker: window_total_batches: 8
XI worker: window_total_frames: 8
XI worker: window_start_timestamp: 374943.07504102
XI worker: window_stop_timestamp: 374943.354446821
XI worker: window_pass_batches: 8
XI worker: window_fail_batches: 0
XI worker: window_pass_frames: 8
XI worker: window_fail_frames: 0
XI worker: window_first_latency: 0.027021727000828832
XI worker: window_pass_max_latency: 0.0449919409584254
XI worker: window_fail_max_latency: 0.0
XI worker: window_brutto_batch_rate: 28.632190069374655
XI worker: window_brutto_frame_rate: 28.632190069374655
XI worker: window_netto_batch_rate: 26.127558971388062
XI worker: window_netto_frame_rate: 26.127558971388062
XI worker: window_frame_passrate: 1.0
XI worker: window_batch_passrate: 1.0
XI worker: window_mean_latency: 0.0382737630061456
XI worker: window_mean_latency2: 0.0015027467953827884
XI worker: window_stdev_latency: 0.006153524252994284
XI worker: window_cv_latency: 0.16077656780197483
XI worker: window_pass_mean_latency: 0.0382737630061456
XI worker: window_pass_mean_latency2: 0.0015027467953827884
XI worker: window_pass_stdev_latency: 0.006153524252994284
XI worker: window_pass_cv_latency: 0.16077656780197483
XI worker: window_fail_mean_latency: 0.0
XI worker: window_fail_mean_latency2: 0.0
XI worker: window_fail_stdev_latency: 0.0
XI worker: window_fail_cv_latency: 0.0
XI worker: window_hist_latency_4: 2
XI worker: window_hist_latency_9: 1
XI worker: window_hist_latency_8: 5
XI worker: warmup_total_duration: 0.02705443004379049
XI worker: warmup_total_batches: 0
XI worker: warmup_total_frames: 0
XI worker: warmup_start_timestamp: 374943.047973889
XI worker: warmup_stop_timestamp: 374943.075028319
XI worker: warmup_pass_batches: 0
XI worker: warmup_fail_batches: 0
XI worker: warmup_pass_frames: 0
XI worker: warmup_fail_frames: 0
XI worker: warmup_first_latency: inf
XI worker: warmup_pass_max_latency: 0.0
XI worker: warmup_fail_max_latency: 0.0
XI worker: warmup_brutto_batch_rate: 0.0
XI worker: warmup_brutto_frame_rate: 0.0
XI worker: warmup_netto_batch_rate: 0.0
XI worker: warmup_netto_frame_rate: 0.0
XI worker: warmup_frame_passrate: 0.0
XI worker: warmup_batch_passrate: 0.0
XI worker: warmup_mean_latency: 0.0
XI worker: warmup_mean_latency2: 0.0
XI worker: warmup_stdev_latency: 0.0
XI worker: warmup_cv_latency: 0.0
XI worker: warmup_pass_mean_latency: 0.0
XI worker: warmup_pass_mean_latency2: 0.0
XI worker: warmup_pass_stdev_latency: 0.0
XI worker: warmup_pass_cv_latency: 0.0
XI worker: warmup_fail_mean_latency: 0.0
XI worker: warmup_fail_mean_latency2: 0.0
XI worker: warmup_fail_stdev_latency: 0.0
XI worker: warmup_fail_cv_latency: 0.0

動的モデルのベンチマーク

動的モデルをテストするには、-s (shape) パラメーターを指定する必要があります。動的モデルを使用できますが、一部の静的モデルでは動的形状を指定することもできます。最初にモデルをワークスペースにダウンロードします。

mkdir -p workspace/face-detection-retail-0005/1
cd workspace/face-detection-retail-0005/1
wget https://storage.openvinotoolkit.org/repositories/open_model_zoo/2023.0/models_bin/1/face-detection-retail-0005/FP32/face-detection-retail-0005.bin
wget https://storage.openvinotoolkit.org/repositories/open_model_zoo/2023.0/models_bin/1/face-detection-retail-0005/FP32/face-detection-retail-0005.xml
cd ../../..

次に、動的入力形状を指定して OVMS を起動します。

docker run -u $(id -u) -p 9000:9000 -p 8000:8000 -d -v ${PWD}/workspace:/workspace openvino/model_server --model_path /workspace/face-detection-retail-0005 --model_name face-detection-retail-0005 --shape "(-1,3,-1,-1)" --port 9000 --rest_port 8000

指定した形状の要求を生成するには、入力形状を明示的に設定する必要があります。これは、-s または --shape パラメーターで必要な数値を指定します。

docker run --network host benchmark_client -a localhost -r 8000 -m face-detection-retail-0005 -p 9000 -n 8 -s 1 3 300 300 --print_all
Client 2.7
NO_PROXY=localhost no_proxy=localhost python3 /ovms_benchmark_client/main.py -a localhost -r 8000 -m face-detection-retail-0005 -p 9000 -n 8 -s 1 3 300 300 --print_all
          XI worker: request for metadata of model face-detection-retail-0005...
          XI worker: Metadata for model face-detection-retail-0005 is downloaded...
          XI worker: set version of model face-detection-retail-0005: 1
          XI worker: inputs:
          XI worker:  input.1:
          XI worker:   name: input.1
          XI worker:   dtype: DT_FLOAT
          XI worker:   tensorShape: {'dim': [{'size': '-1'}, {'size': '3'}, {'size': '-1'}, {'size': '-1'}]}
          XI worker: outputs:
          XI worker:  527:
          XI worker:   name: 527
          XI worker:   dtype: DT_FLOAT
          XI worker:   tensorShape: {'dim': [{'size': '1'}, {'size': '1'}, {'size': '-1'}, {'size': '7'}]}
          XI worker: new random range: 0.0, 255.0
          XI worker: batchsize sequence: [1]
          XI worker: dataset length (input.1): 1
          XI worker: --> dim: 1
          XI worker: --> dim: 3
          XI worker: --> dim: 300
          XI worker: --> dim: 300
          XI worker: Generated data shape: (1, 3, 300, 300)
          XI worker: start workload...
...

MediaPipe ベンチマーク

Mediapipe servable を含む config.json を使用して OVMS コンテナを起動します。OVMS は MediaPipe を有効にしてビルドする必要があります。

cp -r ${PWD}/sample_data ${PWD}/workspace/sample_data
docker run -u $(id -u) -p 9000:9000 -p 8000:8000 -d -v ${PWD}/workspace:/workspace openvino/model_server --port 9000 --rest_port 8000 --config_path /workspace/sample_data/config.json

ベンチマークの要求は、numpy ファイルの配列を基に準備されます。このデータファイルは、スイッチ -d <data-file>.npy を指定することによってベンチマーク・クライアントに供給されます。KServe API が設定されている場合は、単一のモデルやパイプラインに対しても numpy データが使用できることに注意してください。Python3 を使用して、配列の形状と精度を指定してサンプルデータを作成できます。この例では、生成された .npy ファイルを workspace/sample_data ディレクトリーに保存する必要があります。

python -c 'import numpy as np ; \
arr = np.ones((1,3,224,224),dtype=np.float32); \
np.save("workspace/sample_data/resnet50-binary-0001.npy", arr)'

MediaPipe グラフファイルと servable を config.json で指定すると、モデル名の代わりにその名前で呼び出します: -m <mediapipe-servable-name>。Mediapipe グラフは KServe API 経由でのみ公開されるため、--api KFS を設定する必要があります。

docker run -v ${PWD}/workspace:/workspace --network host benchmark_client -a localhost -r 8000 -m resnet50-binary-0001_mediapipe -p 9000 -n 8 --api KFS -d /workspace/sample_data/resnet50-binary-0001.npy --report_warmup --print_all

他の多くのクライアント・オプションとベンチマークの例は、追加の PDF ドキュメントに記載されています。