Open45

TensorFlow Lite on Unity やってることメモ

Koki IbukuroKoki Ibukuro

イシュー対応done。

https://github.com/asus4/tf-lite-unity-sample/pull/239

パッチリリースのために 2.9.1-p1って名前をつけたけど、Unity Package Managerはリリース順ではなく、名前順でアップデートを判定しているみたいで、2.9.1-p12.9.1より新しいバイナリとして、Updateあります。って言ってくる。…リリース順で判定してほしかった。まあ、一時的なものなので、良いか。

npmjsのサーバーはちゃんと2.9.1-p1を最新と判定しているので、これはUnity Package Managerの実装の問題。

npm

Koki IbukuroKoki Ibukuro

v2.10.0 ブランチで TensorFlow Lite Library for Unityをビルド中。

出くわした問題

  • macOS Metal Delegateでは, cpuinfoの判定が正常に動作しない問題が未だにあり、パッチをあてて対処していたものの、cpuinfoライブラリをソース梱包から、Bazelが依存解決して外部からとってくるようになってしまった。この問題に本格的に取り組まなくては行けない気がする。
  • Signature RunnerのC APIに名称変更があった。
  • AndroidではUnsatisfiedLinkError: dlopen failed: library “libc++_shared.so” not foundエラーが出るな…。むむむ
Koki IbukuroKoki Ibukuro

https://github.com/asus4/tf-lite-unity-sample/issues/245

GitHub上でAndroid GPU Delegateに違うエントリーポイントがあることを教えてもらった。こっちはOpenGLES のSSBO BindingのAPI付き。自分でメンテナンスするよりも楽かもしれない。BazelのBUILDファイルに存在しないので、TensorFlowチームが内部的に使ってるだけな気もするが、試してみても良いかもしれない。

Koki IbukuroKoki Ibukuro

とりあえずv2.10.0のブランチはマージ。

最低限の機能だけ用意するのがいいや…と思ってつけてなかった、目次シーン戻るボタン。どう考えても必要だろと思い直して、つけることにした。すいません。

Koki IbukuroKoki Ibukuro

origin/gpu-api-delegate
ブランチで新しいGPU delegate for Android試しているが、SSBOバインディングの動かしかたがわからん。全然ドキュメントない上にUnity経由でやるから、やってる人が私しかいない…。ひとまず棚上げするか…。

Koki IbukuroKoki Ibukuro

すごい小ネタだが、Unity Androidの Build & Runは失敗することもあり、Buildだけのほうが成功率高いので、ビルドしてから以下のスクリプトでadb 経由で立ち上げている。

adb install -r tf-lite-unity-sample.apk
adb shell am start -n com.asus4.tfliteunitysample/com.unity3d.player.UnityPlayerActivity
adb logcat Unity:V tflite:V "*:S"
Koki IbukuroKoki Ibukuro

https://github.com/asus4/tf-lite-unity-sample/issues/261

Unity 2021 LTSにアップデートするとなんかTFLiteの中のフレームワークが見つからないってエラー。Unity LTSバージョンってより、Burstとかのアップデートに影響されてるのかなって思っている。優先度高いが、ちょっと時間をとって見てみたいとわからん問題。

Koki IbukuroKoki Ibukuro

フリーランスとしての依頼が来たので、Android Neural Networks APIの機能追加を優先対応した。

対応した内容詳細はこちら↓
https://zenn.dev/asus4/scraps/14572ff15e229b

以前も何社かコミッションワークとして機械学習 x Unityなプロジェクトへ参加したことがあるが、プロジェクトを離れると私がメンテナンスできなくなり、だんだんと使われなくなってしまうので、こういったOSSへの追加を依頼してもらえるのはありがたい限り。

Koki IbukuroKoki Ibukuro

LTS 2021 x iOSの組み合わせでビルド通らなくなる件、直してみた。

https://github.com/asus4/tf-lite-unity-sample/issues/261

ユーザー数が増えてきたので、本来ならば時間をかけて、全プラットフォームのUnityバージョンの組み合わせをテストできるようなCIを用意すると良い気がするが、メンテコストが上がるので、積極的に、古い端末のサポートを切って、最新LTSのみで試してます。みたいな方が良いかなあ。

本来ならば、
Linux, Windows, macOS, Android, iOS
Unity 2020 LTS, 2021 LTS, 2022 Tech Stream
くらいの全組み合わせを順にCI.
みたいなのが理想。

Koki IbukuroKoki Ibukuro

Android API level 31で動かん問題しらべた。手元の環境で問題を再現。色々手を入れて、修正を確認、

やはり原因は、Android API level 31から use-native-libraryタグを入れないとOpenCLにアクセスできなくなった、というセキュリティレベルの変更が影響しているぽい。

<uses-native-library android:name="libOpenCL.so" android:required="false" />
<uses-native-library android:name="libOpenCL-car.so" android:required="false" />
<uses-native-library android:name="libOpenCL-pixel.so" android:required="false" />

直し方詳細は以下に書いてみた。

https://github.com/asus4/tf-lite-unity-sample/issues/263#issuecomment-1398627955

Koki IbukuroKoki Ibukuro

あー、上記問題、Unity 2021 LTSのGradleのバージョンが 6.1.1 で 多分 <use-native-library> tagがGradleバージョン挙げないと、使えない?てことは、ビルド自動化するのに、 Gradleバージョン依存を解決しなくてはいけなくて、手動でやるのは簡単だけど、ライブラリとして提供するのは結構茨の道である。むむむ。

https://docs.unity3d.com/2022.2/Documentation/Manual/android-gradle-overview.html

Koki IbukuroKoki Ibukuro

GitHubにくるIssueしらべて返信するだけで平気で2時間くらい溶けるので、core-jsの作者の気持まじでわかる〜となる。

Koki IbukuroKoki Ibukuro

完全に気まぐれだけど、SSDのカスタムモデルが動かないってissueをみた。

https://github.com/asus4/tf-lite-unity-sample/discussions/296#discussioncomment-5778137

ちょっと手直ししたら動いたが、これは確かに、なれてないと厄介なやつ。SSD系のNonMaxSupressionは TFLite_Detection_PostProcess でカスタムの実装がTFLiteには組み込まれているが、TensorFlow のversion 1系と2系でoutputの順番が違うという。バージョン依存問題だった。こんなんソースコード見ないと気づかない。

なるべく全部のissueを平等に見たいが、そんな時間はないので、気まぐれになってすいません。

Koki IbukuroKoki Ibukuro

あといつまでも Unity LTS2020でやってたけど、新規もう2023年。Unityの2022 LTSは未だに来る気配がないが、一応Unity 2021 LTSにアップグレードした。

https://github.com/asus4/tf-lite-unity-sample/issues/263

新しいAndroidでOpenCLがリンクされなくて遅くなる問題は、Niantec Lightshipでもう少しいい対応してるのを見つけたので、試してみてもいいかも。

https://lightship.dev/docs/ardk/ardk_fundamentals/building_android.html

Koki IbukuroKoki Ibukuro

TensorFlow Lite v2.13.0

をビルド開始。案の定いっぱいエラーが出る。ただのコンパイル屋さん。

macOS ビルドエラー

bazelで以下のようなエラーが出る。
unknown option: --no-undefined

https://github.com/tensorflow/tensorflow/issues/60745

これをPRをv2.13.0へcherry-pickで動きそう。CIもcherry pick対応させるか悩む。

iOS ビルドエラー

'any_cast<tflite::gpu::Convolution2DAttributes &>' is unavailable: introduced in iOS 12.0

https://github.com/google/mediapipe/issues/4330

Xcodeバージョンを14.2に落とせとのこと。えー。

→ その後masterブランチとdiffとって、Minumum iOS verisonを11.0から12.0に上げれば動くこと確認。

TFL_MINIMUM_OS_VERSION = "12.0"

Android GPU delegate

<uses-native-library> が見つからない関係のエラー。
AndroidはOpenCL.soを使うのに、Android Manifestにこの辺を追記することが必須になった。Build Tools を31に上げると解決するのだが今度は、

build tools 30まで存在したdx.jar が31では消えてるのでコケる。stackoverflowにあるように手動で30から該当dx.jarをコピーすると通るのだが…。納得行かない。

一応手動で通してから再ビルドすると

AHardwareBuffer_acquire が定義されてない的なエラー NDKのバージョンを最低26にあげないと駄目らしい

https://github.com/tensorflow/tensorflow/blob/1cb1a030a62b169d90d34c747ab9b09f332bf905/configure.py#L760-L761
これソースコードのコメントじゃなくて、見えるとこに書いてほしいぞ…。

ってことで、v2.13.0のGPU delegateをビルドするのに必要な構成はこんなかな?

  • ANDROID_SDK_API_LEVEL: 23 (not changed)
  • ANDROID_BUILD_TOOLS_VERSION: 30.0.2 → 31.0.0
  • ANDROID_NDK_API_LEVEL: 21 → 26

CircleCIも通るようにしたいが、なのかの情報が見当たらない気がするな。実際は入ってみて確認するしかないのかな?イメージ一覧。もうDockerに移行するほうがいいのか。

Windows

An error occurred during the fetch of repository 'llvm-raw':
java.net.SocketTimeoutException: Read timed out

でタイムアウトでとまる。

https://github.com/tensorflow/tensorflow/issues/56540#issuecomment-1170125125

GitHubが調子悪いっていってるけど、そんなことある?

→ その後何回もこころみて、llvmダウンロード失敗してもビルドは内部的なllvmかなにかにフォールバックしているのか、ビルドは成功する。
TimeOutのExcepitonが出るとそこでBazelのビルドプロセスがとまるのでllvmダウンロード自体をキャンセルすることで、通った。…CIは…また今度。

Linux

これは一番優秀。
パッチを適用すれば一応ビルドできる。


CIではまだ落ちるが一応ライブラリビルドしてPRマージした。

https://github.com/asus4/tf-lite-unity-sample/pull/315

Koki IbukuroKoki Ibukuro

<uses-native-library>

OpenCLを使うときに以下をAndroidManifast.xmlに追加する必要があった。しかしUnity 2021までのバージョンでは対応gradleバージョンが低いので、<uses-native-library> タグがあるとコンパイルエラーになる。回避するために色々面倒くさい対応をする必要があった。Unity 2022でgradleバージョンがあがったぽいので、対応できるか見てみる。

    <uses-native-library android:name="libOpenCL.so" android:required="false" />
    <uses-native-library android:name="libOpenCL-car.so" android:required="false" />
    <uses-native-library android:name="libOpenCL-pixel.so" android:required="false" />

https://github.com/asus4/tf-lite-unity-sample/issues/263

https://support.google.com/googleplay/android-developer/answer/11926878?hl=en

ちなみに、8/31からtarget API Levelは33になった。

Unity Gradle Versionは2022から7.1.2が載っているのでビルドできるはず。

https://docs.unity3d.com/Manual/android-gradle-overview.html

Koki IbukuroKoki Ibukuro

対応した。カメラコマンドバファーに介入するのをURPとBuilt-in render pipeline両対応。みたいなユースケースではARFoundationが参考になる。

Built-inとURPの設計方針が間逆すぎて、どっちか片方だけにしたすぎる。Built-inは楽だった。

https://github.com/asus4/tf-lite-unity-sample/pull/317

Koki IbukuroKoki Ibukuro

v2.16.1で、画像認識のためのクラス BaseImagePredictorを obsolateにして、モダンなAPIに移行したクラス、 BaseVisionTask を用意してみた。いくつかのタイプの画像認識モデルを扱ってきた経験から、大体のパターンに対応できるクラスができたと思う。また、プロファイラのマーカーをBaseVisionTaskの中に挟むことで、自動でプロファイラに処理が残るようにしてみた。

https://github.com/asus4/tf-lite-unity-sample/releases/tag/v2.16.1

Koki IbukuroKoki Ibukuro

v2.17.0 続き

Android

Android CPU側はビルドできたものの、GPU delegateがビルドできないので、Mavenからビルド済のものを使わせてもらおうと思ったら、なにやらTFLiteがパッケージの更新が止まっていた。TensorFlow LiteはLiteRTに移行するらしい。LiteRTという名前のパッケージの中を見たら、中身はそのままTensorFlowLiteだったので、名前だけ変えたらしい。完全な移行が済むまでTFLiteもメンテしてほしいな。

https://github.com/tensorflow/tensorflow/issues/72157#issuecomment-2371457835

https://developers.googleblog.com/en/tensorflow-lite-is-now-litert/

Koki IbukuroKoki Ibukuro

Linux

Linuxも色々エラー出てるんだけど、Issue Commentを見ると、gcc12 じゃないとだめぽい。Ubuntu 22.04のgccバージョンは11 から 24.04 にアップグレードすることで内部的なバージョンが13.2.0に上がったのでビルド通った。

Windows

tensorflow/lite/core/c/operator.cc(35): error C7555: use of designated initializers requires at least '/std:c++20'

というエラー。.bazelrcでcxxoptが/std:c++17に固定されているので、ビルド時に設定を上書きしてあげれば良さそう。

bazel build -c opt --cxxopt=/std:c++20 --host_cxxopt=/std:c++20 --define tflite_with_xnnpack=true tensorflow/lite/c:tensorflowlite_c

こういう広く使われるライブラリではおしゃれぶってc++20の機能使わず、古い文法で書いてほしいな。