WWDC Quick Look 💓 By SwiftGGTeam
Get models on device using Core ML Converters

Get models on device using Core ML Converters

元の動画を見る

ハイライト

Core ML Tools は、WWDC 2020 で TensorFlow 1、TensorFlow 2、および PyTorch モデル変換を統合しますct.convertMIL を使用して動的形状を処理し、パスと複合演算を最適化し、トレーニング フレームワークによって出力されたモデルを Apple デバイスに展開できるモデルに変換します。.mlmodel

主要内容

多くのチームがモデルをトレーニングする場合、モデルの開始点は Apple プラットフォーム上にありません。ビジョン モデルは TensorFlow 2 の Keras API から取得され、レコメンデーション モデルは PyTorch から取得され、音声モデルは依然として TensorFlow 1 の凍結グラフである可能性があります。以前は、これらのモデルを Core ML に導入するには、開発者は複数の変換パスを覚えておく必要がありました。tfcoreml, PyTorch はまず ONNX をエクスポートし、それを ONNX Core ML に渡します。

このリンクの問題は、中間フォーマットが新たな障害点になることです。 PyTorch の新機能は ONNX エクスポータではカバーされていない可能性があり、ONNX 標準はフレームワークの進化と同期していない可能性があります。セッションは 04:22 で、2020 年の新しい PyTorch コンバーターがこの余分な依存関係レイヤーを削除することを明らかにしました。torch_script_modelCore ML は 1 ステップで入力できます。

Apple の変更は、変換エントリを Core ML Tools に統合することですct.convert。同じ API は TensorFlow 1、TensorFlow 2、または PyTorch モデルを受け取ることができます。コンバーターは、まずさまざまなフレームワークの表現をモデル中間言語 (MIL、モデル中間言語) に変換し、次にパブリック最適化と Core ML バックエンドを使用します。

このセッションは、API の名前変更時に停止しませんでした。 3 つの例を使用して、トランスフォーマーが処理できる内容を説明します。MobileNet は、最短パス TensorFlow 2 と PyTorch 変換を示しています。 DeepSpeech は、動的な形状が音声モデルにどのような影響を与えるかを示します。 T5 は TensorFlow の遭遇を示していますEinsumこのタイプのサポートされていない演算が存在する場合、MIL 合成演算を使用して、Core ML でサポートされている行列乗算に書き直すにはどうすればよいでしょうか。

詳細

Unified TensorFlow と PyTorch の変換の入り口

(02:56) TensorFlow 変換への変更は簡単です。従来は追加インストールが必要でしたtfcoreml、TensorFlow コンバーターが Core ML Tools に統合されました。セッション氏はまた、TensorFlow 2 のサポートが畳み込みモデルから LSTM やトランスフォーマーなどの動的モデルまで拡張されていると説明しました。

import coremltools as ct
import tensorflow as tf

tf_model = tf.keras.applications.MobileNet()
mlmodel = ct.convert(tf_model)

キーポイント:

  • coremltools直接呼び出す必要がある唯一の変換パッケージです。 -tf.keras.applications.MobileNet()TensorFlow 2 モデル オブジェクトを返します。 -ct.convert(tf_model)モデルの種類、入力形状、出力を自動的に識別し、MIL による変換を完了します。

(07:41) PyTorchの入り口も同様になりますct.convert。違いは、通常、TorchScript モデルには完全な入力形状がないことです。例では、ct.TensorTypeコンバータに明示的に渡されます。

import coremltools as ct
import torch
import torchvision

torch_model = torchvision.models.mobilenet_v2()

torch_model.eval()
example_input = torch.rand(1, 3, 256, 256)
traced_model = torch.jit.trace(torch_model, example_input)

mlmodel = ct.convert(
    traced_model,
    inputs=[ct.TensorType(shape=example_input.shape)]
)

キーポイント:

  • torch_model.eval()モデルを推論モードに切り替えて、トレーニング状態の動作がトレースされたモデルに入らないようにします。 -torch.jit.traceサンプル入力を使用して、TorchScript 表現を生成します。 -ct.TensorType(shape=example_input.shape)入力テンソル形状を Core ML コンバーターに追加します。
  • 同じct.convertTensorFlow と PyTorch を同時に提供すると、フレームワークごとに API を記録するコストが削減されます。

モデルのインターフェースをアプリが理解できる形式に整理します。

(09:23) PyTorch サンプルの変換が完了した後、Core ML モデルへの入力が呼び出されます。input.1、出力は次のように呼ばれます1648。これらの名前はソース モデル テンソルに由来するもので、アプリでは十分に明確ではありません。セッション用rename_featureインターフェース名を企業が理解できる名前に変更します。

spec = mlmodel.get_spec()
ct.utils.rename_feature(spec, "input.1", "myInputName")
ct.utils.rename_feature(spec, "1648", "myOutputName")
mlmodel = ct.models.MLModel(spec)

キーポイント:

  • get_spec()Core ML モデルの protobuf 仕様を取り出します。 -rename_feature入力および出力機能の名前を変更します。 -ct.models.MLModel(spec)変更された仕様を使用してモデル オブジェクトを再構築します。

(10:37) TensorFlow 1 の MobileNet の例では、別のタイプのインターフェイス構成も示しています。モデルが実際に画像を処理するとき、それは変換中に使用できます。ImageType入力の前処理を記述するには、次を使用します。ClassifierConfig分類子モデルを生成し、作成者、権限、説明を書き込みます。.mlmodel

import coremltools as ct
import tensorflow as tf

mlmodel = ct.convert("mobilenet_frozen_graph.pb",
                    inputs=[ct.ImageType(bias=[-1,-1,-1], scale=1/127.0)],
                    classifier_config=ct.ClassifierConfig("labels.txt"))

mlmodel.short_description = 'An image classifier'
mlmodel.license = 'Apache 2.0'
mlmodel.author = "Original Paper: A. Howard, M. Zhu, B. Chen, D. Kalenichenko, W. Wang, " \
                 "T. Weyand, M. Andreetto, H. Adam"

mlmodel.save("mobilenet.mlmodel")

キーポイント:

  • ImageType入力が画像であることをコンバーターに伝え、バイアスとスケールの前処理を宣言します。 -ClassifierConfig("labels.txt")カテゴリ ラベルを Core ML 分類子インターフェイスに取り込みます。 -short_descriptionlicenseそしてauthorがモデルのメタデータになります。 -save("mobilenet.mlmodel")出力は、Xcode の Core ML モデル ファイルに配置できます。

DeepSpeech などの動的形状モデルの処理

(15:45) DeepSpeech サンプルへの入力は音声前処理から取得されます。 12 秒のオーディオは 636 シーケンスに変換され、各シーケンスの幅は 19 で、26 の MFCC 係数が含まれます。静的 TensorFlow グラフは、一度に 16 シーケンスのみを処理できます。アプリまたはノートブックは、入力を複数のチャンクに分割し、LSTM 状態を維持する必要があります。

outputs = ["logits", "new_state_c", "new_state_h"]
mlmodel = ct.convert(tf_model, outputs=outputs)

input_dict["previous_state_c"] = np.zeros([1, 2048]).astype(np.float32)
input_dict["previous_state_h"] = np.zeros([1, 2048]).astype(np.float32)

while (start + step) < max_time_steps:
    input_dict["input_node"] = mfccs[:, start:(start + step), :, :]
    preds = mlmodel.predict(input_dict)
    input_dict["previous_state_c"] = preds["new_state_c"]
    input_dict["previous_state_h"] = preds["new_state_h"]

キーポイント:

  • outputsLSTM のロジットと 2 つの状態出力を保持するようにコンバーターに明示的に指示します。 -previous_state_cそしてprevious_state_h最初のオーディオセグメントの初期状態としてゼロに初期化されます。
  • 毎回predict16 シーケンスのみが処理され、新しい状態が入力辞書に書き戻されます。
  • このメソッドは静的モデルを通じて実行できますが、呼び出し元はセグメンテーションと状態を管理する必要があります。

(19:23) 同じ DeepSpeech モデルが動的グラフを再エクスポートした後、Core ML モデルは任意のシーケンス長を受け入れることができます。 Session はリバース機能も追加します。動的 TensorFlow グラフから開始する場合は、次の関数を渡すこともできます。inputs固定形状を渡し、型と​​値の推論により不要な動的操作を削除します。

import coremltools as ct

input = ct.TensorType(name="input_node", shape=(1, 16, 19, 26))
model = ct.convert(tf_model, outputs=outputs, inputs=[input])

キーポイント:

  • name="input_node"TensorFlow グラフ内の入力ノード名を揃えます。 -shape=(1, 16, 19, 26)固定ウィンドウへの狭い動的入力。
  • コンバーターは形状情報を伝播し、動的な再形状や形状の取得などの冗長な操作を削除します。
  • 一般に静的モデルの方がパフォーマンスが向上し、動的モデルは入力の長さが自然に変化するシナリオに適しています。

サポートされていない操作を MIL Builder と複合操作で処理する

(24:28) T5 の例は、変換中に TensorFlow に遭遇しますEinsumサポートされていない操作。セッションには 2 つのオプションがあります。Core ML カスタム レイヤーを使用し、アプリで Swift 実装を構成します。または、この操作を既存の MIL 操作に分割し、複合操作として保持します.mlmodelファイル内にあります。デモでは 2 番目のオプションが選択されました。

from coremltools.converters.mil import Builder as mb

@mb.program(input_specs=[mb.TensorSpec(shape=(1, 100, 100, 3))])
def prog(x):
    x = mb.relu(x=x)
    x = mb.transpose(x=x, perm=[0, 3, 1, 2])
    x = mb.reduce_mean(x=x, axes=[2, 3], keep_dims=False)
    x = mb.log(x=x)
    return x

キーポイント:

  • Builderこれは、MIL の Python ビルド エントリ ポイントです。 -TensorSpec入力形状を宣言します。デフォルトのタイプは次のように推論されます。Float32
  • mb.relumb.transposemb.reduce_meanそしてmb.logMIL プログラムを段階的に作成します。
  • MIL ビルダーは型と形状の推論をすぐに実行するため、各ステップの出力を簡単に確認できます。

(28:20) T5 によって使用Einsumフォームはbnqd,bnkd->bnqk。セッションはこれを 2 番目の入力を転置するバッチ行列乗算として認識するため、次のように TensorFlow 演算変換関数を登録できます。mb.matmul急行。

from coremltools.converters.mil import Builder as mb
from coremltools.converters.mil import register_tf_op

@register_tf_op
def Einsum(context, node):
    assert node.attr['equation'] == 'bnqd,bnkd->bnqk'

    a = context[node.inputs[0]]
    b = context[node.inputs[1]]

    x = mb.matmul(x=a, y=b, transpose_x=False, transpose_y=True, name=node.name)

    context.add(node.name, x)

キーポイント:

  • register_tf_opこの関数を TensorFlow フロントエンドに登録します。 -assert実際に T5 に表示されるもののみに処理を制限するEinsumパラメトリックフォーム。 -context[node.inputs[0]]そしてcontext[node.inputs[1]]ソース グラフの 2 つの入力テンソルを取得します。 -mb.matmul(..., transpose_y=True)すでにMILで利用可能な行列乗算を使用してこれを表現しますEinsum
  • context.add変換された MIL 値を元のノード名に接続し直すと、後続の変換プロセスが続行されます。

重要ポイント

1. 研究モデルをオフラインで実行できるアプリのプロトタイプに変える

  • やるべきこと: チームの既存の TensorFlow 2 または PyTorch イメージ モデルを.mlmodel, まずはオフライン認識のプロトタイプを作ります。
  • 実行する価値がある理由: このセッションの MobileNet の例は、Keras モデルと TorchScript モデルの両方が合格できることを示しています。ct.convertコア ML を導入します。
  • 開始方法: まずはノートブックで使用してくださいct.convertモデルを変換して再利用するmlmodel.save("model.mlmodel")エクスポートして、最後に Xcode にドラッグして、入力インターフェイスと出力インターフェイスを確認します。

2. 可変長オーディオ機能用の Core ML モデルを準備する

  • やるべきこと: ローカル音声コマンド認識または短い音声文字起こしを実装し、音声機能を Core ML に送信します。
  • 実行する価値がある理由: DeepSpeech の例では、レイテンシー、スループット、呼び出しの複雑さを比較するのに適した、固定形状と動的形状の 2 つの Core ML 出力を示します。
  • 開始方法: まず固定ウィンドウ モデルで検証しますoutputs=["logits", "new_state_c", "new_state_h"]状態を転送し、動的 ​​TensorFlow グラフをエクスポートして、モデルが完全な特徴シーケンスを受信できるようにします。

3. 変換に失敗したモデルに複合演算を追加します。

  • 対処方法: サポートされていない操作が見つかった場合は、まず既存の MIL 操作に分割できるかどうかを判断し、次に最小限の変換関数を追加します。
  • 実行する価値がある理由: T5Einsumこの例では、Swift カスタム レイヤーを作成しませんが、次を使用します。mb.matmulCore ML モデル ファイル内に留まります。
  • 開始方法: エラー トレースから op 名とパラメータを見つけ、使用します。register_tf_op同名の関数を登録して関数内で使用するBuilder結合された MIL op.

4. モデル変換後に配信パイプラインを確立する

  • やるべきこと: モデルのトレーニング、変換、インターフェイスの名前付け、Xcode のプレビュー、およびデプロイメントを繰り返し可能なプロセスに分割します。
  • 実行する価値がある理由: セッションでもわかりますrename_feature、モデルのメタデータ、ImageTypeおよび分類子構成。これらはすべてアプリ側の呼び出しエクスペリエンスに影響します。
  • 開始方法: 変換スクリプトの入力名と出力名を修正し、次のように記述します。short_descriptionlicenseそしてauthor、変換されたモデルを Core ML デプロイメント プロセスに渡して、公開を続行します。

関連セッション

コメント

GitHub Issues · utterances