ステップ 2. マークアップ変換

このステップでは、ランタイム属性インスタンスを使用したマークアップ操作を介して、最高の推論パフォーマンスを実現する最適な FakeQuantize 分解精度を定義します。属性は、入力ポート、出力ポートおよび操作に対して作成されます。変換によって操作出力ポートの精度が変更されることはありません。モデル・マークアップの低精度ロジックは分解され、次の一般的なマークアップ変換に実装されます。変換の順序は重要です。

  1. MarkupBias

  2. MarkupCanBeQuantized

  3. MarkupPrecisions

  4. MarkupPerTensorQuantization

  5. MarkupAvgPoolPrecisionPreserved

  6. PropagatePrecisions

  7. AlignQuantizationIntervals

  8. AlignQuantizationParameters

変換名

属性の作成

属性を使用

MarkupBias

Bias

MarkupCanBeQuantized

Precisions

MarkupPrecisions

Precisions、PrecisionPreserved

MarkupPerTensorQuantization

PerTensorQuantization

MarkupAvgPoolPrecisionPreserved

AvgPoolPrecisionPreserved

Precisions、PrecisionPreserved

PropagatePrecisions

Precisions

Precisions、PrecisionPreserved

AlignQuantizationIntervals

IntervalsAlignment

PrecisionPreserved

AlignQuantizationParameters

QuantizationAlignment

PrecisionPreserved、PerTensorQuantization

同じタイプの属性インスタンスを異なる変換で作成できます。このアプローチは、変換の単一責任原則の結果です。例えば、Precision 属性インスタンスは MarkupCanBeQuantized 変換と MarkupPrecisions 変換で作成されますが、それらを作成する理由は異なります

一般的なマークアップ変換は、より単純なユーティリティー・マークアップ変換に分解できます。マークアップ・ユーティリティーの変換の順序は重要ではありません。

同じモデルを使用して、すべての変換とその関係を詳しく調べてみます。

../../../../../_images/step2_markup_original.svg

元のモデルのキーの特徴は次のとおりです。

  • 最初の concat1 連結操作では、convolution1 コンシューマーが量子化されていません。

  • 2 番目の concat2 連結操作には、次の要件を持つ量子化された convolution2 コンシューマーがあります。

    • アクティベーション時に unsigned int8 をサポートします。

    • テンソルごとの量子化。

  • concat2 連結操作と Convolution の間には AvgPool 操作があり、数学的には f32 テンソルを返すはずです。ただし、MarkupAvgPoolPrecisionPreserved 変換はアクティブです。これにより、AvgPool の後の低精度変換が、低精度テンソルを次のコンシューマーに伝播することが可能になります。

変換は次のパラメーターを使用して実行されます。

auto supportedPrecisions = std::vector<PrecisionsRestriction>({
    PrecisionsRestriction::create<ov::opset1::Convolution>({
        {{0}, {ov::element::u8}},
        {{1}, {ov::element::i8}},
    }),
});

auto perTensorQuantization = std::vector<QuantizationGranularityRestriction>({
    QuantizationGranularityRestriction::create<ov::opset1::Convolution>({0})
});

ov::pass::Manager lptManager;
lptManager.register_pass<ov::pass::low_precision::LowPrecision>(supportedPrecisions, perTensorQuantization);
lptManager.run_passes(model);

1. MarkupCanBeQuantized

変換では、量子化できない操作がマークされます。変換前に属性は必要ありません。

MarkupCanBeQuantized 変換後のサンプルモデルの変更:

  • 量子化されていない convolution1 操作は、空の値を持つ Precisions 属性によってマークされます。この属性により、次の変換で量子化されていない操作を無視できるようになります。

結果モデル:

MarkupCanBeQuantize

モデルの表示機能 (ここと以下):

  • 現在の変換によって追加された属性は太字でマークされています。

  • 属性が 1 行に収まらない場合、1 行を 1 つの属性のみで構成します。

2. MarkupPrecisions

変換は必須であり、次の 2 つのタスクが含まれます。

  1. 指定された制限 (入力ポートのインデックスと必要な精度) に従って、操作の入力ポートをマークします (Precision 属性インスタンスを作成します)。制限は、ov::pass::low_precision::LowPrecision コンストラクターの入力引数として提供されます。

  2. 精度を維持した操作をマークします。

変換前に属性は必要ありません。

MarkupPrecisions 変換後のサンプルモデルの変更:

  • どちらの連結操作も、精度を保持する操作としてマークされます。これらの操作を通じて精度を伝播することができます。

  • 量子化 convolution2 操作は、指定された制限に従って、アクティベーションでは u8 精度、重みでは i8 精度の Precisions 属性によってマークされます。この属性インスタンスを使用すると、量子化された畳み込み操作に必要な精度を指定できます。

結果モデル:

MarkupPrecisions result

3. MarkupPerTensorQuantization

変換は必須であり、指定された制限 (テンソルごとの量子化を必要とする操作) によって操作 (PerTensorQuantization 属性インスタンスの作成) をマークします。変換前に属性は必要ありません。

MarkupPerTensorQuantization 変換後のサンプルモデルの変更:

  • 両方の畳み込み操作は PerTensorQuantization でマークされます。

結果モデル:

MarkupPerTensorQuantization result

4. MarkupAvgPoolPrecisionPreserved

変換はオプションです。MarkupAvgPoolPrecisionPreserved は、AvgPool 操作の精度が保持されるか、されないかをマークします。AvgPool 操作は、次に精度が保持されない操作が低精度で推論できる場合、精度が保持されます。言い換えれば、AvgPool 操作は精度を維持する操作となり、モデル推論を高速化します。変換では、前に作成した PrecisionPreserved 属性を使用します。変換を組み合わせて使用します。

  • CreatePrecisionsDependentAttribute

  • PropagateThroughPrecisionPreserved

  • UpdateSharedPrecisionPreserved

MarkupAvgPoolPrecisionPreserved 変換後のサンプルモデルの変更:

  • AvgPool 操作は、PrecisionPreserved および AvgPoolPrecisionPreserved によってマークされます (以下では使用しません)。

結果モデル:

arkupAvgPoolPrecisionPreserved

5. PropagatePrecisions

変換が必要です。PropagatePrecision はマークアップ・パイプラインの主な変換であり、FakeQuantize 出力ポートの精度をマークします。変換では、前に作成した PrecisionPreserved 属性インスタンスを使用します。変換を組み合わせて使用します。

  • CreateAttribute

  • PropagateThroughPrecisionPreserved

  • PropagateToInput

PropagatePrecisions 変換後のサンプルモデルの変更:

  • すべての精度を保持する操作は、必要な精度を定義する Precisions 属性インスタンスによってマークされます。

  • FakeQuantize 操作出力ポートは、分解のターゲット精度を定義する Precisions 属性インスタンスによってマークされます。サンプルモデルでは、FakeQuantize 操作には符号付き間隔がありますが、Precisions 属性は、畳み込み操作の変換制限中に適用される結果として、u8 (unsigned int8) 値によって初期化されます。

結果モデル:

PropagatePrecisions

AlignQuantizationIntervals モデルに量子化された連結操作がある場合は、AlignQuantizationParameters 変換が必要です。

6. AlignQuantizationIntervals

量子化操作を行うモデルには変換が必要です。この変換は、将来の量子化間隔の調整のため、さまざまな FakeQuantize 操作からの量子化情報を結合、FakeQuantize 操作と精度を保持するコンシューマーをマークします。変換を組み合わせて使用します。

  • CreateAttribute

  • PropagateThroughPrecisionPreserved

AlignQuantizationIntervals 変換後のサンプルモデルの変更:

  • すべての FakeQuantize 操作とその精度が保持されるコンシューマーは、IntervalsAlignment 属性インスタンスによってマークされます。

結果モデル:

AlignQuantizationIntervals

7. AlignQuantizationParameters

変換は、量子化された連結操作を行うモデルに必要です。変換は、FakeQuantize の精度を保持するコンシューマーをマークして、量子化の間隔を調整します。変換を組み合わせて使用します。

  • CreateAttribute

  • PropagateThroughPrecisionPreserved

  • UpdateSharedPrecisionPreserved

AlignQuantizationParameters 変換後のサンプルモデルの変更:

  • すべての FakeQuantize 精度を保持するコンシューマーは、QuantizationAlignment 属性インスタンスによってマークされます。convolution1 入力ポートは、空の精度コレクションを持つ Precisions 属性インスタンスによってマークされます。その結果、convolution1 操作は量子化されていないことが検出され、QuantizationAlignment 属性のデフォルト値 false は変更されません。convolution2 入力ポートは、空ではない精度コレクションを持つ Precisions 属性インスタンスによってマークされます。convolution2 操作が PerTensorQuantization 属性で量子化されていることが検出され、QuantizationAlignment 属性のデフォルト値が true に変更されました。

最終モデル:

AlignQuantizationParameters