以前一直用D11,用了好多年,没有什么大问题,但小问题不少,最近把Delphi升级到了D12,最担心的几个控件包也解决了兼容问题(我只用5个,DevExpress,NextSuite,ComPort,FFVCL和多年累积下来自己写的一些工具控件),庆幸之余试了一下前几年自己封装的一套Tensorflow Lite 库,没想到出问题了。

我是封装了 Tensorflow Lite 的API接口库,包括CPU、GPU和NPU上推理,其中,CPU和NPU推理没有问题,但GPU调不起来,始终返回一个空指针对象

FDelegateOptions.is_precision_loss_allowed := 1;
FDelegateOptions.inference_preference :=Int32(TFLITE_GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED);
FDelegateOptions.inference_priority1 := Int32(TFLITE_GPU_INFERENCE_PRIORITY_MIN_LATENCY);
FDelegateOptions.inference_priority2 := Int32(TFLITE_GPU_INFERENCE_PRIORITY_AUTO);
FDelegateOptions.inference_priority3 := Int32(TFLITE_GPU_INFERENCE_PRIORITY_AUTO);
FDelegateOptions.experimental_flags:=Int32(TFLITE_GPU_EXPERIMENTAL_FLAGS_CL_ONLY);
FDelegateOptions.max_delegated_partitions:=1;
FDelegateOptions.model_token:=nil;
FDelegateOptions.serialization_dir:=nil;

FDelegateOptions.first_delegate_node_index:=0;
FDelegateOptions.last_delegate_node_index:=High(Integer);

FDelegateOptions.gpu_invoke_loop_times:=1;

GpuDelegate := GpuDelegateV2Create(@FDelegateOptions);

if (GpuDelegate <> nil) then
begin
   InterpreterOptionsAddDelegate(InterpreterOptions, GpuDelegate);
   GpuAvailable := True;
end;

//创建GPU的解释器
Interpreter := InterpreterCreate(Model, InterpreterOptions);

if Interpreter = nil then   //在 D11.2, D11.3 和 D12 下总是返回一个空对象指针
  raise ETensorFlowLiteFMXError.Create('Create interpreter error');

我总觉得这个和 Java SDK的版本有冲突,不兼容导致的,然后一顿输出尝试不同的Android Java SDK库,但结果全部失败,不死心,尝试把D11下的所有关于安卓的库和相关文件复制到D12下,也全部失败,然后尝试修改 PAClient 的库,试来试去还是失败,心里一凉,难到安卓下要用Delphi开发AI程序只能终结到D11了吗?

在折腾了几天后,今天冷静下来仔细想了想,之前看过一篇文章,提到过Delphi开发安卓程序有个重要的配置文件 AndroidManifest.xml,马上打开对比了一下,有点区别,最引起我注意的是这句话:

D12生成的是:

...
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="34" />
...

D11生成的是:

...
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="30" />
...

很明显,D11使用的是低版本的SDK,但之前我在D12的 SDK Manager 中导入过 D11 低版本的 Java SDK库啊? 难道光用 SDK Manager 中导入低版本的还不够? 于是我又在网上趴了一番,


这篇文章中提到 AndroidManifest.xml 文件是通过项目中 AndroidManifest.template.xml 这个模板文件中配置的,于是乎,直接在这个模板中指定 SdkVersion =30

再次编译运行,问题解决

android framebuffer gpu显存 安卓调用gpu_人工智能

使用CPU的推理速度,只有可怜的 1.2帧

android framebuffer gpu显存 安卓调用gpu_android_02

使用NPU的推理速度,可以达到 8帧

android framebuffer gpu显存 安卓调用gpu_xml_03

使用GPU的推理速度,可以达到恐怖的 50帧

android framebuffer gpu显存 安卓调用gpu_python_04