在后台运行coreml时出错:计算NN输出错误时出错

Sim*_*son 0 swift ios11 coreml

我正在运行来自iPhone 6上来自keras的mlmodel。预测通常会因错误而失败Error computing NN outputs。有谁知道可能是什么原因,如果我有什么办法可以解决?

do {
    return try model.prediction(input1: input)
} catch let err {
    fatalError(err.localizedDescription) // Error computing NN outputs error
}
Run Code Online (Sandbox Code Playgroud)

模型输入和输出

编辑:我尝试了苹果的示例项目,并且该项目在后台运行,因此看来它特定于我们的项目或模型类型。

Ray*_*ayD 5

我自己在类似的“看似随机”的时间也遇到了同样的错误。一些调试跟踪确定这是由于应用程序有时在将其发送到后台时尝试加载其 coreml 模型,然后在重新加载到前台时崩溃或冻结造成的。

该消息Error computing NN outputs error之前是:

Execution of the command buffer was aborted due to an error during execution. Insufficient Permission (to submit GPU work from background) (IOAF code 6)
Run Code Online (Sandbox Code Playgroud)

我不需要(或不想)在应用程序处于后台时使用模型,所以我检测到应用程序何时进入/退出后台,在尝试调用模型之前设置一个标志并使用一个保护语句。

  1. 使用applicationWillResignActiveAppDelegate.swift 文件检测何时进入后台并设置 Bool 标志,例如appInBackground = true. 有关更多信息,请参阅:检测 iOS 应用程序进入后台

  2. applicationDidBecomeActive在同一个 AppDelegate.swift 文件中检测应用程序何时重新进入前台,并重置标志appInBackground = false

  3. 然后在调用模型的函数中,就在调用模型之前,使用如下语句:

    guard appInBackground == false else { return } // new line to add guard let model = try? VNCoreMLModel(for modelName.model) else { fatalError("could not load model") // original line to load model

我怀疑这是最优雅的解决方案,但它对我有用。

我还没有确定为什么有时会尝试在后台加载模型。

在您链接到的 Apple 示例中,看起来他们的应用程序只会响应用户输入调用模型,因此它永远不会尝试在后台加载模型。因此,我的情况有所不同……也可能是您的情况?


Sim*_*son 5

最后,足以让我们设置usesCPUOnly标志。在iOS中似乎禁止在后台使用GPU。苹果实际上也在他们的文档中写了这个。要指定此标志,我们不能再使用生成的模型类,而必须调用原始coreml类。我可以想象在将来的版本中这种变化。下面的代码片段来自生成的模型类,但MLPredictionOptions指定了添加的内容。

let options = MLPredictionOptions()
options.usesCPUOnly = true // Can't use GPU in the background

// Copied from from the generated model class
let input = model_input(input: mlMultiArray)
let output = try generatedModel.model.prediction(from: input, options: options)
let result = model_output(output: output.featureValue(for: "output")!.multiArrayValue!).output
Run Code Online (Sandbox Code Playgroud)