Tensorflow,Tensorflow-serving:SavedModel签名的多个输入

时间:2017-06-20 15:47:51

标签: tensorflow tensorflow-serving

我正在尝试通过SavedModel导出我的模型进行服务,并且在do推断调用中遇到服务客户端上的问题。

error: 
grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Missing ModelSpec")

我有4个占位符必须提供,输入,丢失(将推断为1.0),以及(一个可怕的解决方法)加载预先训练的GoogleW2V矢量嵌入(由于它们的大小,我必须提供它们通过占位符到嵌入查找的图形。我把它们分成两半,因为在服务客户端我必须创建一个tensor_proto来提供给占位符,你不能创建大于2 GB的张量原型。所以作为一种解决方法我打破它们一半,并在图表中完成它们

在我的模型中,我将签名保存如下(我试图让它尽可能简单,以帮助弄清楚如何使用多个输入)。

builder = saved_model_builder.SavedModelBuilder(export_path)

tensor_info_x = utils.build_tensor_info(model._input)
tensor_info_dropout = utils.build_tensor_info(model._dropout)
tensor_info_emb1 = utils.build_tensor_info(model._embeddingPlaceholder1)
tensor_info_emb2 = utils.build_tensor_info(model._embeddingPlaceholder2)
tensor_info_y = utils.build_tensor_info(model.softmaxPredictions)

prediction_signature = signature_def_utils.build_signature_def(
inputs={'inputs': tensor_info_x,
        'dropout': tensor_info_dropout,
        'googlew2v1': tensor_info_emb1,
        'googlew2v2': tensor_info_emb2
 },
 outputs={'softmaxPredictions': tensor_info_y},
 method_name=signature_constants.PREDICT_METHOD_NAME)

builder.add_meta_graph_and_variables(
    tfSession,
    [tag_constants.SERVING],
    signature_def_map={
       'softmaxPredictions': prediction_signature
})

builder.save()

在客户端我做推理:

def do_sem_inference(vs, data):

    host, port = CONFIG.semserver.split(':')
    channel = implementations.insecure_channel(host, int(port))
    stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)
    request = predict_pb2.PredictRequest()
    request.model_spec.name = 'sem'
    request.model_spec.signature_name = 'softmaxPredictions'

    proto = tf.contrib.util.make_tensor_proto(data, dtype=tf.int32)
    request.inputs['inputs'].CopyFrom(proto)

    dropoutProto = tf.contrib.util.make_tensor_proto(1.0, dtype=tf.float32)
    request.inputs['dropout'].CopyFrom(dropoutProto)

    #####
    # This is the reason I have to break the GoogleW2V in half, tensor_proto cannot be larger than 2GB
    #####

    googlew2vProto1 = tf.contrib.util.make_tensor_proto(vs.wordVectors()[:1500000], dtype=tf.float32)
    request.inputs['googlew2v1'].CopyFrom(googlew2vProto1)
    googlew2vProto2 = tf.contrib.util.make_tensor_proto(vs.wordVectors()[1500000:], dtype=tf.float32)
    request.inputs['googlew2v2'].CopyFrom(googlew2vProto2)

    result_future = stub.Predict.future(request, 100.0)
    results = tf.contrib.util.make_ndarray(result_future.result().outputs['outputs'])

但是我得到了错误(如上所示):

Traceback (most recent call last):
  File "sem_client.py", line 121, in <module>
    tf.app.run()
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/platform/app.py", line 48, in run
    _sys.exit(main(_sys.argv[:1] + flags_passthrough))
  File "sem_client.py", line 114, in main
    result = do_sem_inference(vectorSpace, embeddingLookup(vectorSpace, sentence))
  File "sem_client.py", line 66, in do_sem_inference
    results = tf.contrib.util.make_ndarray(result_future.result().outputs['outputs'])
  File "/usr/local/lib/python2.7/dist-packages/grpc/beta/_client_adaptations.py", line 112, in result
    raise _abortion_error(rpc_error_call)
grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Missing ModelSpec")

我在网上寻求使用多个输入签名的帮助,有人说使用exporter.generic_signature,但是源代码说这是不推荐使用的,而是使用SavedModel。我还没有看到任何显示如何使用generic_signature的明显示例。我还发现没有通过SavedModel对签名使用多个输入的示例,任何想法如何使其工作?

感谢您的帮助和建议。

P.S。我也有兴趣避免不得不将googleW2V嵌入分成两半并通过占位符将其输入(同样,由于需要提供此模型)。目标是在googleW2V中查找嵌入并在我的模型中使用它们(我知道如何在不使用google w2v嵌入的情况下执行此操作,但我更愿意使用这些)。

2 个答案:

答案 0 :(得分:0)

因此,当我坐下来思考它时,我想我已经弄明白了发生了什么,手头的问题和它的愚蠢。

googlew2v矢量嵌入大约为3GB。在我的服务客户端中,我试图为嵌入设置输入张量,然后进行RPC调用......必须有一些安全措施,不允许我尝试RPC那么多的数据(做&#39; h)。关于这一点的错误并不是很清楚,但是一旦我随机使用了一个小的嵌入子集就没问题了。

我想我可以为我的用例提出一个解决方法。但是现在我不能让googlew2v嵌入在我的模型中作为占位符(否则我必须在服务器期间提供它们并且它不会允许我通过RPC发送非常大的数据。即使它确实需要永远)。

我现在在我的项目中有一个解决方法(我只是在训练和服务之前进行嵌入查找等)。但是如果它可能希望选择通过变量或类似物将Googlew2v嵌入包含在我的模型中而不必将它们作为占位符(这样我就可以利用tf.nn.embedding_lookup并行性和速度)。 / p>

答案 1 :(得分:0)

导出pb模型时,您可以在构建器中使用资产,并且在使用able = lookup.index_table_from_file(vocab_path)

定义模型时可以使用input_x = tf.placeholder(tf.string, ... )