TFX - REST API без сериализации вводимых данных для получения прогнозов

Я новичок в TFX, изучал руководство по Keras и успешно создал конвейер TFX, используя свои данные. Пока я учусь обслуживать свою модель через Docker с TF Serving, мои вводимые данные должны быть сериализованы следующим образом, чтобы вернуть результат прогнозирования.

Как я могу вводить данные в REST API без сериализации ввода данных. При этом я создал вторую функцию - def_get_serve_raw. Тренер успешно создан, но я не могу вызвать его с исходным вводом данных через REST API. Я тестировал несколько форматов, но каждый раз возникала другая ошибка.

Что мне делать в функции def_get_served_raw, чтобы модель принимала входные данные без данных base64?

К вашему сведению - модель имеет 2 входа данных в виде строк.

Ниже показано, что у меня есть на def run_fn в трейнере TFX

def _get_serve_tf_examples_fn(model, tf_transform_output):

    model.tft_layer = tf_transform_output.transform_features_layer()

    @tf.function
    def serve_tf_examples_fn(serialized_tf_examples):
        """Returns the output to be used in the serving signature."""
        feature_spec = tf_transform_output.raw_feature_spec()
        feature_spec.pop(features.LABEL_KEY)
        parsed_features = tf.io.parse_example(serialized_tf_examples, feature_spec)

        transformed_features = model.tft_layer(parsed_features)
        transformed_features.pop(features.transformed_name(features.LABEL_KEY))

        outputs = model(transformed_features)
        return {'outputs': outputs}

    return serve_tf_examples_fn

def _get_serve_raw(model, transform_output):

    model.tft_layer = tf_transform_output.transform_features_layer()

    @tf.function
    def serve_raw_fn(country_code, project_type):

        country_code_sp_tensor = tf.sparse.SparseTensor(
            indices= [[0,0]],
            values= country_code,
            dense_shape= (1,1)
        )

        project_type_sp_tensor = tf.sparse.SparseTensor(
            indices= [[0,0]],
            values= project_type,
            dense_shape= (1,1)
        )

        parsed_features = {'Country_Code' : country_code_sp_tensor,
                           'Project_Type' : project_type_sp_tensor}

        transformed_features = model.tft_layer(parsed_features)
        transformed_features.pop(_transformed_name(_LABEL_KEY_EA))

        outputs = model(transformed_features)
        return {'outputs': outputs}

    return serve_raw_fn



signatures = { "serving_default": _get_serve_tf_examples_fn(model, tf_transform_output).get_concrete_function(
                                    tf.TensorSpec(shape=[None], dtype=tf.string, name='examples')),
               "serving_raw": _get_serve_raw(model, tf_transform_output).get_concrete_function(
                                    tf.TensorSpec(shape=[None], dtype=tf.string, name='country_code'),
                                    tf.TensorSpec(shape=(None), dtype=tf.string, name='project_type'))}


model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)

Подпись обслуживания

MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['__saved_model_init_op']:
  The given SavedModel SignatureDef contains the following input(s):
  The given SavedModel SignatureDef contains the following output(s):
    outputs['__saved_model_init_op'] tensor_info:
        dtype: DT_INVALID
        shape: unknown_rank
        name: NoOp
  Method name is: 

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['examples'] tensor_info:
        dtype: DT_STRING
        shape: unknown_rank
        name: serving_default_examples:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['outputs'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: StatefulPartitionedCall:0
  Method name is: tensorflow/serving/predict

signature_def['serving_raw']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['raw'] tensor_info:
        dtype: DT_STRING
        shape: unknown_rank
        name: serving_raw_raw:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['outputs'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: StatefulPartitionedCall_1:0
  Method name is: tensorflow/serving/predict

ТЕСТ И ОШИБКА 1:

url = f'http://localhost:8501/v1/models/ea:predict'
headers = {"content-type": "application/json"}
data = {
  "signature_name":"serving_raw",
  "instances":[
     {
       "raw":{"countty_code": "US",
              "project_type": "Delivery"}
    }
  ]
}

data = json.dumps(data)
print(data)
json_response = requests.post(url, data=data, headers=headers)
print(json_response.content)
print(json_response.json)

b'{\n    "error": "Failed to process element: 0 key: raw of \'instances\' list. Error: Invalid argument: JSON Value: {\\n    \\"country_code\\": \\"US\\",\\n    \\"project_type\\": \\"Delivery\\"\\n} not formatted correctly for base64 data"\n}'

ТЕСТ И ОШИБКА 2

url = f'http://localhost:8501/v1/models/ea:predict'
headers = {"content-type": "application/json"}
data = {
  "signature_name":"serving_raw",
  "instances":[
     {
       "raw":{"b64": "US",
              "b64": "Delivery"}
    }
  ]
}

data = json.dumps(data)
print(data)
json_response = requests.post(url, data=data, headers=headers)
print(json_response.content)
print(json_response.json)

b'{\n    "error": "You must feed a value for placeholder tensor \'StatefulPartitionedCall_1/StatefulPartitionedCall/transform_features_layer_1/transform/transform/inputs/F_Project_Type/shape\' with dtype int64 and shape [2]\\n\\t [[{{node transform_features_layer_1/transform/transform/inputs/F_Project_Type/shape}}]]"\n}'

person LLTeng    schedule 10.06.2020    source источник


Ответы (1)


После повторного тестирования тест 1 успешно выполнен.

person LLTeng    schedule 12.06.2020