アルゴリズム モデルをエンドツーエンドのインテリジェント モデルに変換するにはどうすればよいでしょうか?

アルゴリズム モデルをエンドツーエンドのインテリジェント モデルに変換するにはどうすればよいでしょうか?

エッジ インテリジェント テクノロジーのエンジニアリング プラクティスを紹介する前に、避けることのできない質問があります。エッジのコンピューティング パワーとは何でしょうか?ニューラル ネットワーク操作の高速化については聞いたことがあり、モバイル デバイスごとに高速化ソリューションが異なることも知っていますが、定量的な分析を行わずに明確かつ客観的に理解することは困難です。そこで、機械学習のHellowordプロジェクトのMnist手書き数字認識について小さな実験を行いました。同じアルゴリズムモデルをそれぞれMacBook ProとiPhoneで実行し、両側のトレーニングサンプル、モデル構造、モデルパラメータ、トレーニングパラメータなどを揃えて、最終的に図1の結果を得ました。60,000のトレーニングサンプルに直面して、i7 CPUを搭載した2015 15インチMacBook Proでは10エポックで128秒かかりますが、iPhone 13 Pro Maxではわずか86秒です。これは、端末の計算能力が、モデルを予測やトレーニングに使用するための計算能力要件を満たすことができることを証明するのに十分です。

図1 モバイル端末の速度は今どれくらいですか?同じモデルはiOSでは86秒、i7 MacOSでは128秒かかります

ただし、平均的なパフォーマンスのモバイル端末では、ユーザーエクスペリエンスを確保するために、コンピューティング能力の要件を測定し、フレームワークとプラットフォームのアルゴリズムモデルを最適化することも必要です。ここでのアルゴリズム モデルの最適化は 2 つの部分から構成されます。1 つはアルゴリズム モデル自体の圧縮、プルーニング、量子化、知識の蒸留などから成り、もう 1 つはフレームワークに付属するツールまたは JAX や TVM などのサードパーティ ツールから成り、アルゴリズム モデルをさまざまなプラットフォームで最適化されたモデルに変換します。最初の部分は、機械学習に関する関連研究から学ぶことができます。以下では、TensorFlow 機械学習フレームワークと iOS 機械学習テクノロジーによって提供されるツールに基づくエッジ インテリジェンスの技術的エンジニアリング基盤を紹介する第 2 部に焦点を当てます。

アルゴリズムモデルの評価と準備

アルゴリズムモデルの評価と準備を始める前に、まずは前回の記事で触れたiPhone 13 Pro Maxのプロセッサについて紹介しましょう。この A15 プロセッサは TSMC の 5nm プロセスを採用し、合計 150 億個のトランジスタを統合し、NPU パフォーマンスは 15.8TOPS に達します。 TOPS (Tera Operations Per Second)、1TOPS はプロセッサが 1 秒あたり 1 兆回の操作を実行できることを意味します。ハードウェアの計算能力と比較して、アルゴリズム モデルの複雑さは、計算能力要件 FLOP (浮動小数点演算) によって相対的に評価されます。これは、浮動小数点演算の量を指し、アルゴリズム モデルの複雑さを測定するために使用できます。図 2 からわかるように、アルゴリズム モデルのパラメーター、モデル サイズ、および FLOP はすべて、アルゴリズム モデルを評価するために使用される指標です。これらの指標は、パラメータスケールが大きいほどモデルが大きくなり、計算能力要件が高くなるという規則をほぼ示しているため、アルゴリズムモデルを評価するときは、図 1 のモデルパラメータスケール Total params: 585958 を使用して、モデルの計算能力要件を大まかに評価できます。ただし、AlexNet と ResNet152 はパラメータが少ないものの、モデルが大きく、FLOP が高いという状況にも注意する必要があります。これは主に、ネットワーク構造やオプティマイザーの違いなどの要因によって発生します。

図2. 一般的なアルゴリズムモデルの複雑さの比較

もちろん、モデルのパラメータは少ないが計算能力要件が高い状況を特定するために、より正確な評価が必要な場合、図 1 の計算能力要件では、580,000 パラメータのモデルを推定するには不十分です。TensorFlow の API を使用すると、モデルに必要な計算能力は 2.8 MFLOP であると計算できます。

 # TensorFlow 推奨の計算方法
tensorflow.python.framework.convert_to_constants からconvert_variables_to_constants_v2_as_graph インポートます

def get_lops ( モデル):
具体的な= tf . function ( lambda 入力: モデル( 入力))
コンクリート関数= コンクリート.get_concrete_function (
[ tf . TensorSpec ([ 1 , * inputs . shape [ 1 :]]) モデル内の入力に対して. inputs ])
フローズン関数グラフ定義= convert_variables_to_constants_v2_as_graph ( 具体的な関数)
tf.Graph (). as_default () グラフとして使用:
tf . graph_util . import_graph_def ( graph_def名前= '' )
run_meta = tf .compat .v1 .RunMetadata ()
opts = tf .compat .v1 .profiler .ProfileOptionBuilder .float_operation ( )
lops = tf . compat . v1 . profiler . profile ( graph = graphrun_meta = run_metacmd = "op"options = opts )
フロップスを返す。total_float_ops

print ( "FLOPS は:{}" . format ( get_lops ( model )) , flush = True )

もちろん、Pytorch アルゴリズム フレームワークを使用する場合は、計算能力の要件を評価するのに役立つ対応するツールが必要です。

 #推奨オープンソースツールpytorch - OpCounter
トップインポートプロファイルから
入力= torch.randn ( 1,1,28,28 )
macsparams = profile ( modelinputs = ( input 、 ))
print ( '合計 macc:{}, 合計 params: {}' . format ( macs , params ))
#出力: 合計macc : 2307720.0合計パラメータ: 431080.0

ハードウェアの計算能力に戻ると、AppleのA15プロセッサはNPUだけで15.8TOPSの計算能力を持っているのに対し、CPU+GPU+DSPを重ね合わせたQualcomm Snapdragon 855プロセッサのAI計算能力はわずか7TOPSです。アルゴリズムモデルをモバイル端末上でスムーズに実行するには、アルゴリズムモデルをAndroidやiOSのハードウェアアクセラレーション機能に適応できるように、アルゴリズムモデルに何らかの処理を施す必要があることがわかります。

アルゴリズム モデルをモバイル デバイス用に変換する方法は多数ありますが、フレームワークが提供する変換関数とサードパーティの変換ツールの 2 種類に大別できます。フレームワークが提供する変換関数の利点は、比較的単純で、API を介してモデルを直接変換できることです。欠点は、ランタイムがフレームワークに依存する必要があり、これらのランタイムに互換性がないことが多いことです。サードパーティの変換ツールは比較的面倒です。異なるツールを変換できるようにするには、モデルの入力に特別な要件があり、出力にも一定の制限があります。まずはフレームワークが提供する変換機能を見てみましょう。

すべてのフレームワークの変換方法を包括的に紹介することは、この記事の範囲を超えています。ここでは、TensorFlow が提供する変換関数を例に、一般的なモデル変換方法を紹介します。これらの方法は、さまざまなフレームワークで類似しています。ドキュメントで同様の機能を持つ API を見つけるだけで済みます。

TensorFlow でモデルを変換する主な状況は 2 つあります。1 つはモデルのデバッグとトレーニング中に変換することであり、もう 1 つはフレームワークがモデルを保存した後に変換することです。これら 2 つの状況の違いは、モデルのデバッグとトレーニング中に変換がよりシンプルで直感的であり、演算子の互換性などの問題をいつでも調整できることです。モデル ファイルを保存後に変換する場合、モデル定義と演算子はいつでも調整できません。ただし、保存後のモデル ファイルの変換は、入力としてのファイルによってモデルのトレーニングとモデルの変換を切り離すことができるため、エンジニアリング リンクを完了するのが簡単になります。私の提案は、エッジ インテリジェンス プロジェクトの初期段階で、デバッグ中およびモデル トレーニング中にフレームワーク機能を使用して変換し、その後、モバイル デバイスに展開してテストすることです。

 テンソルフローtf としてインポートする

# レベルtf.keras . * API 使用してモデル作成する
モデル= tf . keras . models . Sequential ([
tf . keras . レイヤー. ( 単位= 1input_shape = [ 1 ] )、
tf . keras . レイヤー. ( 単位= 16アクティベーション= 'relu' )、
tf . keras . レイヤー. ( 単位= 1 )
])
model.compile ( optimizer = 'sgd' , loss = 'mean_squared_error' ) # モデルコンパイルする
model.fit ( x = [ - 1,0,1 ], y = [ - 3 , -1,1 ] , epochs = 5 )# モデルトレーニングする
# ( SavedModel 生成する) tf .saved_model .save ( model , "saved_model_keras_dir" )

# モデル変換します
converter = tf.lite.TFLiteConverter.from_keras_model ( モデル)
tflite_model = converter.convert ( )

# モデル保存します
open ( 'model.tflite' , 'wb' ) f として実行します:
f .write( tflite_model ) を記述します

上記のコードでは、tf.keras API を使用して簡単なモデルを定義し、tf.lite.TFLiteConverter を使用して Keras モデルを TFLite モデルに変換し、最後に .tflite サフィックスを持つモデル ファイルとして保存します。これで、モデルの準備作業は完了です。

アルゴリズム モデル ファイルを TFLite に変換する場合は、TensorFlow が提供するコマンドライン ツールを使用できます。

 #SaveModel ファイルを変換する
python - m tflite_convert \
--saved_model_dir = /tmp/ mobilenet_saved_model \
--output_file = /tmp/mobilenet.tflite
#H5 形式のモデルファイルを変換する
python - m tflite_convert \
--keras_model_file = /tmp/mobilenet_keras_model.h5 \
--output_file = /tmp/mobilenet.tflite

最初のパラメーターは元のモデル ファイルの入力パスであり、2 番目のパラメーターは変換された TFLite モデルの出力パスです。

TensorFlow フレームワークは変換プロセス中に特定の最適化を行ったため、モデルの TOP も 2.8 MFLOP から 1.8 MFLOP に削減されました。ここでは、TFLite モデルの計算能力を評価するために、オープンソース ツール tflite_lops を使用します。以下の例に従ってインストールして使用できます。

 #インストール
pip3 git をインストール+ https://github.com/lisosia/tflite-lops
#使用
python - m tflite_lops モデル.tflite
#結果
OP_NAME | メガフロップス
-- -- -- -- -- -- -- -- -- -- -- -- -- --
変換_2D | 0.4
MAX_POOL_2D | < 無視>
変換_2D | 1.2
MAX_POOL_2D | < 無視>
再形成| < 無視>
完全に接続済み| < 無視>
完全に接続済み| < 無視>
SOFTMAX | < 無視>
-- -- -- -- -- -- -- -- -- -- -- -- -- --
合計: 1.6 M FLOPS

基本的に、エッジ インテリジェンスで使用されるモデルは、デスクトップとサーバーでトレーニングされたモデルから変換されます。この変換は、モバイル端末やエッジ デバイスごとに異なるため、変換が複雑になります。

オープンなニューラル ネットワーク交換標準である ONNX は、さまざまなフレームワークとさまざまなモバイルおよびエッジ デバイスのランタイムを標準化し、異なるフレームワークと異なるランタイム間でモデルを変換するコストを削減します。現在、主流のフレームワークとデバイスは ONNX をサポートしています。

 #ONNX モデルをインストールして変換するためのコマンドライン ツール
pip インストール-U tf2onnx
python - m tf2onnx . convert \
--saved - モデル./output/saved_model \
--output ./output/mnist1 . onnx \
--opset 7

上記は、TensorFlow コマンドライン ツールを使用してモデルを ONNX 形式に変換する例です。モデルを .onnx 形式に変換すると、ONNX ランタイムで直接実行できるだけでなく、さまざまなデバイスのランタイムに簡単にインポートして実行できます。主流の Android および iOS デバイスのランタイムは、次に示すように iOS をインポートするなど、ONNX 形式のモデルのインポートをサポートしています。

 coremltools をインポートする
onnxmltools をインポートする
# CoreML モデル入力パス更新します
input_coreml_model = 'モデル.mlモデル'

# このパスをONNX モデル出力パス変更します
output_onnx_model = 'model.onnx'
# CoreML モデルロードする
coreml_model = coremltools.utils.load_spec ( input_coreml_model )

# CoreML モデルONNX 変換する
onnx_model = onnxmltools.convert_coreml ( coreml_model ) です

# protobuf として保存
onnxmltools.utils.save_model (onnx_model output_onnx_model )

もう一つの重要な方法はコンパイルです。機械学習はフレームワークのランタイムで解釈され実行されるのではないのかと疑問に思うかもしれません。コンパイルプロセスを実行する意味は何でしょうか?実際、ここには多くの知識があります。さまざまなランタイムの基本的な互換性要件は別として、さまざまなハードウェアのアクセラレーション機能のためだけでもやるべき作業は多く、ソフトウェア エンジニアは膨大な労力を費やす必要があります。私がUC International Browserで行った超解像度プロジェクトを例に挙げてみましょう。ネットワーク環境の悪いインドのユーザーがより高精細な画像や動画を楽しめるように、超解像度アルゴリズムモデルをトレーニングしました。このモデルアルゴリズムは、ARMのNEON命令セットアクセラレーションに基づいて、ミッドエンドおよびローエンドモデル向けに最適化されており、240pの動画を毎秒24フレームの速度でリアルタイムに720pに変換できます。しかし、このプロジェクトの最大の課題はアルゴリズムモデルではありません。Githubで検索すると、多くの超解像度SOTAモデルが見つかります。圧縮刈り込み、量子化、知識蒸留、精度低下などの最適化方法も簡単に見つけて適用できます。ただし、これらの最適化は、ニューラルネットワークの計算能力に対する基本的な要件を変更するものではありません。ビデオのデコード、メモリ、データ転送のパフォーマンス消費と相まって、ミッドエンドおよびローエンドモデルでビデオ超精細アルゴリズムモデルを実行することは容易ではありません。過去6か月間、アルゴリズムエンジニアのHuang Zhenは、Androidの低レベルのR&Dエンジニアになることを余儀なくされました。NEON命令セットとAndroidのオープンな低レベル最適化機能に基づいて、機能を絞り込み、計算電力の消費を少しずつ圧縮することで、パフォーマンスが3〜5フレーム/秒から24フレームに向上しました。

コンパイルベースのモデル最適化

機械学習技術エコシステムの発展に伴い、ニューラルネットワークの最適化の複雑さとコストを削減するために、機械学習分野に携わる大手企業は、PlaidML、TVM、JAX、MLIRなど独自のソリューションを提案してきました。 Google の XLA (Accelerated Linear Algebra) は、グラフ最適化と演算子最適化の階層的最適化の考え方を打ち破ります。XLA は、バックエンドに依存しない最適化に使用される HLO (High Level Optimizer) と IR の 2 つの部分に分かれています。これには、ニューラル ネットワークの基礎となる計算グラフに関連する最適化のほか、共通部分式の削除や強度の削減などの従来の最適化手法も含まれます。複数のバックエンドに対する llvm コンパイル アーキテクチャの利点を最大限に活用し、デバイス関連のコード生成と最適化を llvm に任せることができるのが利点です。同様に、Facebook の Glow にもこれら 2 つの最適化レイヤーが含まれています。Glow は複数のバックエンドと新しいチップに重点を置いていますが、XLA と Glow はどちらも llvm との組み合わせに重点を置いて、既存の最適化手法を最大限に活用しています。

JAX は、科学計算と関数変換の相互統合、およびディープラーニング モデルのトレーニングに重点を置いています。また、次の機能も備えています。

  1. ジャストインタイムコンパイル
  2. 自動並列化
  3. 自動ベクトル化
  4. 自動微分化

JAX を利用してアルゴリズム モデルを準備する方法を実際の例を使って学習しましょう。最初のステップは依存関係をインストールすることです。

 pip install tf - ナイトリー--upgrade
pip インストールjax --upgrade
pipjaxlib をインストール--upgrade

次に、Jupyter Notebook を開いて実験を開始し、必要な Python パッケージをインポートします。

 numpyをnp としてインポートする
テンソルフローtf としてインポートする
関数ツールをインポートする
インポート時間
itertools をインポートする
numpy.random をnpr としてインポートする
# JAX 新パーツ
jax.numpy をjnp としてインポートします
jax からjitgradrandom をインポートします
jax から実験的なインポートオプティマイザー
jax から実験的なインポートstax

トレーニング サンプルと検証セット関連のデータを準備します。ここでも、mnist を例として取り上げます。

 _one_hot を定義します( xkdtype = np.float32 ) :
"" "サイズ k の x のワンホットエンコーディングを作成します。" ""
np.array ( x [:, None ] == np.arange ( k ), dtype ) 返す

( train_images , train_labels ) , ( test_images , test_labels ) = tf.keras.datasets.mnist.load_data ( )
トレーニング画像テスト画像= トレーニング画像/ 255.0テスト画像/ 255.0
train_images = train_images.astype ( np.float32 ) です
test_images = test_images.astype ( np.float32 ) です

列車ラベル= _one_hot ( 列車ラベル10 )
test_labels = _one_hot ( test_labels , 10 )

次に、先ほど紹介した JAX パッケージが提供する API を使用してモデルを定義します。

 init_random_params予測= stax . serial (
スタックス平らにする
スタックス. デンス1024 )、 スタックス. レル
スタックス. デンス1024 )、 スタックス. レル
スタックス. デンス( 10 )、 スタックス. ログソフトマックス)

これは、Keras を使用した以前のモデル定義とは少し異なりますが、注意深く見れば、Dense、Relu、Softmax など、多くの馴染みのある部分が見つかるはずです。これらのニューラル ネットワーク レイヤーとオプティマイザーの定義は、従来の機械学習アーキテクチャによって提供される機能に似ており、モデルの定義とトレーニングに使用されます。トレーニングの具体的な手順についてはここでは説明しません。JAX を使用する場合は、Tensorflow の公式 Web サイトにアクセスして完全な例を確認してください。次に、モデルの変換と保存について見てみましょう。

 サービング関数= functools.partial ( 予測パラメータ)
x_input = jnp . ゼロ( ( 1 , 28 , 28 ))
コンバーター= tf.lite.TFLiteConverter.experimental_from_jax (
[ サービング関数], [[( 'input1' , x_input )]])
tflite_model = converter.convert ( )
open ( 'jax_mnist.tflite' , 'wb' ) f として実行します:
f .write ( tflite_model ) を記述します

変換には引き続き TFLiteConverter を使用しますが、jax モデルを TFLite 形式に変換することは、前に紹介したモデル変換と変わりません。したがって、jax モデルの定義とトレーニング プロセスも Tensorflow.keras に置き換えることができます。jax を使用する利点は、モデル トレーニングによって、jax JIT 環境で TPU、GPU、NPU などのハードウェアの加速機能が最大限に発揮されることです。 (具体的なサポート情報については、JAX のドキュメントを参照してください)

2022年初頭現在、JAXはまだ実験的なフレームワークであり、モデルのコンパイルと高速化は主にモデルの定義とトレーニングの段階に集中しています。モデルがTFLiteに変換され、モバイルフォンに展開されると、JAX JITではなくTFLiteのランタイムに依存します。最後にJAXを使用するとパフォーマンスの高速化が達成されるという誤った考えを避けるために、これを明確に認識する必要があります。ここで JAX を紹介する理由は、ローエンドの Android フォンで超解像度を実行するように、機械学習を徹底的に実践し続けると、パフォーマンスの最適化で多くのボトルネックが発生するからです。JAX を使用すると、Keras の高レベル API をバイパスし、低レベルになりすぎて複雑さが急増することなく、ニューラル ネットワークの低レベル機能をさらに最適化できます。

アルゴリズム モデルを最適化するためのもう 1 つのツールは、Apache Software Foundation が後援するオープン ソースの機械学習コンパイル フレームワークである TVM です。JAX と比較すると、ランタイム最適化に重点を置いており、特にモバイル デバイスのサポートが優れており、拡張が容易です。従来のモバイル プロセッサとニューラル ネットワーク アクセラレータに加えて、ZYNQ などの FPGA ニューラル ネットワーク アクセラレーション ハードウェアもサポートされています。DSP、CPLD などを使用して独自のアクセラレーション ハードウェアを定義し、TVM コンパイル サポートを追加することもできます。TVM は、特定のハードウェアに合わせてモデルを自動的に最適化します。

TensorFlow.js と ONNX.js はブラウザに機械学習をもたらし、この本の冒頭では Tensorflow.js をベースにした例が紹介されていますが、Web バージョンとネイティブ バージョンの間には依然としてパフォーマンスに大きな差があります。理由の 1 つは、Web 上で GPU への標準的で高性能なアクセスが不足していることです。WebGL には、高性能なディープラーニングに必要なコンピューティング シェーダーや共通ストレージ バッファーなどの重要な機能が欠けています。

次世代の Web グラフィックス標準である WebGPU は、この状況を劇的に変える可能性を秘めています。 Vulkan や Metal などの最新世代のグラフィックス API と同様に、WebGPU は第一級のコンピューティング シェーダー サポートを提供します。ブラウザでの機械学習の展開に WebGPU を使用する可能性を探るため、TVM は WASM (起動パラメータの計算とデバイス起動用のホスト コードの呼び出し用) と WebGPU (デバイス実行用) をターゲットにし、GPU 上でネイティブに近いパフォーマンスを提供しながら、Web 上で機械学習アプリケーションを展開します。

図3 WebGPU、Metal、OpenCLIのパフォーマンス比較(TVM公式サイトより)

TVM の WebGPU バックエンド経由でネイティブに実行された完全な計算グラフと、ネイティブ GPU ランタイム (Metal と OpenCL) を使用して MobileNet モデルで比較すると、WebGPU が Metal のパフォーマンスに近いことがわかります。また、Chrome WebGPU ランタイムは MacOS で OpenCL ではなく Metal をターゲットにしているため、GPU をターゲットにしたニューラル ネットワーク アクセラレーションではパフォーマンスの低下はほとんどないと想定できます。

このベンチマークには、CPU から GPU へのデータコピーのコストは含まれず、GPU 実行のみがベンチマークされます。現在、CPU から GPU へのデータのコピーには実行時間の 25% がまだかかりますが、連続実行設定でのダブルバッファリングなどの方法によってこれらのコストをさらに削減できます。

WebGPU を試すためのアプローチは、ディープ ニューラル ネットワークの基本演算子 (行列乗算と畳み込み) 用のシェーダーを記述し、そのパフォーマンスを直接最適化することです。これは、TensorFlow.js などの既存のフレームワークで使用される従来のワークフローです。 TVM は異なります。コンパイルベースのアプローチを使用して、ネイティブに近いパフォーマンスを提供します。 TVM は、TensorFlow、Keras、PyTorch、MXNet、ONNX などの高度なフレームワークからモデルを自動的に抽出し、機械学習主導のアプローチ (機械学習機能を使用して AI に最適化方法を決定させる) を使用して、より最適化されたネイティブ コードを自動的に生成します。

コンパイルベースのアプローチの重要な利点は、基礎となるレイヤーの再利用です。基礎となるレイヤーを再利用して、CUDA、Metal、OpenCL などのターゲット プラットフォーム向けに GPU カーネルを最適化することで、TVM を Web 向けに簡単に最適化できます。 WebGPU API からネイティブ API へのマッピングが効果的であれば、TVM を使用すると、ほとんど作業せずに Web 上で同様のパフォーマンスを実現できます。さらに重要なのは、AutoTVM インフラストラクチャにより、特定のモデル向けにコンピュート シェーダーを特化できるため、関心のある特定のモデルに最適なコンピュート シェーダーを生成できることです。 (このカスタマイズ機能は、前述のカスタム ハードウェア アクセラレーションと一致しています)

Web 用の WASM および WebGPU ベースのエンディアン アプリケーションを構築するには、次のコンポーネントが必要です。

  1. コンピュートシェーダー用の SPIR-V ジェネレーター。
  2. ホスト プログラム用の WASM ジェネレーター。
  3. 生成されたプログラムを読み込んで実行するランタイム。

幸いなことに、TVM はすでに Vulkan 用の SPIR-V ターゲットを提供しており、LLVM を使用してホスト コードを生成するため、両方を再利用してデバイス プログラムとホスト プログラムを生成することができます。

TVM には最小限の C++ ベースのランタイムがあり、最小限の Web ランタイム ライブラリを構築し、生成されたシェーダーおよびホスト ドライバー コードとリンクして、単一の WASM ファイルを生成します。 TVM の JS ランタイムに WebGPU ランタイムを構築し、GPU コードを呼び出すときに WASM モジュールからこれらの関数をコールバックします。図 4 に示すように、TVM ランタイム システムの PackedFunc メカニズムを使用すると、JavaScript クロージャが WASM インターフェイスに渡され、高レベルのランタイム プリミティブが直接公開されます。

図4 TVM側のインテリジェントエンジニアリングリンク(TVM公式サイトより)

WASI と WASM の助けを借りて、TVM はフロントエンドでいくつかの一般的な AI アルゴリズム モデルを優れたパフォーマンスで Web ベース環境に簡単にコンパイルできるようにします。

図5 従来の機械学習フレームワークTVMとの比較(TVM公式サイトより)

図5に示すように、TVMアーキテクチャは、特にエンドツーエンドのインテリジェンス分野におけるさまざまなオペレーティングシステムとハードウェアデバイスの加速機能の点で、より柔軟です。開発者は手動で適応および最適化する必要がなくなり、エンドツーエンドのインテリジェンスプロジェクトの効率が大幅に向上します。以下は、TVM の使用方法を示す具体的な例です。これにより、この方法が技術エンジニアリング システムに適合するかどうかを評価できます。

始める前に、Github から ONNX モデルをダウンロードしましょう。

 https://github.com/onnx/models/raw/main/vision/classification/resnet/model/resnet50-v2-7.onnx ​ を実行します。

モデルのアドレスは変更される可能性があるため、ダウンロードに失敗した場合は、https://github.com/onnx/models/ でモデルを再度検索してダウンロードできます。

次に、必要なソフトウェアをインストールする必要があります。ここでは、MacOS を例にインストール プロセスを紹介します。他のシステムについては、TVM の公式 Web サイト tvm.apache.org を参照してください。

 brew gcc git cmake をインストール
llvm をインストールします
Python3.8 をインストールします

インストールが完了したら、ソース コードをダウンロードして構成ファイルを生成します。

 git clone --recursive https://github.com/apache/tvm tvm
CDTVM
mkdir ビルド
cp cmake / config .cmake ビルド

ここで注意する必要があるのは、コンパイルオプションの変更です。ローカルでテストしたい場合は、set(USE_LLVM ON) のデフォルトの OFF スイッチを ON に変更する必要があります。 CUDA バックエンドを有効にする場合は、TVM 用の他のバックエンドとライブラリ (OpenCL、AMD エコシステム RCOM、APPLE エコシステム METAL、VULKAN など) をビルドし、スイッチ セット (USE_CUDA ON) を有効にする必要があります。

 CD ビルド
.. のcmakeを実行します
作る- j4

コンパイルを開始するときは、-j4 コンパイル オプションに注意し、自分のスレッドと CPU コアに応じて適切に設定し、コンパイル結果を待ちます。私は、MacOS 12.2.1 バージョン システムを使用して、コンパイルを 1 回で完了しました。次に、Python ライブラリをインストールします。

 pip3 インストール--user numpy デコレータattrs tornado psutil xgboost cloudpickle
pip3 インストール--user onnx onnxoptimizer libomp pillow
export MACOSX_DEPLOYMENT_TARGET = 10.9 #この環境変数はlibstdc ++の競合を解決するために使用されます
cd python ; python セットアップ。py install --user ; cd ..

TVM の最適化は 3 つのレイヤーに分かれていることに注目してください。第 1 レイヤーは、TVM によって直接コンパイルされたモデルに、コンパイル レベルの最適化がいくつか施されるというものです。第 2 レイヤーは、TVM が提供する自動最適化ツールであるオートチューナーを使用して、CPU、GPU、NPU、TPU などのさまざまなターゲット向けに最適化されたコードを生成するというものです。第 3 レイヤーは、TVM の分析ツールとカスタム調整機能を使用して、モデルのパフォーマンスをさらに最適化するというものです。通常、エッジ インテリジェンスの分野で第 2 レベルの最適化機能を習得できれば、ほとんどのシナリオに対応できます。ただし、入力処理、CPU、メモリ、I/O などの最適化に対する取り組みのバランスを取る必要があります。

開始する前に、TVM のコンパイルと最適化の結果の検証を容易にするために、モデル予測入力を生成するための Python スクリプトと、モデル予測結果を解析するためのスクリプトの 2 つの Python スクリプトを準備する必要があります。

 #!python ./preprocess.pyはモデル入力を生成するために使用されます
tvm . contrib . download からdownload_testdata をインポート
PIL インポート画像から
numpyをnp としてインポートする
img_url = "https://s3.amazonaws.com/model-server/inputs/kitten.jpg"
img_path = download_testdata ( img_url"imagenet_cat.png"モジュール= "data" )
# 224x224 サイズを変更します
resized_image = 画像.open ( img_path ) .resize ( ( 224,224 ))
img_data = np . asarray ( resized_image ). astype ( "float32" )
# ONNXはNCHW 入力を期待しているので配列変換します
img_data = np . transpose ( img_data , ( 2 , 0 , 1 ))
# ImageNet に従って正規化する
imagenet_mean = np . 配列([ 0.485 , 0.456 , 0.406 ])
imagenet_stddev = np . 配列([ 0.229 , 0.224 , 0.225 ])
norm_img_data = np . zeros ( img_data . shape ). astype ( "float32" )
i範囲( img_data . shape [ 0 ] ) の場合:
norm_img_data [ i , :, :] = ( img_data [ i , :, :] / 255 - imagenet_mean [ i ]) / imagenet_stddev [ i ]
# バッチディメンションを追加
img_data = np . expand_dims ( norm_img_dataaxis = 0 )
# .npz 保存( imagenet_cat .npz を出力)
np . savez ( "imagenet_cat"データ= img_data )

TVM を使用して、予測のために先ほどダウンロードした画像分類モデルを実行し、予測結果を解析する必要もあります。

 #!python ./postprocess.py
os.path インポートする
numpyをnp としてインポートする
scipy から. special import softmax
tvm . contrib . download からdownload_testdata をインポート
# ラベルリストダウンロードする
labels_url = "https://s3.amazonaws.com/onnx-model-zoo/synset.txt"
labels_path = download_testdata ( labels_url"synset.txt"module = "data" )
open ( labels_path , "r" ) f として:
ラベル= [ l . rstrip () lf 入れる ]
出力ファイル= "予測.npz"
# 出力開いて出力テンソル読み取ります
os.path . が存在する場合( output_file ):
np . load ( output_file ) データとして:
スコア= softmax ( データ[ "output_0" ])
スコア= np . squeeze ( スコア)
ランク= np . argsort ( スコア)[:: - 1 ]
順位[ 0 : 5 ] :
print ( "クラス='%s'、確率=%f" % ( ラベル[ 順位]、 スコア[ 順位]))

次に、最初のレイヤーに入り、TVM ツールを使用してモデルをコンパイルします。

 python -m tvm.driver.tvmc コンパイル\  
--target "llvm" \
-- 出力resnet50 - v2-7 - tvm.tar \
resnet50 - v2-7.onnx

モジュールで作成されたファイルを見てみましょう: tvmc compile

 mkdir モデル
tar - xvf resnet50 - v2 - 7 - tvm . tar - C モデル
ls モデル

3 つのファイルがリストされます。

  • mod.so は、TVM ランタイムによってロードできる C++ ライブラリとして表されるモデルです。
  • mod.json は TVM 計算グラフのテキスト表現です。
  • mod.params は、事前トレーニング済みのモデル パラメータを含むファイルです。

モデルと入力データが手元にあるので、TVMC を実行して予測を行うことができます。

 python -m tvm.driver.tvmc 実行\  
--inputs imagenet_cat . npz \
-- 出力予測.npz \
resnet50 - v2-7 - tvm.tar

.tar モデル ファイルには、C++ ライブラリ、Relay モデルの計算グラフのテキスト表現、およびモデルのパラメーターが含まれていることに注意してください。 TVMC には、モデルをロードして入力を予測できる TVM ランタイムが含まれています。上記のコマンドを実行すると、TVMC は NumPy 形式のモデル出力テンソルを含む新しいファイル predictions.npz を出力します。

この例では、モデルをコンパイルするために使用したのと同じマシンでモデルを実行します。場合によっては、RPC Tracker を介してリモートで実行する必要があることもあります。これらのオプションの詳細については、 をご覧ください。

 python -m tvm . ドライバー. tvmc 実行--help 

図6: 子猫の写真

次に、後処理された予測結果と図 6 を入力として使用して、モデルの分類予測精度を確認します。

 Python 後処理.py
# クラス= 'n02123045 トラ猫、トラ猫' 確率= 0.610553
# クラス= 'n02123159 トラ猫' 確率= 0.367179
# クラス= 'n02124075 エジプト猫' 確率= 0.019365
# クラス= 'n02129604 トラ、Panthera tigris' 確率= 0.001273
# クラス= 'n04040759 ラジエーター' 確率= 0.000261

TVMC はモデルのパラメータ空間を検索し、さまざまな構成を試して、指定されたターゲット上で最も高速なパラメータを生成します。これは CPU とモデルに基づいたガイド付き検索ですが、検索が完了するまでに長い時間がかかる場合があります。この検索の出力は resnet50-v2-7-autotuner_records.json ファイルに保存され、後で最適化されたモデルをコンパイルするために使用されます。

 python -m tvm.driver.tvmc tune \  
--target "llvm" \
-- 出力resnet50 - v2-7 - autotuner_records.json \
resnet50 - v2-7.onn

--target llvm -mcpu=skylake フラグに、より具体的な最適化ターゲットを指定すると、より良い結果が得られます。以前の -mcpu パラメータは Intel プロセッサで使用でき、LLVM は指定された CPU アーキテクチャに合わせてコンパイルを最適化します。 MacOS では、sysctl machdep.cpu コマンドを使用してプロセッサの詳細情報を表示し、プロセッサの公式 Web サイトにアクセスして、その情報に基づいてアーキテクチャ コードを照会できます。

しばらく待つと、次の情報と .json ファイルに含まれる調整データを取得できるはずです。

 [ タスク25/25 ] 現在/ 最高: 29.87 / 29.87 GFLOPS | 進行状況: ( 40/40 ) | 64.33 完了

モデルのチューニングデータを収集したので、最適化された演算子を使用してモデルを再コンパイルして計算を高速化できます。

 python -m tvm    
- ターゲット「llvm」 \
-Tuning -Resnet50 -V2-7 -AutoTuner_Records.json \
-output Resnet50 -V2-7 -TVM_AUTOTUNED.TAR \
Resnet50 -V2-7.onnx

最適化モデルが実行され、同じ結果が生成されることを確認します。

 Python -M TVMC    
- Imagenet_catを入力します
- 出力予測.npz \
ResNet50 -V2-7 -TVM_AUTOTUNED.TAR

python postprocess.py

予測が以前と同じであることを確認してください。

 #class = 'n02123045 tabby、tabby cat ' 確率= 0.610550
#class = 'n02123159タイガーキャット' 確率= 0.367181
#class = 'n02124075エジプト猫' 確率= 0.019365
#class = 'n02129604 tiger、panthera tigris ' 確率= 0.001273
#class = 'n04040759ラジエーター' 確率= 0.000261

TVMCは、モデル間の基本的なパフォーマンスベンチマークツールを提供し、TVMCはモデルのランタイムをレポートします。チューニングがモデルのパフォーマンスをどれだけ改善するかについて、大まかなアイデアを得ることができます。たとえば、Intelプロセッサでのローカルテストでは、調整されたモデルは、先に戻されたモデルよりも30%以上速く実行されます。

 #optimizedモデル
Python -M TVMC
- Imagenet_catを入力します
- 出力予測.npz \
-print -time \
- 繰り返し100 \
ResNet50 -V2-7 -TVM_AUTOTUNED.TAR

実行時間概要
平均ms中央値msmaxmsminmsstdms
108.9112 106.0590 172.0100 103.3303 10.4451

#UNOPTIMIZEDモデル
Python -M TVMC
- Imagenet_catを入力します
- 出力予測.npz \
-print -time \
- 繰り返し100 \
ResNet50 -V2-7 -TVM.TAR

実行時間概要
平均ms中央値msmaxmsminmsstdms
135.0077 131.8776 202.7213 124.4521 11.0818

これらのデータは、TVMの公式Webサイトの例では、ターゲットとモデルによって異なる場合がありますが、全体的な改善効果は非常に明白です。同時に、TVMをコンパイルして構築するとき、コンピレーションオプションは、ここでピットに踏み込んで再コンパイルしてインストールすることに直接影響することに注意する必要があります。

これまでのところ、アルゴリズムモデルをエンドツーエンドのインテリジェントモデルに変換する方法を学び、2つの典型的なモデルコンパイルツール、JAXとTVMを使用して、モデルのパフォーマンスを最適化する方法を学習およびマスターしました。より多くの関連コンテンツが後で共有され、興味のある学生は注意を払うことができます。

チームについて

私たちは、アリババ・タオバオのテクノロジーショッピングガイドおよびマーケティング製品(以前はチャンネルとD2Cインテリジェントチーム)であり、アリババ経済のフロントエンド委員会のインテリジェントな方向性の中核チームです。 ES)。

私たちは杭州アリババxixi公園で働いています。

私たちの目標は、「詩人のロマンスと科学者の厳しさを使用して、AIを最もよく理解しているスマートで国際的なフロントエンドチームを構築する」ことです。

私たちの使命は、「フロントエンドインテリジェンスがビジネスイノベーションをより効率的にする」ことです。

<<:  アリババDAMOアカデミーがAIの人間の言語理解の向上を支援する論文でSemEval最優秀賞を受賞

>>:  エッジ vs. クラウド: どちらの AI インフラストラクチャを選択すべきか?

ブログ    

推薦する

2024年はテクノロジー企業の終焉となるでしょうか?報告書:3年後には技術の80%が素人によって提供される

[[405703]]最近、アメリカの有名なテクノロジー調査・コンサルティング会社であるガートナーは、...

...

90年代のアンティークコンピューターでCNNをトレーニングしました

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

5G、IoT、AI、機械学習は2021年に最も重要なテクノロジーとなる

[[353503]]画像ソース: https://pixabay.com/images/id-575...

コストを 95% 削減した ChatGPT の代替品を作成しましょう! OpenAIのハードコアアップデートが来月リリースされ、ビジュアルAPIが登場

世界中の開発者は長い間、OpenAI モデルの価格に悩まされてきました。ロイター通信は、11月6日に...

人工知能業界の最新の開発動向を1つの記事で理解する

[[418444]]現在、新世代の人工知能に代表される科学・産業革命が起こりつつあります。デジタル化...

AIが髪の毛に至るまで肖像画を生成!北京大学卒業生の最新研究が2.8千個の星を獲得

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

二次編集やUnreal Engine 5へのインポートをサポートし、Stable Diffusionは3D生成機能に進化

全体像を捉えるモデルに関して言えば、Stability AI が 2022 年にリリースした Sta...

第1回自動車開発者会議(2021)が成功裏に終了しました

10月20日、国家インテリジェントコネクテッドビークルイノベーションセンター(以下、「イノベーション...

...

AIの新たな方向性:敵対的攻撃

[[249559]]近年のAI分野を調査していく中で、近年、世界中の研究者の視野の中に敵対的攻撃とい...

中国移動のチーフサイエンティスト、馮俊蘭氏との独占インタビュー:AIビジネスアプリケーションは何度も融合する必要がある

「インテリジェンス」が本格的に到来!人工知能(AI)は、科学技術革命と産業変革の新たなラウンドにおけ...

人工知能の雇用に関するレポートによると、GenAI は米国のほぼすべての仕事に影響を与えるだろう

世界有数の求人サイトおよび採用プラットフォームである Indeed は、Indeed AI 求人レポ...

インテリジェントデータベースに基づくセルフサービス機械学習

翻訳者 | 張毅校正 | 梁哲、孫淑娟1. IDOになるにはどうすればいいですか? IDO (インサ...