Pytorch 错误:无法压缩值不是1的维度

Pytorch 错误:无法压缩值不是1的维度,pytorch,coreml,bert-language-model,Pytorch,Coreml,Bert Language Model,我有一个基于pytorch预训练BERT的mlmodel,通过ONNX导出到CoreML。这一过程非常顺利,所以现在我正在尝试做一些(非常)基本的测试——也就是说,只是做一些预测,大致了解我们可能会遇到哪些性能问题 但是,当我尝试运行预测时,会出现以下错误: [espresso] [Espresso::handle_ex_plan] exception=Espresso exception: "Invalid state": Cannot squeeze a dimension whose

我有一个基于pytorch预训练BERT的mlmodel,通过ONNX导出到CoreML。这一过程非常顺利,所以现在我正在尝试做一些(非常)基本的测试——也就是说,只是做一些预测,大致了解我们可能会遇到哪些性能问题

但是,当我尝试运行预测时,会出现以下错误:

[espresso] [Espresso::handle_ex_plan] exception=Espresso exception: "Invalid state": Cannot squeeze a dimension whose  
value is not 1: shape[1]=128 stat2020-02-16   
11:36:05.959261-0800 Xxxxx[6725:2140794] [coreml] Error computing NN outputs -5  
这个错误是否表明模型本身存在问题(即,来自模型转换),或者Swift/CoreML中是否有我做错的地方?我的预测函数如下所示:

public func prediction(withInput input: String) -> MLMultiArray? {
        var predictions: MLMultiArray? = nil
        if let bert = bertMLModel {
            var ids = tokenizer.tokenizeToIds(text: input, includeWordpiece: true)
            print("ids: \(ids)")
            while ids.count < 256 {
                ids.append(0)
            }
            let inputMLArray = MLMultiArray.from(ids, dims: 2)
            let modelInput = bert_256_FP16Input(input_ids: inputMLArray)
            var modelOutput: bert_256_FP16Output? = nil
            do {
                modelOutput = try bert.prediction(input: modelInput)
            } catch {
                print("Error running prediction: \(error)")
            }
            if let modelOutput = modelOutput {
                predictions = modelOutput.output_weights
            }
        }
        return predictions
    }
我承认我以前没有从python运行mlmodel,但我认为输入是正确的。规范指出:

input {
  name: "input.1"
  type {
    multiArrayType {
      shape: 1
      shape: 128
      dataType: INT32
    }
  }
}
input {
  name: "input.3"
  type {
    multiArrayType {
      shape: 1
      shape: 128
      dataType: INT32
    }
  }
}
...
我的意见

对于这种情况,我没有得到
无法压缩
消息或错误代码(-5),但它确实会在
错误计算NN输出时失败
。所以肯定是出了问题。我只是不知道如何调试它

J

更新:为了进行比较,我已经训练/转换了HuggingFace-BERT模型(实际上是DistilBert-我已经相应地更新了上面的代码),并且有相同的错误。查看onnx中的日志,我看到添加了一个
压缩
(当然,从onnx coreml日志中也可以看到),但是PyTorch代码中唯一的
压缩
是在
BertForQuestionAnswering
中,而不是
BertForMaskedLM
。也许onnx正在构建问答模型,而不是传销模型(或者问答模型保存在检查点中)

查看swift coreml transformers示例代码,我可以看到distilBert的输入只是
let input\u ids=MLMultiArray.from(allTokens,dims:2)
,这正是我定义它的方式。所以我想我已经走到了死胡同。是否有人在CoreML(通过onnx)与Bert/DistilBert一起进行传销?如果是这样的话,举个例子会非常有帮助

顺便说一句,我正在使用HuggingFace最新的
run\u language\u modeling.py
进行培训

查看Netron中的mlmodel,我可以看到令人不快的
挤压
。我承认我不知道输入的那个分支是用来做什么的,但我猜它是一个面具(进一步的猜测可能是它与问答有关)。我能把它去掉吗


我会尝试用Python运行此模型,看看是否会出现相同的错误消息。这可能与您如何创建MLMultiArray有关,但如果Python也给出了相同的消息,则可能是mlmodel文件本身中的某些内容。@MatthijsHollemans,您在GitHub上解决了这个问题:。如果你想把它作为答案发布,我会把它标记为解决方案。谢谢我会尝试在Python中运行这个模型,看看是否会给出相同的错误消息。这可能与您如何创建MLMultiArray有关,但如果Python也给出了相同的消息,则可能是mlmodel文件本身中的某些内容。@MatthijsHollemans,您在GitHub上解决了这个问题:。如果你想把它作为答案发布,我会把它标记为解决方案。谢谢
input {
  name: "input.1"
  type {
    multiArrayType {
      shape: 1
      shape: 128
      dataType: INT32
    }
  }
}
input {
  name: "input.3"
  type {
    multiArrayType {
      shape: 1
      shape: 128
      dataType: INT32
    }
  }
}
...