Tensorflow、Tensorflow-serving:SavedModel 签名的多个输入
Tensorflow, Tensorflow-serving: Multiple inputs for SavedModel signature
我正在尝试导出我的模型以通过 SavedModel 提供服务,并且 运行 在 do 推理调用中遇到服务客户端的问题。
error:
grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Missing ModelSpec")
我有 4 个必须提供的占位符,输入、dropout(推理时将为 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 中的嵌入并在我的模型中使用它们(我知道不使用 googlew2v 嵌入的方法,但我更愿意使用这些)。
所以我想我弄清楚了正在发生的事情和手头的问题,一旦我坐下来思考它就有点傻了。
googlew2v 向量嵌入大约为 ~3GB。在我的服务客户端中,我试图为嵌入设置输入张量,然后进行 RPC 调用......必须有一些保护措施不允许我尝试对那么多数据进行 RPC (do'h)。这个错误不是很清楚,但是一旦我随机使用嵌入的一小部分,它就没问题了。
我想我可以为我的用例想出一个解决方法。但现在我无法让 googlew2v 嵌入成为我模型中的占位符(否则我必须在服务器期间提供它们并且它不允许我通过 RPC 发送非常大的数据。即使它做到了这将需要永远)。
我现在在我的项目中有一个解决方法(我只是在训练和服务之前进行嵌入查找等)。但是,如果可能的话,我希望可以选择通过变量或其他方式将 Googlew2v 嵌入包含在我的模型中,而不必将它们作为占位符(这样我就可以利用 tf.nn.embedding_lookup 并行性和速度)。
导出 pb 模型时可以在构建器中使用资产,使用 input_x = tf.placeholder(tf.string, ... )
定义模型时可以使用 able = lookup.index_table_from_file(vocab_path)
我正在尝试导出我的模型以通过 SavedModel 提供服务,并且 运行 在 do 推理调用中遇到服务客户端的问题。
error:
grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Missing ModelSpec")
我有 4 个必须提供的占位符,输入、dropout(推理时将为 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 中的嵌入并在我的模型中使用它们(我知道不使用 googlew2v 嵌入的方法,但我更愿意使用这些)。
所以我想我弄清楚了正在发生的事情和手头的问题,一旦我坐下来思考它就有点傻了。
googlew2v 向量嵌入大约为 ~3GB。在我的服务客户端中,我试图为嵌入设置输入张量,然后进行 RPC 调用......必须有一些保护措施不允许我尝试对那么多数据进行 RPC (do'h)。这个错误不是很清楚,但是一旦我随机使用嵌入的一小部分,它就没问题了。
我想我可以为我的用例想出一个解决方法。但现在我无法让 googlew2v 嵌入成为我模型中的占位符(否则我必须在服务器期间提供它们并且它不允许我通过 RPC 发送非常大的数据。即使它做到了这将需要永远)。
我现在在我的项目中有一个解决方法(我只是在训练和服务之前进行嵌入查找等)。但是,如果可能的话,我希望可以选择通过变量或其他方式将 Googlew2v 嵌入包含在我的模型中,而不必将它们作为占位符(这样我就可以利用 tf.nn.embedding_lookup 并行性和速度)。
导出 pb 模型时可以在构建器中使用资产,使用 input_x = tf.placeholder(tf.string, ... )
able = lookup.index_table_from_file(vocab_path)