トレーニング後の量子化は、モデルのサイズを小さくできる変換手法 CPU とハードウェア アクセラレータのレイテンシも向上します。 モデル精度の低下につながりますトレーニング済みの浮動小数点数を量子化できる TensorFlow モデルを LiteRT 形式に変換する場合は、 LiteRT コンバータ。
最適化手法
トレーニング後の量子化オプションはいくつかあります。こちらの 選択肢とそれぞれのメリットをまとめたものです。
技術 | 利点 | ハードウェア |
---|---|---|
ダイナミック レンジ 量子化 | 4 分の 1 の小型、2 ~ 3 分の 1 の高速化 | CPU |
整数 量子化 | 4 分の 1 の小型、3 倍以上のスピードアップ | CPU、Edge TPU マイクロコントローラー |
Float16 量子化 | 2 分の 1 の小型、GPU 加速 | CPU、GPU |
次のディシジョン ツリーを使用すると、トレーニング後の量子化のうちどれが 次の方法をおすすめします。
量子化なし
まずは、量子化なしで TFLite モデルに変換することをおすすめします。 ありますこれにより、浮動小数点型の TFLite モデルが生成されます。
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) tflite_quant_model = converter.convert()
元のデータが TF モデルの演算子は TFLite と互換性があり、 後続のトレーニング後に発生した量子化エラーをデバッグするためのベースライン あります。たとえば、量子化された TFLite モデルが 浮動小数点 TFLite モデルは正確ですが TFLite 演算子の量子化バージョンによって生じるエラーの問題です。
ダイナミック レンジの量子化
ダイナミック レンジの量子化によりメモリ使用量を削減し、計算を高速化 平均的なデータセットを用意する必要はありません。この 浮動小数点数からの重みのみを静的に量子化します。 を変換時に整数に変換します。これにより、8 ビットの精度が実現します。
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] tflite_quant_model = converter.convert()
推論中のレイテンシをさらに短縮するには、演算子 8 ビットの範囲に基づいて活性化を動的に量子化し、 8 ビットの重みと活性化関数を使って 計算を行いますこの最適化により ほぼ完全固定小数点の推論に近い点です。ただし出力は 浮動小数点数を使用して保存されるため、ダイナミック レンジ演算の速度の向上が 完全な固定小数点計算よりも効率的です。
完全整数量子化
レイテンシのさらなる改善、ピーク時のメモリ使用量の削減など、 整数のみのハードウェア デバイスまたはアクセラレータとの互換性を モデルの計算はすべて整数量子化されます。
完全な整数量子化では、範囲のキャリブレーションまたは推定が必要です。
例:モデル内のすべての浮動小数点テンソルの (min, max)。定数と異なる
重みやバイアスなどのテンソル、モデル入力などの可変テンソル、
活性化(中間層の出力)とモデル出力を
推論サイクルを数回実行しなければ
調整されませんその結果、コンバータは
キャリブレーションのための代表的なデータセットが必要です。このデータセットはサイズが小さくても
トレーニング データまたは検証データのサブセット(約 100 ~ 500 のサンプル)詳しくは、
representative_dataset()
関数を使用します。
TensorFlow 2.7 バージョンから、代表的なデータセットを 署名を返します。次に例を示します。
def representative_dataset(): for data in dataset: yield { "image": data.image, "bias": data.bias, }
特定の TensorFlow モデルに複数のシグネチャがある場合は、 署名キーを指定して複数のデータセットを指定します。
def representative_dataset(): # Feed data set for the "encode" signature. for data in encode_signature_dataset: yield ( "encode", { "image": data.image, "bias": data.bias, } ) # Feed data set for the "decode" signature. for data in decode_signature_dataset: yield ( "decode", { "image": data.image, "hint": data.hint, }, )
入力テンソルのリストを指定して、代表的なデータセットを生成できます。
def representative_dataset(): for data in tf.data.Dataset.from_tensor_slices((images)).batch(1).take(100): yield [tf.dtypes.cast(data, tf.float32)]
TensorFlow 2.7 バージョン以降では、シグネチャベースのアプローチを使用することをおすすめします。 リストベースのアプローチよりも優れている点が異なります。これは、入力テンソルの順序付けが 簡単に反転できます
テスト目的で、次のようにダミー データセットを使用できます。
def representative_dataset(): for _ in range(100): data = np.random.rand(1, 244, 244, 3) yield [data.astype(np.float32)]
浮動小数点数によるフォールバックありの整数(デフォルトの浮動小数点入力/出力を使用)
モデルを完全に整数量子化するには、浮動小数点演算子を使用する 整数の実装がない場合(変換をスムーズに行うため)、 次のとおりです。
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset tflite_quant_model = converter.convert()
整数のみ
整数のみのモデルの作成は、LiteRT for マイクロコントローラと Coral Edge TPU。
また、整数のみのデバイス(8 ビットなど)との互換性を確保するために、 マイクロコントローラなど)やアクセラレータ(Coral Edge TPU など)を使用する場合、 すべてのオペレーション(入力と出力を含む)の完全な整数量子化を、 次のとおりです。
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 # or tf.uint8 converter.inference_output_type = tf.int8 # or tf.uint8 tflite_quant_model = converter.convert()
Float16 量子化
浮動小数点数モデルのサイズを小さくするには、重みを float16(16 ビット浮動小数点数の IEEE 規格)。float16 を有効にするには 量子化するには、次の手順を使用します。
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_types = [tf.float16] tflite_quant_model = converter.convert()
float16 の量子化の利点は次のとおりです。
- モデルのサイズを最大で半分に削減できます(すべての重みが できます。
- 精度の低下は最小限に抑えられます。
- 動作可能な一部のデリゲート(GPU デリゲートなど)がサポートされています。 float16 データに対して直接実行するため、float32 データよりも高速に実行されます 説明します。
float16 の量子化のデメリットは次のとおりです。
- 固定小数点計算の量子化ほどレイテンシは短縮されません。
- デフォルトでは、float16 の量子化モデルは「逆量子化」します。重み値 float32 に設定します。(GPU デリゲートは この逆量子化は float16 データでも操作できるためです)。
整数のみ: 8 ビットの重みで 16 ビットのアクティベーション(試験運用版)
これは試験運用中の量子化スキームです。「整数のみ」関数と ただし、活性化は 16 ビット、重み、 8 ビット整数で量子化され、バイアスは 64 ビット整数に量子化されます。この 16x8 量子化と呼ばれます
この量子化の主な利点は、精度が向上することです。 モデルサイズをわずかに増やすだけです
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.representative_dataset = representative_dataset converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8] tflite_quant_model = converter.convert()
モデル内の一部の演算子で 16x8 の量子化がサポートされていない場合、 モデルは引き続き量子化できますが、サポートされていない演算子は浮動小数点数で保持されます。「 これを許可するには、target_spec に次のオプションを追加する必要があります。
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.representative_dataset = representative_dataset converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8, tf.lite.OpsSet.TFLITE_BUILTINS] tflite_quant_model = converter.convert()
この機能によって精度が向上したユースケースの例 次のような量子化スキームがあります。
- 超解像技術
- オーディオ信号処理(ノイズ キャンセリングやビームフォーミング、
- 画像ノイズ除去、
- 単一の画像からの HDR 再構成。
この量子化の欠点は次のとおりです。
- 現在、推論は、次の理由により、8 ビットの完全整数よりも著しく低速です。 最適化されたカーネル実装の欠如です。
- 現在、既存のハードウェア アクセラレーションされている TFLite との互換性はありません。 代議員数です。
この量子化モードのチュートリアルについては こちらをご覧ください。
モデルの精度
重みはトレーニング後に量子化されるため、精度が低下する可能性があります。 特に小規模なネットワークでは重要です事前トレーニング済みの完全量子化モデルは、 Kaggle の特定のネットワークに関する モデル をタップします。重要なのは、量子化モデルの精度をチェックして、 許容範囲内です。Google Cloud には、 LiteRT モデルの評価 正確さ。
精度の低下が大きすぎる場合は、量子化 トレーニング をタップします。ただし、そのためにはモデルのトレーニング中にモデルを修正し、 生成しますが、これに対するトレーニング後の量子化手法では、 既存の事前トレーニング済みモデルを使用します
量子化テンソルの表現
8 ビットの量子化では、次を使用して浮動小数点値を近似します。 示されます
\[real\_value = (int8\_value - zero\_point) \times scale\]
この表現は、主に次の 2 つの部分で構成されています。
軸ごと(チャンネルごと)、または int8 の 2 で表されるテンソルごとの重み ゼロ点が 0 である範囲 [-127, 127] の補数値
int8 の 2 の補数で表されるテンソルごとの活性化/入力。 範囲は [-128, 127] で、ゼロ点は [-128, 127] の範囲です。
Google の量子化スキームについて詳しくは、量子化 仕様をご覧ください。TensorFlow に接続したいと考えているハードウェア ベンダー Lite のデリゲート インターフェースでは、量子化スキームを実装することをおすすめします。 参照してください。