将 ARCore 添加到 Android 应用程序后,我无法再使用 TFLite API 中的 GPU Delegate 在手机 GPU 上运行我的 ML 模型。
我不知道有什么方法可以在不从我的应用程序中放弃 ARCore 的情况下重新获得 GPU 访问权限。
我已在 Google Pixel 7 Pro 和 Google Pixel 平板电脑设备上进行了测试,这两种设备均受 ARCore 支持并提供对 TFLite 的 GPU 访问。
我正在开发一个同时使用 ARCore 和 TFLite 的 Android 应用程序。 在添加 ARCore 之前,我让 TFLite 模型与 Interpreter API 一起使用。
我使用 CompatibilityList().isDelegateSupportedOnThisDevice 检查 GPU 委托的可用性,仅在可用时添加它。
val interpreterOptions = Interpreter.Options().apply {
addDelegate(NnApiDelegate())
if (CompatibilityList().isDelegateSupportedOnThisDevice) {
addDelegate(GpuDelegate(CompatibilityList().bestOptionsForThisDevice))
} else {
Log.w("MyApp", "GPU Delegate is not supported on this device.")
}
}
加载模型后,我从这些选项实例化解释器。
val interpreter = Interpreter(myModel, interpreterOptions)
但是,将 ARCore 添加到我的应用程序后,我似乎无法访问设备的 GPU(即
isDelegateSupportedOnThisDevice == false
始终)。
除了权限之外,我还在我的
AndroidManifest.xml
中添加了以下语句。
<uses-feature android:name="android.hardware.camera.ar" />
<uses-feature android:name="com.google.ar.core.depth" />
<application ...>
<!-- require ARCore (https://developers.google.com/ar/develop/java/enable-arcore) -->
<meta-data
android:name="com.google.ar.core"
android:value="required" />
<!-- other stuff ... -->
</application>
并在
build.gradle.kts
dependencies {
// ARCore
implementation("com.google.ar:core:1.33.0")
implementation("de.javagl:obj:0.2.1") // OBJ file loader (for compatibility purposes only!)
// ... other stuff ...
}
并使用基于 Hello AR Kotlin 示例的 OpenGL 包装器代码实现了 ARCore。
但是,我很快注意到我的模型现在运行速度没有那么快,并且调试显示 GPU Delegate 现在在我运行 ARCore 的任何设备上都不可用。 但仅仅停用 ARCore 还不够,我需要删除上述所有依赖语句,GPU Delegate 访问才能再次工作。
MainActivity
类中删除 ARCore 引用(即不使用 ARCore 但保留依赖项)- 不会改变任何内容
GPU 访问现在再次可用
我在 TensorFlow 中偶然发现了这个 GitHub 问题,其中讨论了 GPU Delegate 在第三方手机上无法访问。 他们不使用 ARCore,但遇到了一些类似的问题。
它说将以下语句添加到我的
<activity/>
中的AndroidManifest.xml
。
<uses-library
android:name="libOpenCL.so"
android:required="false" />
<uses-library
android:name="libOpenCL-pixel.so"
android:required="false" />
这并没有改变任何东西。
我仍然坚信使用 ARCore 是导致此问题的原因。我还知道 ARCore 至少在 GPU 上进行了一些处理(因此是 OpenGL 包装器),但我还没有发现与 TFLite API 的这个特定问题有关的任何问题。
有没有办法重新获得对 GPU Delegate 的访问权限?
也许值得一提的是,虽然有一个 使用 ARCore 和 ML 的示例,但它使用了 Google 的 MLKit,它确实为高级 ML 任务提供了包装器,其中一些具有内置 GPU 支持。
但是,我的模型不属于这些任务所涵盖的应用范围,因此唯一的其他选择是回退到 TFLite,这基本上就是我现在正在做的事情。
此外,据我所知,MLKit API 不会公开 GPU 设置。
我将所有 TFLite 实现移至使用 Google Play 服务(支持使用
org.tensorflow
)。
implementation("com.google.android.gms:play-services-tflite-impl:16.1.0")
implementation("com.google.android.gms:play-services-tflite-java:16.1.0")
implementation("com.google.android.gms:play-services-tflite-support:16.1.0")
implementation("com.google.android.gms:play-services-tflite-gpu:16.2.0")
请注意,这还要求我使用稍微不同的解释器 API。
因此,删除所有 ARCore 依赖项并不能解决问题。 我通过
git
恢复来做到这一点,在这个过程中,我似乎还混合了来自不同来源的 TFLite 依赖项。也就是说,我使用了 Maven 的 TFLite
implementation("org.tensorflow:tensorflow-lite-task-vision:0.4.0")
implementation("org.tensorflow:tensorflow-lite:2.9.0")
implementation("org.tensorflow:tensorflow-lite-gpu-delegate-plugin:0.4.0")
implementation("org.tensorflow:tensorflow-lite-gpu:2.9.0")
与 Google Play 服务中的一些软件包一起使用
implementation("com.google.android.gms:play-services-tflite-impl:16.1.0")
implementation("com.google.android.gms:play-services-tflite-gpu:16.2.0")
有关更多信息,请参阅有关 GPU 加速委托与解释器 API 的 Google 文档
即使我没有更改 TFLite API 的使用方式,但这似乎足以破坏兼容性。
我不确定我到底是如何混淆的,但我认为这是因为 TFLite 示例和文档的不同部分使用不同的 API,而我忽略了这种区别。