精度の制御#
データタイプの選択は推論ランタイムにとって不可欠であり、パフォーマンスやその他のメトリックに大きな影響を与える可能性があります。通常、次の 2 種類の精度が識別されます:
モデルストレージ精度 (IR 精度)、
モデル推論精度。
推論の精度は IR の精度に依存しなくなりました。つまり、ユーザーにはモデルのパフォーマンスと精度のバランスを見つけるいくつかのオプションがあります。
基本的に、IR の精度は重みの精度を下げることでモデルを圧縮しますが、デバイスがモデルを実行する方法には影響しません。この変更により、デフォルトでは GPU 上で高性能モデルを実行できなかったり、デバイス間の動作が異なったりする多くの問題が解消されました。
このガイドでは、推論の精度を制御する方法に注目します。また、小さなデータタイプほど計算帯域幅が高くなる傾向があり、ハードウェアには小さなデータタイプのみ効率的な積和演算を行う特別なブロックが備わっていることが多いため、精度を低くすることがパフォーマンス上重要です (例: GPU 上のインテル® Xe マトリクス・エクステンション (インテル® XMX)) および CPU 上のインテル® アドバンスト・マトリクス・エクステンション (インテル® AMX) は f32
をサポートしません)。また、テンソルのバイト・サイズが小さいため、I/O 操作に必要なメモリーも少なくなります。このガイドでは、推論の精度を制御する方法に注目します。
実行モデル#
ov::hint::execution_mode
は、ユーザーが最高の精度を維持したいか (ACCURACY モード)、またはデバイスがパフォーマンス上の理由で精度を低下させる最適化を実行するか (PERFORMANCE モード) を制御する高レベルのヒントです。
ACCURACY モードでは、デバイスは浮動小数点テンソルをより小さい浮動小数点タイプに変換できないため、デバイスは精度メトリックを、デバイスの実際の機能と比較して、トレーニング後に取得した元の値にできるだけ近づけようとします。これは、デバイスが
f32
精度をサポートしている場合、ほとんどのデバイスがその精度で推論を行うことを意味します。PERFORMANCE モードでは、デバイスはより小さいデータタイプに変換し、精度に影響を与える最適化を適用できますが、それでも精度の損失を最小限に抑えようとし、場合によっては混合精度の実行を行うことがあります。
OpenVINO 最適化ツールやその他の方法でモデルが量子化されている場合、デバイスにそのタイプのハードウェア・アクセラレーションがあれば、量子化された操作はターゲットの整数精度で実行されます。例えば、デバイスが浮動小数点タイプと比較して 8 ビット・データ・タイプで高い計算帯域幅を提供する場合、量子化された int8
プリミティブは、ACCURACY モードと PERFORMANCE モードの両方で int8
精度で実行されます。一方、int8
データタイプのハードウェア・アクセラレーションを備えていないデバイスは、操作を浮動小数点精度に保ち、正確な浮動小数点タイプは、execution_mode
プロパティーと inference_precision
プロパティーの影響を受けます。
コード例:
import openvino as ov
import openvino.properties.hint as hints
core = ov.Core()
# 精度
core.set_property(
"CPU",
{hints.execution_mode: hints.ExecutionMode.ACCURACY},
)
# パフォーマンス
core.set_property(
"CPU",
{hints.execution_mode: hints.ExecutionMode.PERFORMANCE},
)
ov::Core core;
// 精度
core.set_property("CPU", ov::hint::execution_mode(ov::hint::ExecutionMode::ACCURACY));
// パフォーマンス
core.set_property("CPU", ov::hint::execution_mode(ov::hint::ExecutionMode::PERFORMANCE));
推論の精度#
ov::hint::inference_precision
精度は、ユーザーが必要とする正確な精度を指定できる下位レベルのプロパティーですが、移植性は低くなります。例えば、CPU は一部のプラットフォームで f32
推論精度と bf16
をサポートし、GPU は f32
と f16
をサポートするため、ユーザーが複数のデバイスを使用するアプリケーションを必要とする場合、これらすべての組み合わせを手動で処理するか、より高い精度の execution_mode
プロパティーを使用して OV が自動的に実行できるようにします。もう 1 つは、inference_precision
もヒントであることから、指定された値がランタイムで確実に使用される保証がないことです (現在のデバイスに必要なハードウェア機能がない場合)。
注
ランタイムでは量子化を実行できないため、すべてのデバイスは inference_precision
属性の値として浮動小数点データタイプ (f32
、f16
、bf16
) のみをサポートします。
bf16
推論精度の制限#
bf16
ランタイム精度を使用して FP16 および FP32 LLM モデルを推論すると、事前に決定されたしきい値 0.5% よりも高い精度損失が発生する可能性があることに注意してください。bf16
を使用して dolly-v2-12b、dolly-v2-3b、gpt-neox-20b のオリジナル Pytorch モデルを推論すると、精度の表現が制限され精度が大幅に低下する可能性があります。
この問題を解決するには、INT8 モデルを使用して FP32 推論精度を強制することができます。FP32 を使用した INT8 モデルの精度は、f32
を使用した FP16 モデルの精度とほぼ同じです。さらに、CPU プラグインでの FP32 ops の選択的実行と NNCF bf16
キャリブレーションを組み合わせることで、精度の低下を軽減できる可能性があります。
残念ながら、上記のソリューションでは、インテル AMX-BF16 SPR を搭載したマシンで大規模バッチサイズの推論タスクを実行すると、パフォーマンスが大幅に低下してしまいます。このような場合、AMX の代わりに、融合乗算加算操作 (FMA) が使用されます。また、LLM バッチ推論/サービングなどの計算依存のケースでは、これらの回避策によりスループットが 60% 以上低下します。