高レベルのパフォーマンスのヒント#
OpenVINO™ でサポートされるすべてのデバイスは、低レベルのパフォーマンス設定を提供しますが、それらの使用はごく少数の場合を除いてあまり推奨されません。OpenVINO ランタイムでパフォーマンスを設定するのに推奨される方法は、パフォーマンス・ヒントを使用することです。これは、自動デバイス選択推論モードと完全に互換性があり、移植性を考慮して設計された、将来性のあるソリューションです。
ヒントは、構成の方向性を正しい順序に設定することにもなります。アプリケーションのニーズを低レベルのパフォーマンス設定にマッピングし、各デバイスを個別に構成するため関連するアプリケーション・ロジックを保持する代わりに、ヒントは単一の構成でターゲットのシナリオを表現し、デバイスがそれに応じて構成するようにします。
これまでは、一定レベルの自動構成はパラメーターのデフォルト値によるものでした。例えば、ov::streams::AUTO
が設定されている場合、CPU ストリーム数は CPU のコア数から推定されます。ただし、結果として得られるストリーム数は、推論されるモデルの実際の計算要件を考慮しませんでした。対照的に、ヒントは実際のモデルを尊重しており、最適なスループットのパラメーターはモデルごとに個別に計算されます (計算対メモリー帯域幅の要件とデバイスの機能に基づいて)。
パフォーマンスのヒント: レイテンシーとスループット#
最適化ガイドで説明されているように、推論速度には関連するいくつかの異なるメトリックがあります。スループットとレイテンシーは、アプリケーション全体のパフォーマンスを測定するため最も広く使用されるメトリックの 1 つです。
デバイスの構成を容易にするため、OpenVINO は 2 つのヒント、ov::hint::PerformanceMode::LATENCY
(デフォルト) と ov::hint::PerformanceMode::THROUGHPUT
を提供します。
benchmark_app
によるパフォーマンス測定の詳細については、このドキュメントの最後のセクションを参照してください。
一般的なモデルは、ov::hint::PerformanceMode::THROUGHPUT
を使用するとロードに大幅に時間がかかり、ov::hint::PerformanceMode::LATENCY
と比較して多くのメモリーを消費する可能性があることに注意してください。また、THROUGHPUT と LATENCY ヒントは、非同期推論パイプラインのパフォーマンスのみに影響します。非同期推論の詳細については、非同期 API を優先するを参照してください。
パフォーマンスのヒント: どのように動作するか#
内部的に、すべてのデバイスはヒントの値を実際のパフォーマンス設定に “変換” します。例えば、ov::hint::PerformanceMode::THROUGHPUT
は、CPU または GPU のストリーム数を選択します。さらに、GPU に最適なバッチサイズが選択され、可能な限り自動バッチ処理が適用されます。デバイスがそれをサポートするか確認するには、サポートされるデバイスを参照してください。
(デバイス固有の) 結果設定は、ov:Compiled_Model
のインスタンスから照会できます。benchmark_app
は THROUGHPUT
ヒントの実際の設定を出力することに注意してください。以下の出力例を参照してください:
$benchmark_app -hint tput -d CPU -m 'モデルへのパス' ...[Step 8/11] Setting optimal runtime parameters
[ INFO ] Device: CPU
[ INFO ] { PERFORMANCE_HINT , THROUGHPUT }
...[ INFO ] { OPTIMAL_NUMBER_OF_INFER_REQUESTS , 4 }
[ INFO ] { NUM_STREAMS , 4 }
...
パフォーマンスのヒントを使用する: 基本 API#
以下のコード例では、compile_model
の ov::hint::performance_mode
プロパティーに ov::hint::PerformanceMode::THROUGHPUT
が指定されています。
import openvino.properties as props
import openvino.properties.hint as hints
config = {hints.performance_mode: hints.PerformanceMode.THROUGHPUT}
compiled_model = core.compile_model(model, "GPU", config)
auto compiled_model = core.compile_model(model, "GPU",
ov::hint::performance_mode(ov::hint::PerformanceMode::THROUGHPUT));
アプリからの追加のヒント (オプション)#
4 つのビデオストリームを処理するアプリケーションで並列スラックの制限を伝える最も将来性のある方法は、オプションの ov::hint::num_requests
構成キーを 4 に設定してパフォーマンス・ヒントを使用することです。前述のように、これにより、GPU のバッチサイズと CPU の推論ストリームの数が制限されます。各デバイスはヒントを実際のデバイス構成オプションに変換する際に ov::hint::num_requests
を使用します:
config = {hints.performance_mode: hints.PerformanceMode.THROUGHPUT,
hints.num_requests: "4"}
# 'スループット’ に利用可能な並列余裕を制限し、
# 特定のパラメーター (選択されたバッチサイズなど) がそれに応じて自動的に調整されるようにする
compiled_model = core.compile_model(model, "GPU", config)
// ov::hint::num_requests を介して 'スループット' ヒントの利用可能な並列スラックを制限する
// 特定のパラメーター (選択されたバッチサイズなど) がそれに応じて自動的に調整されるようにする
auto compiled_model = core.compile_model(model, "GPU",
ov::hint::performance_mode(ov::hint::PerformanceMode::THROUGHPUT),
ov::hint::num_requests(4));
最適な推論要求数#
ヒントは、アプリケーションが ov::optimal_number_of_infer_requests
を照会して、取得した数の要求を同時に作成、および実行するという前提で使用されます。
# バッチサイズが実装によって自動的に選択される場合
# 十分なリクエストを照会/作成して実行することが重要です
config = {hints.performance_mode: hints.PerformanceMode.THROUGHPUT}
compiled_model = core.compile_model(model, "GPU", config)
num_requests = compiled_model.get_property(props.optimal_number_of_infer_requests)
// バッチサイズが実装によって自動的に選択される場合
// 十分なリクエストを照会/作成して実行することが重要です
auto compiled_model = core.compile_model(model, "GPU",
ov::hint::performance_mode(ov::hint::PerformanceMode::THROUGHPUT));
auto num_requests = compiled_model.get_property(ov::optimal_number_of_infer_requests);
アプリケーションは必要に応じて追加の要求を自由に作成できますが (例えば、非同期入力の取り込みをサポートするため)、少なくとも推論要求の ov::optimal_number_of_infer_requests
を並行して実行することが重要です。効率やデバイス使用率の理由から、これを推奨します。
ov::hint::PerformanceMode::LATENCY
は、必ずしも単一の推論要求を使用することを意味するわけではないことに注意してください。例えば、マルチソケット CPU は、システム内の NUMA ノード数と同じ最小限のレイテンシーで同じ数の要求を供給できます。アプリケーションをスケーラブルにするには、ov::optimal_number_of_infer_requests
を直接照会することが必須です。
推奨される非同期 API#
推論要求の API は、同期および非同期の実行を提供します。ov::InferRequest::infer()
は本質的に同期性があり、現在のアプリケーション・スレッドで実行フローをシリアル化するため操作が簡単です。非同期は、infer()
を ov::InferRequest::start_async()
と ov::InferRequest::wait()
(またはコールバック) に “分割” します。同期モードと非同期モードの詳細については、OpenVINO 推論要求を参照してください。
同期 API は簡単に始めることができますが、運用コードでは非同期 (コールバック・ベース) API を使用することを推奨します。これは、可能な数の要求に対してフロー制御を実装する最も一般的でスケーラブルな方法です。THROUGHPUT
と LATENCY
のパフォーマンス・ヒントは、最適な数の処理ストリームと推論要求を使用するよう非同期パイプラインを自動的に構成します。
注
重要: パフォーマンス・ヒントは、非同期実行モードが使用される場合にのみ機能します。これは同期パイプラインのパフォーマンスには影響しません。
ヒントと低レベル設定の組み合わせ#
移植性はある程度犠牲になりますが、ヒントを個々のデバイス固有の設定と組み合わせることができます。例えば、ov::hint::PerformanceMode::THROUGHPUT
を使用して一般的な構成を準備し、特定の値でオーバーライドします。
config = {hints.performance_mode: hints.PerformanceMode.THROUGHPUT,
props.inference_num_threads: "4"}
# 'スループット’ に利用可能な並列余裕を制限し、
# 特定のパラメーター (選択されたバッチサイズなど) がそれに応じて自動的に調整されるようにする
compiled_model = core.compile_model(model, "CPU", config)
{
// 高レベルのパフォーマンス・ヒントは、低レベルのデバイス固有の設定と互換性があります
auto compiled_model = core.compile_model(model, "CPU",
ov::hint::performance_mode(ov::hint::PerformanceMode::THROUGHPUT),
ov::inference_num_threads(4)); }
Benchmark_App を使用したヒントのパフォーマンス・テスト#
benchmark_app サンプルは、特定のデバイスのパフォーマンス・ヒントの機能を評価するのに最良です。
benchmark_app -hint tput -d ‘device’ -m ‘path to your model’
benchmark_app -hint latency -d ‘device’ -m ‘path to your model’
ヒントを無効にして、ヒントの適用前をエミュレートします (以下のストリーム数やスレッド数など、低レベルの設定を試す前に推奨されます):
benchmark_app -hint none -nstreams 1 -d ‘device’ -m ‘path to your model’