[在Android上,我有一个模型可以在CPU上正常运行,但是在切换到GPU委托时会溢出(结果为'Infinity')。如果我重新缩放输入,就可以消除溢出,因此这似乎是CPU和GPU之间内部范围/精度不同的问题。我的印象是,默认情况下,CPU和GPU都使用32位浮点数,因此结果应该相同。有谁知道TFLite的内部知识足以提供一些见解?
关于浮点精度,Android上的TFLite GPU委托可以两种模式运行,您可以在Options
类中使用以下方法进行选择。 (从here复制)
/**
* Sets whether precision loss is allowed.
*
* @param precisionLossAllowed When `true` (default), the GPU may quantify tensors, downcast
* values, process in FP16. When `false`, computations are carried out in 32-bit floating
* point.
*/
public Options setPrecisionLossAllowed(boolean precisionLossAllowed) {
this.precisionLossAllowed = precisionLossAllowed;
return this;
}
由于此precisionLossAllowed
选项的默认值为true
,因此默认情况下,使用GPU时,您的模型将以FP16模式运行。如果要像在CPU中一样强制以FP32模式运行,则在创建委托时应将此选项显式设置为false
。
GpuDelegate.Options gpuOptions = new GpuDelegate.Options();
gpuOptions.setPrecisionLossAllowed(false);
GpuDelegate gpuDelegate = new GpuDelegate(gpuOptions);
Interpreter.Options interpreterOptions = new Interpreter.Options();
interpreterOptions.addDelegate(gpuDelegate);
Interpreter interpreter = new Interpreter(tflite_model_file, interpreterOptions);
这应该给您与CPU模式下相同的结果,但与FP16模式相比,执行速度较慢。