生き抜くぜ21世紀

統計?機械学習?っぽいことを書く

TensorFlowのSavedModelの便利さを紹介する

はじめに

今は2020年8月なのですが、コロナ禍だし、暑いし、経済状況最悪で暇だし、良いことないですね。

暇になったので、1年ぶりにkaggleをやってみました。

Landmark Retrievalという建物の画像検索コンペに出たところ、そのコンペの提出形式がTensorFlowのSavedModel形式でした。

私はTensorFlow案件をけっこうやってきたので抵抗はなかったのですが、この制約が原因となったのか、あまりこのコンペの参加者は多くなかったようです。

kaggleの提出形式としては賛否両論あると思いますが、実務ではとても便利な形式だと私は思っています。

それなのにもし実務でも敬遠されているとしたらもったいないと思い、この記事ではSavedModelの便利さについて紹介してみます。

ちゃんとした使い方は公式リファレンスを当たってもらうとして、概念やsaved_model_cliの活用方法をお伝えするのを主眼に置いています。

目次

  • SavedModelとは
  • SavedModelの何が便利なのか
  • SavedModel使い方リンク集

SavedModelとは

SavedModelとは、TensorFlowのモデルを保存する形式のひとつです。

特徴はモデルのweightとネットワーク構造が一緒に保存されることです。

そのため、ユーザはこのSavedModel形式で保存されたモデルさえあれば推論をすることが可能です。

このようにモデルを復元するのに必要な情報がすべて格納されているため、さらに別の形式(TensorFlow Liteなど)に変換するための中間形式としてこのSaved Modelを使用することもあります。

ちなみに、SavedModel形式に対して、Checkpoint形式という形式もあります。(こちらの方が一般的と言って良いと思います)

このCheckpoint形式ではモデルのweightのみが保存され、ネットワーク構造は保存されません。ネットワーク構造はソースコードで定義する必要があります。

SavedModelの何が便利なのか

SavedModelで個人的に便利と感じている点は以下の3点です。

  • 学習環境と推論環境でのソースコードの二重管理が防げる
  • saved_model_cliを活用することで、ネットワークのin/outを楽に・確実に確認することができる
  • TensorFlow Servingで簡単にデプロイできる

それぞれについて、詳しく説明します。

学習環境と推論環境でのソースコードの二重管理が防げる

機械学習をプロダクトに組み込んでいるとき、よくあるのが、以下のような役割分担じゃないでしょうか。

  • モデルを作るところまで→データサイエンティスト的なポジションの人
  • 作成してあるモデルを推論環境にデプロイする→エンジニア的なポジションの人

この時、仮にCheckpoint方式を採用すると、ネットワーク定義の部分のソースコードを学習環境と推論環境の両方で管理する必要があります。

しかし、運用に耐えうるように二重管理するのはかなり大変です。大変さの一例を書くと、以下のような感じでしょうか。

  • 学習側での変更を推論側に常に反映させる必要がある
  • モデルの切り戻しができるように、後方互換性を保った形でネットワーク定義を書かなくてはならない

このような悩みを解決してくれるのがSavedModelです。

SavedModelを使用すると、登場人物の役割が以下のように明確になります。

  • データサイエンティスト的なポジションの人: SavedModelを作る
  • エンジニア的なポジションの人: SavedModelをデプロイする

このような仕組みにしておくことで、デプロイに際する煩雑な作業を減らし、バグを少なくできると考えています。

saved_model_cliを活用することで、ネットワークのin/outを楽に・確実に確認することができる

イントロ

saved_model_cliとは何かを解説する前に、こんなケースを考えて頂きたいです。

あなたは機械学習モデルを作成する担当であり、SavedModelを作成するところまでが担当範囲です。作成したモデルは別のエンジニアの方々にデプロイしてもらっています。

役割が明確だから楽でいいな〜と思いながら仕事をしていたのですが、最近別のエンジニアから結構な頻度でモデルについて質問が来るようになりました。

  • このモデルに画像を入力するとエラーが出ちゃったんだけどどうすればいいの?入力サイズを教えて?あ、あとフォーマットはuint8でいいんだっけ?
  • 今設計を考えているんだけど、このSavedModelの出力ってどういう形式なんだっけ?

これに毎回回答するのも大変だし、モデルのreadmeに毎回過不足なく必要な情報を残しておくのを人力に頼ると記入漏れなどのミスが起きそうで嫌ですよね。

そんなときに便利なのがsaved_model_cliです。

saved_model_cliについて

saved_model_cliとは、TensorFlowが公式でサポートしている、SavedModelの中身をチェックするためのcliツールです。

TensorFlowをインストールする際に自動でついてきているので、実はTensorFlowが入っている環境下であればすぐに使うことができます。

色々使い方はあるのですが、最も単純な使い方だけ説明します。

saved_model_cli show --dir <SavedModelのパス> --all

とコマンドを打つと、以下のようなモデルについての情報が出力されます。(これは前述kaggleコンペの私のモデルの情報です)

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['ts_image'] tensor_info:
        dtype: DT_UINT8
        shape: (-1, -1, 3)
        name: serving_default_ts_image:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['global_descriptor'] tensor_info:
        dtype: DT_FLOAT
        shape: (1536)
        name: StatefulPartitionedCall:0
  Method name is: tensorflow/serving/predict
…

これにより、以下のような情報がわかります。

  • 入力
    • 入力はひとつ
    • 入力画像のshapeが(-1, -1, 3)
    • データ型はuint8
  • 出力
    • 出力もひとつ
    • 出力ベクトルのshapeが(1536)
    • データ型はfloat

メリット

イントロの気持ちに戻ってみてください。

他のエンジニアからモデルについての質問が多く、生産性が下がっている状態です。

そんな時は、モデルについての情報を毎回他のエンジニアに伝えるのではなく、saved_model_cliの存在を教えて、「その情報はsaved_model_cliを叩けばわかりますよ」と返すのはいかがでしょうか。

私は前の現場でそのような形でsaved_model_cliを広めまくっていたのですが、段々と浸透してくると不要なやり取りが減り、組織としてハッピーになったと思っています。

この生産性向上が最大のメリットと感じています。

また、readmeを毎回モデル作成時に書く運用でも理論上はOKなのですが、readmeを更新し忘れてしまうとモデルの説明とモデルに齟齬が生まれ、余計なコストがかかってしまいます。

簡単に・確実にモデルの中身をチェックできるという意味でも、SavedModel + saved_model_cliのメリットは大きいです。

TensorFlow Servingで簡単にデプロイできる

TensorFlow Servingとは、SavedModelを指定して起動するとそのモデルをAPI化してくれるシステムです。

以下のような特長があります。

  • パフォーマンスが優れている
  • http / grpc両対応
  • モデルのバージョニングができる

このTensorFlow Servingを活用することにより、SavedModelを簡単にデプロイすることができます。

SavedModel + TensorFlow Servingで手軽に高機能のデプロイが実現できるところも、また大きなメリットと感じています。

SavedModel使い方リンク集

ここまでで世の中にまとまっていない情報は大体書ききったので、後は先人の記事に任せてみます。

official

Using the SavedModel format  |  TensorFlow Core

Serving a TensorFlow Model  |  TFX

unofficial

SavedModelについてのまとめ - Qiita

TensorFlow2.0時代のTensorFlow Serving向けモデル出力 | AI tech studio

TensorFlow Servingで機械学習モデルをプロダクション環境で運用する - freee Developers Blog

おわりに

ここまで紹介したように、SavedModelはかなり運用に向いている形式であると感じています。

TensorFlowで学習したモデルをデプロイする時は、有力な選択肢として考えるとよいのではないかと思います。

余談ですが、TensorFlow-SavedModel-Tensorflow Servingの関係は、PyTorch-ONNX-ONNX Runtime Serverの関係と似ています。

個人的にモデル作成しやすいのはPyTorchなのでこちらも魅力的に思っています。

しかし、Tensorflow→SavedModelの変換は(個人的な経験では)100%成功するのに対し、PyTorch→ONNXの変換はまだ完全にうまくは行かないという認識です。

そのためモデルの精度要件が緩めで運用の要件が厳しめだったらTensorFlowを採用するのもアリかな、と思っています。

ここらへんの私の考えに甘さがある場合、コメントにてご指摘いただければ嬉しいです。以上です。