ONNXのドキュメントをちゃんと読もうということで読んだところからメモとしていろいろまとめていこうと思う(今更だけど)。今回はONNX利用者がまず意識しないといけないversioningのドキュメントを読む。
Ref: https://github.com/onnx/onnx/blob/v1.4.1/docs/Versioning.md


ONNX versioningの基本方針

ONNXのversioningには大きく三つのポリシーがある:

  • IR version: グラフと演算子の抽象モデル、それらのフォーマットのバージョン管理。
  • Operator version: ONNX graphから参照されるオペレータ仕様のバージョン管理。
  • Model version: 定義済み/学習済みモデルのバージョン管理。

IR versionとOperator versionは守らなければいけないバージョン管理であるが、Model versionに関しては任意である(推奨されているだけ)。ローカルで独自に利用する場合はユーザーの判断に任されるが、オープンにシェアする前提のモデルに関してはversioninigをすべきである。

IR versioning

型定義などIRを構築するもののバージョン管理。ONNX IR formatはprotobuf3のUpdating a Message Typeに規定されたバージョン管理ガイドラインを準拠している。ONNXにはONNX checkerというものがあり、このツールによってルールが守られているかどうかがチェックされている。
Ref: Protobuf3 Updating a Message Type

Operator versioning

Deep Learningの各命令(convやfcなど)のバージョン管理。operatorは3要素のtupleで定義されている。

(domain.op_type:op_version) グラフ内のノードはいつもこの3要素を参照してoperatorを見るようになっている。また、破壊的なoperatorの変更は下記の通り:

  • operator自体のadding/removing/renaming。また、新しいオプション属性の追加も含まれる
  • operatorのinputとoutputのadding/removing/reordering。
  • 型の追加と削除、あるいは変更
  • 既存parameterのシグネチャの新しい振る舞い

ONNXモデルは二つのオペレータ情報(domain, opset_verison)を含んだリストを宣言する必要がある。空の文字列("")ドメインはONNX仕様の一部として定義されているオペレータであることを示す。与えられたモデルよって指定されたオペレータセットの和集合は、モデルグラフ内の各ノードに対して互換性のあるオペレータを宣言しなければならない。

Model versioning

Model versioningはONNX変換して配布するユーザーによって依存するため、あくまでもONNXが推奨するプラクティスを提示しているだけである。なので、学習済みモデルをONNXのフォーマットに変換して配布する場合はONNXが推奨するバージョンの付け方に従うといい。推奨されるやり方としては破壊的変更であるケースと非破壊的変更のケースの二つに分かれる。 破壊的変更である場合はModelProto.model_versionのメジャーバージョンをインクリメントする。破壊的変更は下記のようなものを含む:

  • カラー画像のインプットからグレースケールに変換するといったインプットまたはアウトプットの意味を変えてしまう変更
  • 互換性のない型の変更
  • GraphProto内の値と同じ名前の値いったインプットの追加
  • 既存アウトプットの削除

また、非破壊的変更はModelProto.model_versionのマイナーバージョンをインクリメントする。非破壊的変更は下記のようなものを含む: 互換性のある型の変更 意味を持った、または指定されたデフォルト値がある新しい入力の追加 以前のバージョンのグラフでは不可能だった入力によって引き起こされる新しい振る舞いの追加


ONNXの躓くところとして、opsetのバージョンの差異があると思う。バージョンが違った際にはONNXが提供しているVersion Converterを利用することができるが、まだ上手く動かないといったことは多い。ONNXを利用する場合は、インプットとアウトプットのONNX対応のバージョンの互換性を確認する必要がある。