У меня есть mlmodel, основанная на pytorch-pretrained-BERT, экспортированная через ONNX в CoreML. Этот процесс был довольно плавным, поэтому сейчас я пытаюсь провести некоторое (очень) базовое тестирование c, то есть просто сделать какой-то прогноз и получить общее представление о том, с какими проблемами производительности мы можем столкнуться.
Как бы то ни было, когда я пытаюсь запустить прогнозирование, я получаю следующую ошибку:
[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
}
На данном этапе я не пытаюсь сделать что-либо значимое, только чтобы запустить его.
Я использовал pytorch-pretrained-BERT репо, потому что я смог найти пример предварительной подготовки для этого. С тех пор я заметил, что HuggingFace выпустил вариант обучения «с нуля», но все еще есть некоторые проблемы с этим уроком, которые решаются. Поэтому я хотел бы по крайней мере понять, что может быть не так с моей текущей моделью / подходом. Однако, если проблема определенно заключается в преобразовании PyTorch-> ONNX-> CoreML, тогда я не хочу участвовать в этой битве и просто углублюсь в то, что предлагает HuggingFace.
Любые мысли приветствуются.
ОБНОВЛЕНИЕ: По совету Матти js, я пытаюсь предсказать из модели в python:
from coremltools.models import *
import numpy as np
# Just a "dummy" input, but it is a valid series of tokens for my data.
tokens = [3, 68, 45, 68, 45, 5, 45, 68, 45, 4]
tokens_tensor = np.zeros((1, 128))
for i in range(0, 10):
tokens_tensor[0, i] = tokens[I]
# I'm doing masked token prediction, so one segment.
segments_tensor = np.zeros((1, 128))
mlmodel = 'bert_fp16.mlmodel'
model = MLModel(mlmodel)
spec = model.get_spec()
print("spec: ", spec.description)
predictions = model.predict({'input.1': np.asarray(tokens_tensor, dtype=np.int32), 'input.3': np.asarray(segments_tensor, dtype=np.int32)})
Я признаю, что я не запускал mlmodel из python раньше, но я думаю, что данные верны. Spe c указывает:
input {
name: "input.1"
type {
multiArrayType {
shape: 1
shape: 128
dataType: INT32
}
}
}
input {
name: "input.3"
type {
multiArrayType {
shape: 1
shape: 128
dataType: INT32
}
}
}
...
для моих входов.
В этом случае я не получаю сообщение cannot squeeze
или код ошибки (-5), но это не с Error computing NN outputs
. Так что что-то определенно не так. Я просто не совсем уверен, как go отладить его.
J.
ОБНОВЛЕНИЕ: Для сравнения я обучил / преобразовал модель BERT HuggingFace (на самом деле, DistilBert - Я обновил код выше соответственно) и имею ту же ошибку. Глядя на журнал из onnx, я вижу, что добавлен один Squeeze
(также, конечно, из журнала onnx-coreml), но единственный squeeze
в коде PyTorch находится в BertForQuestionAnswering
, а не BertForMaskedLM
. Возможно, onnx строит модель ответа на вопрос, а не MLM (или вопрос, отвечающий на вопрос, сохраняется в контрольной точке)?
Глядя на пример кода swift-coreml-transformers, я вижу, что на входахtilBert просто let input_ids = MLMultiArray.from(allTokens, dims: 2)
, и именно так я его и определил. Так что я в тупике, я думаю. Кому-нибудь удалось запустить MLM с Bert / DistilBert в CoreML (через onnx)? Если это так, пример был бы очень полезен.
Я тренируюсь, используя последние run_language_modeling.py
от HuggingFace, кстати.
Глядя на mlmodel в Netron, я вижу оскорбительные squeeze
. Признаюсь, я не знаю, для чего предназначена эта ветвь ввода, но я предполагаю, что это маска (и еще одно предположение может быть связано с ответом на вопрос). Могу ли я просто удалить это как-нибудь?