Форматирование ввода для обслуживаемой модели tenorflow 2 BERT - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь обслуживать модель BERT, используя TF 2.1 (модель Keras) и TF, обслуживающие Colab.

Я следовал руководству (https://www.tensorflow.org/tfx/tutorials/serving/rest_simple), и он работал хорошо , Но в этом уроке ввод в обслуживаемую модель достаточно прост (это список тензоров).

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['Conv1_input'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 28, 28, 1)
        name: serving_default_Conv1_input:0

В случае модели BERT ввод модели при выводе - это словарь с ключами:

dict_keys(['input_ids', 'attention_mask', 'token_type_ids', 'labels']

и результаты проверки сохраненной модели:

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['attention_mask'] tensor_info:
        dtype: DT_INT32
        shape: (-1, 128)
        name: serving_default_attention_mask:0
    inputs['input_ids'] tensor_info:
        dtype: DT_INT32
        shape: (-1, 128)
        name: serving_default_input_ids:0
    inputs['labels'] tensor_info:
        dtype: DT_INT32
        shape: (-1, 1)
        name: serving_default_labels:0
    inputs['token_type_ids'] tensor_info:
        dtype: DT_INT32
        shape: (-1, 128)
        name: serving_default_token_type_ids:0

Я создал словарь ввода для проверки обслуживаемой модели с 5 предложениями. Это хорошо работает, когда я выполняю выводы для необслуживаемой модели Keras:

label_predictions = model(test_deploy_inputs)
label_predictions
(<tf.Tensor: shape=(5, 2), dtype=float32, numpy=
 array([[-2.1985834,  1.7191753],
        [ 2.7828176, -2.9217367],
        [ 3.2120934, -3.2556024],
        [ 3.4262116, -3.4961216],
        [-2.6834514,  2.2755196]], dtype=float32)>,)

Я создал модифицированную версию этих входных данных, заменив тензоры списками:

inputs = {"input_ids": np.array(all_input_ids).tolist(), 
            "attention_mask": np.array(all_input_mask).tolist(), 
            "token_type_ids": np.array(all_input_type_ids).tolist(), 
            "labels": np.array(all_label).tolist()} 

Не знаю не знаю, как отформатировать ввод данных для обслуживаемой модели. Учебное пособие использует:

data = json.dumps({"signature_name": "serving_default", "instances": test_images[0:3].tolist()})

Я попытался заменить его своим измененным вводом следующим образом:

data = json.dumps({"signature_name": "serving_default", "instances": test_deploy_inputs2})

Когда я выполняю вызов API для выполнения выводов на обслуживаемой модели, я получаю 400 сообщение об ошибке.

headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/fashion_model:predict', data=data, headers=headers)
json_response
<Response [400]>

Я не знаю, связано ли это с тем, как я определяю свои входные данные или передаю их в API.

Я видел другие попытки обслуживания Модели BERT на TF 1.x с использованием оценщика и определения (или переопределения?) Функции serve_input_fn ( Создать SavedModel для BERT ):

def serving_input_fn():
  feature_spec = {
      "input_ids" : tf.FixedLenFeature([MAX_SEQ_LENGTH], tf.int64),
      "input_mask" : tf.FixedLenFeature([MAX_SEQ_LENGTH], tf.int64),
      "segment_ids" : tf.FixedLenFeature([MAX_SEQ_LENGTH], tf.int64),
      "label_ids" :  tf.FixedLenFeature([], tf.int64)

  }
  serialized_tf_example = tf.placeholder(dtype=tf.string, 
                                         shape=[None],
                                         name='input_example_tensor')
  receiver_tensors = {'example': serialized_tf_example}
  features = tf.parse_example(serialized_tf_example, feature_spec)
  return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

Любая помощь будет принята с благодарностью:)

...