Docker 部署tensorflow服务客户端脚本

Docker 部署tensorflow服务客户端脚本,docker,tensorflow,kubernetes,google-cloud-platform,tensorflow-serving,Docker,Tensorflow,Kubernetes,Google Cloud Platform,Tensorflow Serving,我是tensorflow的新手,正在学习如何部署生产模型。我已经在GCP云存储上部署了我的Tensorflow对象检测模型,它可以在Google Kubernetes引擎上使用,并且有一个端点。现在,我想部署使用gRPC的客户机脚本(而不是REST以获得更快的响应时间)。如何部署客户端脚本,使其作为API请求提供给外部世界,并使其能够获取编码的图像阵列,向服务模型发出请求,然后将其响应返回给用户?我希望它有快速的响应时间,并可能处理多个请求一次。客户端脚本是: import os import

我是tensorflow的新手,正在学习如何部署生产模型。我已经在GCP云存储上部署了我的Tensorflow对象检测模型,它可以在Google Kubernetes引擎上使用,并且有一个端点。现在,我想部署使用gRPC的客户机脚本(而不是REST以获得更快的响应时间)。如何部署客户端脚本,使其作为API请求提供给外部世界,并使其能够获取编码的图像阵列,向服务模型发出请求,然后将其响应返回给用户?我希望它有快速的响应时间,并可能处理多个请求一次。客户端脚本是:

import os

import argparse
from argparse import RawTextHelpFormatter

from grpc.beta import implementations
import numpy as np
from PIL import Image
import tensorflow as tf

from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc

from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
from object_detection.core.standard_fields import \
    DetectionResultFields as dt_fields

tf.logging.set_verbosity(tf.logging.INFO)

def load_image_into_numpy_array(input_image):
    image = Image.open(input_image)
    (im_width, im_height) = image.size
    image_arr = np.array(image.getdata()).reshape(
        (im_height, im_width, 3)).astype(np.uint8)
    image.close()
    return image_arr

def load_input_tensor(input_image):
    image_np = load_image_into_numpy_array(input_image)
    image_np_expanded = np.expand_dims(image_np, axis=0).astype(np.uint8)
    tensor = tf.contrib.util.make_tensor_proto(image_np_expanded)
    return tensor

def main(args):
    host, port = args.server.split(':')
    channel = implementations.insecure_channel(host, int(port))._channel
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    request = predict_pb2.PredictRequest()
    request.model_spec.name = args.model_name

    input_tensor = load_input_tensor(args.input_image)
    request.inputs['inputs'].CopyFrom(input_tensor)

    result = stub.Predict(request, 60.0)
    image_np = load_image_into_numpy_array(args.input_image)

    output_dict = {}
    output_dict[dt_fields.detection_classes] = np.squeeze(
        result.outputs[dt_fields.detection_classes].float_val).astype(np.uint8)
    output_dict[dt_fields.detection_boxes] = np.reshape(
        result.outputs[dt_fields.detection_boxes].float_val, (-1, 4))
    output_dict[dt_fields.detection_scores] = np.squeeze(
        result.outputs[dt_fields.detection_scores].float_val)

    category_index = label_map_util.create_category_index_from_labelmap(args.label_map,
                                                                        use_display_name=True)

    vis_util.visualize_boxes_and_labels_on_image_array(image_np,
      output_dict[dt_fields.detection_boxes],
      output_dict[dt_fields.detection_classes],
      output_dict[dt_fields.detection_scores],
      category_index,
      instance_masks=None,
      use_normalized_coordinates=True,
      line_thickness=8)
    output_img = Image.fromarray(image_np.astype(np.uint8))
    base_filename = os.path.splitext(os.path.basename(args.input_image))[0]
    output_image_path = os.path.join(args.output_directory, base_filename + "_output.jpg")
    tf.logging.info('Saving labeled image: %s' % output_image_path)
    output_img.save(output_image_path)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Object detection grpc client.",
                                     formatter_class=RawTextHelpFormatter)
    parser.add_argument('--server',
                        type=str,
                        required=True,
                        help='PredictionService host:port')
    parser.add_argument('--model_name',
                        type=str,
                        required=True,
                        help='Name of the model')
    parser.add_argument('--input_image',
                        type=str,
                        required=True,
                        help='Path to input image')
    parser.add_argument('--output_directory',
                        type=str,
                        required=True,
                        help='Path to output directory')
    parser.add_argument('--label_map',
                        type=str,
                        required=True,
                        help='Path to label map file')

    args = parser.parse_args()
    main(args) 
我正在考虑用docker构建一个包含tensorflow、tensorflow服务api和客户端脚本的微服务

更新1:我尝试使用grpc客户端时遇到问题。 因为我使用了,请求的url的形式是:predict。但是客户端脚本似乎不接受这种url格式。它只接受主机:端口号格式,我得到一个错误

Traceback (most recent call last):
  File "object_detection_grpc_client.py", line 104, in <module>
    main(args)
  File "object_detection_grpc_client.py", line 41, in main
    stub = prediction_service_pb2_grpc.PredictionServiceStub('http://A.B.C.D:8000/model/my-model:predict')
  File "/usr/local/lib/python3.5/dist-packages/tensorflow_serving/apis/prediction_service_pb2_grpc.py", line 40, in __init__
    self.Classify = channel.unary_unary(
AttributeError: 'str' object has no attribute 'unary_unary'
回溯(最近一次呼叫最后一次):
文件“object\u detection\u grpc\u client.py”,第104行,在
主(args)
文件“object\u detection\u grpc\u client.py”,第41行,主
存根=预测服务pb2 grpc.PredictionServiceStub('http://A.B.C.D:8000/model/my-模型:预测')
文件“/usr/local/lib/python3.5/dist-packages/tensorflow\u-serving/api/prediction\u-service\u-pb2\u-grpc.py”,第40行,在init中__
self.Classify=channel.monary\u一元(
AttributeError:“str”对象没有属性“一元”
当我仅使用A.B.C.D:8000作为服务器参数值时,我得到错误:

Traceback (most recent call last):
  File "object_detection_grpc_client.py", line 104, in <module>
    main(args)
  File "object_detection_grpc_client.py", line 48, in main
    result = stub.Predict(request, 60.0)
  File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 550, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 467, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
    status = StatusCode.UNAVAILABLE
    details = "Socket closed"
    debug_error_string = "{"created":"@1550755989.677583779","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1036,"grpc_message":"Socket closed","grpc_status":14}"
>
回溯(最近一次呼叫最后一次):
文件“object\u detection\u grpc\u client.py”,第104行,在
主(args)
文件“object\u detection\u grpc\u client.py”,第48行,主
结果=存根预测(请求,60.0)
文件“/usr/local/lib/python3.5/dist packages/grpc/_channel.py”,第550行,在调用中__
返回\u结束\u一元\u响应\u阻塞(状态、调用、错误、无)
文件“/usr/local/lib/python3.5/dist packages/grpc/_channel.py”,第467行,一元响应中
提升集合点(状态,无,无,截止日期)
grpc._通道_会合点:

我直接使用了存储库中可用的predict protobufs。我如何修改代码以解决问题?

如果您使用的是grpc客户端,您的主机格式应该是host:PORT。并且是rest\u api格式。请确保您的端口正确。您能说明启动tf服务的方式吗?

如果您使用的是grpc客户端,您的主机格式应该是be HOST:PORT。并且是rest\U api格式。请确保您的端口是正确的。您能展示一下启动tf服务的方式吗?

到目前为止您做了什么?您遇到了什么问题吗?我确实遇到了问题。相应地更新了问题。@CRU我也包含了错误消息。到目前为止您做了什么?您遇到了什么问题吗?我没有取消进入问题。相应地更新了问题。@cru我也包含了错误消息。实际上,我使用命令“kubectl-n default port forward service/my model 9000:9000”使用端口转发解决了这个问题。使用这个命令,我可以使用localhost:9000作为我的主机格式。但是我遇到了另一个问题。这个方法对deb很好在开发环境中进行UGG和测试,但不针对生产环境,因为响应时间很长。实际上,我使用命令“kubectl-n default port forward service/my model 9000:9000”使用端口转发解决了这个问题。使用这个命令,我可以使用localhost:9000作为主机格式。但我遇到了另一个问题。此方法适用于开发环境中的调试和测试,但不适用于生产环境,因为响应时间较长。