verilog書く人

自称ASIC設計者です。どなたかkaggle一緒に出ましょう。

iOSで機械学習の推論をするためにCoreMLを使おうとした時のつらみと回避方法まとめ

iOS機械学習機械学習の推論をする場合、Core MLやPytorch Mobileなどの選択肢がありますが、

Apple謹製のCore MLを使ってみようと思う人は多いはずです。

Core MLのメリットとしては

  • Pytorch MobileはiOS12以上なのに対し、Core MLはiOS11以上をサポートしているでのサポート範囲が広い

  • Core MLで作ったモデルはiPhoneのスペックに応じて最適化され、高速に実行される

  • Appleがサポートしているので安心

と言ったところがあります。

ただ、実際使ってみると画像分類などはQiitaにも多数使ってみた的な記事があるのですが、

マイナーなタスクのモデルを使ってみるとつらいところもあったので、まとめてみました。

(この記事自体はどちらかのライブラリを推奨するものではございません。)

目次

CoreMLのつらいところ

サポートされている演算がそんなに多くない

ちょっとマイナーな演算を使おうとすると、サポートされてないことがあります。

そんなときにはどうするかというと、サポートされている演算で書き直すか、自分でPRを作るなどしてサポートしてもらうという手があります。

私は5つほど未サポートの演算にぶつかり、以下のような方法で回避しました。

triu -> PR作った

logical_or -> PR作った

outer -> PR作った

einsum -> reshapeとmatmulを使って書き直した

einopsのrearrange -> reshapeやpermuteを使って書き直した

という感じでわりとサポートされていない演算を迂回したりサポートするのに時間がかかりました。

Flexible Input Shapeのトラブルがかなり多い

報告されているイシューのリストも参照してみてください。

例えばEnumerated sizeを複数同時に適用できないというようなバグがあります。

また、私がハマったバグとしてはflattenがFlexible Shapeと合わせて使えないというバグがありました。

ValueError: Cannot add const [10*is0]というエラーメッセージがでましたがわかりづらいです。

結局flattenは諦めて、reshapeを使ってモデルを書き直すことで、回避することができました。

エラーメッセージがわかりづらい

flattenの件もそうですが、全体的にエラーメッセージはわかりづらいです。

たとえば、coremltoolsでコンバートしたモデルの推論をしようとするとRuntimeError: value type not convertibleというエラーが出ることがあります。

このランタイムエラーというのが曲者で、ようはPythonOSSライブラリ内のエラーであればスタックトレースが表示されてコードが読めるのですが、

クローズドソースのCore ML内のランタイムではなにが起きているかを推定するのが難しいです。

value type not convertibleの場合は、Inputされた行列のなにかがおかしいと考えられます。

例えば、int32int64を入力してしまっているとかnumpy.ndarrayではなくtorch.tensorを入力しているという誤りが考えられます。

また入力がImageTypeの場合には、PILImage型を入力する必要があります。

他にも色々エラーが起こりえますが、どこで起きているかわからないエラーが多いので、

原因箇所の特定にはモデルの層をエラーが出なくなるまで後ろから減らしていくなどのテクが必要となります。

古いiOSでは一部のテンソル演算が使われておらず、なんだかんだでサポート対象のiOSのバージョンが上がってしまう

例えばcumsumがiOS14以上だったりします。

coremltoolsのサポート体制が薄めな気がする

PRを出したらしっかりレビューしてもらえましたし、実力あるメンバーが開発についていると思いますが、

時間的なリソースがあまり注がれてないのかPRのマージに時間がかかることがあります。

Swiftでの画像などの前処理がつらい

例えばゼロ行列を得るのもそこそこ苦労します。 (実装方法例

torchならtorch.zerostorch.zeros_likeなどが使えますが、Core MLのMultiMLArrayではそのようなものがありません。

回避方法としては、torchモデルになるべく前処理を組み込んで、Swiftではあまりテンソル演算をしないのがよいと思います。

多少の演算をしたい場合は上記のHelperが便利な時があります。

CoreMLのいいところ

つらいところばかり書いてしまいましたが、いいこともあります。

  • すでに使われているモデルをそのまま使う分にはそんなにつらくないです

逆に、マイナーなタスクや、マイナーな演算を使いたい場合はそれなりに苦労すると思ってよいです。

  • XCode + Swift上での開発体験はいいです

モデルのサイズや概要を表示してくれたり、入出力の変数の型を表示してくれます。

というわけで、以上Core MLについてでした。