Closed21

ONNXRuntime Unity Plugin

Koki IbukuroKoki Ibukuro

Unity BarracudaSentisに変わって迷走しているなか、別の選択肢を試して置くことは大事だなと思い

OnnxRuntimeをUnityで動かす実験をしてみます。

https://github.com/microsoft/onnxruntime/

Onnx自体がMicrosoft製ということもあり、C APIをC#から叩くコードは全部含まれていて、それとUnity側の世界を繋げてあげるあげるだけで動きそうな予感。うまく行けばWebでも同じコードで動くかもという淡い期待。

Koki IbukuroKoki Ibukuro

Onnx RuntimeはMicrosoft製というだけあり、C#のAPIが整備されていてクオリティも高いので、変な自作はせずにそのまま使いたい。その時に厄介になるのはのは、DllImportで定義されている#define

https://github.com/microsoft/onnxruntime/blob/49470f06e88ff99837e7ab0ae6062c32a782e068/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs#L519-L528

PlayerSettingsの Scripting Define Symbolsに入れれば動くと思わわれるかも知れないが、EditorでもAndroidやiOSが有効になるので、Editor実行時にも動作させるには、TensorFlow Liteで定義したようなUnity Editorを除外する処理を書かなくてはいけません。Onnx Runtime本家で対応してくれないかな…。

https://github.com/asus4/tf-lite-unity-sample/blob/7eb841ea486abce4837ecee0fbc30868a1efce70/Packages/com.github.asus4.tflite/Runtime/Interpreter.cs#L241-L247

本家にPR送ってみるのもありだけど、ひとまずUnityで実行出来るように、ビルド前に無理やりPlayerSettings.SetScriptingDefineSymbolsでdefineを書き換えるということをしてみた。一応動いている気はする。

https://github.com/asus4/onnxruntime-unity-examples/blob/f06b8bc3387dbe56c18c442e20004a4b828c524c/Packages/com.github.asus4.onnxruntime/Editor/OrtPreProcessBuild.cs#L19-L28

Koki IbukuroKoki Ibukuro

テストで入れた、軽量なImage classification model Apple MobileOne がmacOS, iOS, Androidで動いたので、とりあえず、Unity package方式でプレビューリリース。

他のプラットフォーム対応。GPU acceleration 対応。 などなどやることはまだまだ沢山あるが、ひとまず、Unity BarracudaやSentisで動かないようなOnnxモデルもUnityで動くなるのは喜ばしい限り。

https://github.com/asus4/onnxruntime-unity-examples/releases

UnityのWebカメラ入力をリサイズしてNCHW変換するところもCompute shader一発で行けたので、TensorFlow Liteでの知見が生きている。

Koki IbukuroKoki Ibukuro

Tokanizer等の面倒くさいpre/post processingも extensions という形でネイティブ実装されているみたい。便利!

Koki IbukuroKoki Ibukuro

Yoloxも動いた。macOS/iOS上のCoreMLは動くけど、AndroidのNNAPIではCPUにフォールバックされて遅い。でもCPUモードも十分速いですね。
次はextensions対応。

Koki IbukuroKoki Ibukuro

WindowsとLinux対応を追加中。

CPUのライブラリのサイズは小さいのだが、CUDAのGPU providerがそれぞれ300MB以上あり、全部を
GitHub LFSで管理するのも辛いなーと。


私のGitHub LFSの99%はTFLiteのためにお金払っている。こんなに使ってもらえると思わなかったので適当に全部入りにしてしまった…。

ということでお金の節約も考えて、最初からNPMだけにするかな。
はじめは全部をまとめてNPMにpublishしようとしたら、413 Content Too Largeで公開出来なかった。NPMの公式の最大ファイルサイズはちょっと見つからなかったけど。

選択肢として、NuGetへ移行することも調べたが、NuGetも最大ファイルサイズは250MBらしい。NuGetでも機械学習ライブラリを公開したいのに最大サイズが小さすぎと議論されていた。わかる。

なので、NPMのまま、WindowsとLinuxのGPU providerはCore packageから分割することにした。

Koki IbukuroKoki Ibukuro

Windows DirectX12で動くDirectML版はonnxruntime.dllに統合されていて、バイナリサイズも1MBくらいしか変わらないので、コアパッケージに入れてあげるのがいいかも知れないな。

UnityユーザーのWindowsにCUDAは入ってない可能性高いので。

Koki IbukuroKoki Ibukuro

XNNPACK対応入れてみた。けど、テストに使ってるモデルがXNNPACK対応してないみたい?もっと単純なモデルで検証必要かな。

Koki IbukuroKoki Ibukuro

ONXX Runtime Extensions

https://onnxruntime.ai/docs/extensions/build.html
https://github.com/microsoft/onnxruntime-extensions/blob/main/build.sh

この辺を参考にmacOS Fat dylibをビルドしてみた。

cmake -D CMAKE_OSX_ARCHITECTURES=x86_64 "$@" ../../.. && cmake --build . --config $BUILD_FLAVOR  --parallel "${CPU_NUMBER}"

cmake -D CMAKE_OSX_ARCHITECTURES=arm64 "$@" ../../.. && cmake --build . --config $BUILD_FLAVOR  --parallel "${CPU_NUMBER}"

でそれぞれビルドして最後に

lipo -create -output libortextensions.dylib path_to_x86_64//libortextensions.dylib path_to_arm64/libortextensions.dylib

で結合する。で合ってると思う、

Koki IbukuroKoki Ibukuro
Koki IbukuroKoki Ibukuro

ONXX 2GB超のモデルファイルの扱い

ONNXのファイルフォーマットは、ProtoBufに依存している。それの制約で、2GB超のファイルを扱えない。
Stable Diffusionなどの大きいモデルでは、

  • model.onnx
  • weights.pb

とファイルが分かれることがあるみたい。

  • model.onnx
  • model.onnx.data

となってるやつもある。これらをORTフォーマットに変換することは出来るのかな?
.onnx拡張子を取り扱うと、OnnxRuntimeプロジェクトでUnity Sentisをインストール出来なくなるため、.onnxではなく、*.ortだけのサポートにしたかったが。

調査中。

Koki IbukuroKoki Ibukuro

マルチプラットフォームで動作

  • Classification
  • Object Detection
  • Segmentation

という基本的なサンプルを追加。基本は完了した気がするので、閉じます。

このスクラップは2ヶ月前にクローズされました