Тензор с пустым именем не найден при обслуживании модели

Системная информация

  • Linux Ubuntu 16.04:
  • TensorFlow Serving устанавливается из пункта (1.10.1):
  • Версия обслуживания TensorFlow 1.10.1:

Опишите проблему

Я обнаружил сообщение об ошибке в проводной сети при обслуживании своей собственной модели, я протестировал файл.pb с save_model.load, и все хорошо, но когда я отправляю запрос через клиента, появляется следующая ошибка:

<_Rendezvous для RPC, завершившегося с помощью: status = StatusCode.INVALID_ARGUMENT details = "Тензор:0, указанный либо в feed_devices, либо в fetch_devices, не найден в графе" debug_error_string = "{" создал ":" @ 1537040456.210975912 "," описание ": "Ошибка, полученная от однорангового узла", "файл": "src / core / lib / surface / call.cc", "file_line": 1099, "grpc_message": " Тензор: 0, указанный в feed_devices или fetch_devices, не найден в График ","grpc_status":3}" >

Проводная часть - это то, что Tensor, о котором сообщается, что он не найден, не имеет имени, которое, как я полагаю, вызвано тем, что клиент просит ввести этот пустой тензор. Но я просто не понимаю, откуда может произойти эта операция.

Точные шаги для воспроизведения

Я создаю обслуживание на основе примера клиента mnist и исходного клиента. Экспортированная модель.pb была успешно протестирована путем перезагрузки через tf.saved_model.loader.load, поэтому я думаю, что проблема вызвана запросом.

Это часть клиентского кода:

channel = grpc.insecure_channel(FLAGS.server)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
request = predict_pb2.PredictRequest()
request.model_spec.name = 'chiron'
request.model_spec.signature_name = tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
collector = _Result_Collection()
for batch_x,seq_len,i,f,N,reads_n in data_iterator(FLAGS.raw_dir):
    request.inputs['signals'].CopyFrom(
        tf.contrib.util.make_tensor_proto(batch_x, shape=[FLAGS.batch_size, CONF.SEGMENT_LEN]))
    request.inputs['seq_length'].CopyFrom(
        tf.contrib.util.make_tensor_proto(seq_len, shape=[FLAGS.batch_size]))
    result_future = stub.Predict.future(request, 5.0)  # 5 seconds
    result_future.add_done_callback(_post_process(collector,i,f))

2 ответа

Я нашел причину, это потому что при создании TensorProto SparseTensor, ему не присваивается имя. Смотрите также здесь: https://github.com/tensorflow/serving/issues/1100 Таким образом, решением было бы создание TensorProto для Sparse Tensor отдельно:

import tensorflow as tf
signal =  tf.constant([[[1]]])
sequence_length = tf.constant([1])
output,log_prob = tf.nn.ctc_beam_search_decoder(signal,sequence_length)
indices = output[0].indices
values = output[0].values
dense_shape = output[0].dense_shape
indices_tensor_proto = tf.saved_model.utils.build_tensor_info(indices)
values_tensor_proto = tf.saved_model.utils.build_tensor_info(values)
dense_shape_tensor_proto = tf.saved_model.utils.build_tensor_info(dense_shape)

У меня была эта проблема с моделью LSTM + RaggedTensors, у моего выходного тензора было пустое имя. Я думаю, это связано с тем, что модель выводит рваные тензоры.

      The given SavedModel SignatureDef contains the following output(s):
    outputs['output_1'] tensor_info:
        dtype: DT_INVALID
        shape: ()
        name: 
  Method name is: tensorflow/serving/predict

Я решил это, написав пользовательскую выходную подпись и преобразовав выходные данные моделей в обычный тензор. Это работало для функциональной модели и модели с подклассами.

          @tf.function()
    def overwrite_predict_signature(prediction_input):
        inputs = prediction_input
        prediction = model.call(inputs)
        return {"named_prediction_outputs": prediction.to_tensor()}

    my_signatures = overwrite_predict_signature.get_concrete_function(
       prediction_input={'feature_1': RaggedTensorSpec(TensorShape([None, None, 1]), tf.float32, 1, tf.int64), 'feature_2': RaggedTensorSpec(TensorShape([None, None, 1]), tf.string, 1, tf.int64), 'feature_3': RaggedTensorSpec(TensorShape([None, None, 1]), tf.float32, 1, tf.int64), 'feature_4': RaggedTensorSpec(TensorShape([None, None, 1]), tf.string, 1, tf.int64), 'feature_5': RaggedTensorSpec(TensorShape([None, None, 1]), tf.int32, 1, tf.int64)})

    tf.saved_model.save(model, export_dir=(args.sm_model_dir + "/1/"), signatures=my_signatures)

Который зарегистрировал операцию/функцию с моим выводом.

       The given SavedModel SignatureDef contains the following output(s):
    outputs['named_prediction_outputs'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, -1, 1)
        name: StatefulPartitionedCall:0
  Method name is: tensorflow/serving/predict
Другие вопросы по тегам