如何使用 inception/mobilenet 模型设置 tfserving 以进行图像分类?
How to setup tfserving with inception/mobilenet model for image classification?
我找不到合适的文档来成功地为 inception 或 mobilenet 模型提供服务并编写 grpc 客户端来连接到服务器并执行图像分类。
到目前为止,我只在 CPU 上成功配置了 tfserving 图像。无法在我的 GPU 上 运行 它。
但是,当我发出 grpc 客户端请求时,请求失败并出现错误。
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.INVALID_ARGUMENT
details = "Expects arg[0] to be float but string is provided"
debug_error_string = "{"created":"@1571717090.210000000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1017,"grpc_message":"Expects arg[0] to be float but string is provided","grpc_status":3}"
我知道请求格式存在一些问题,但我找不到可以准确指出正确方向的 grpc 客户端的适当文档。
这是我用于请求的 grpc 客户端。
from __future__ import print_function
import grpc
import tensorflow as tf
import time
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
tf.app.flags.DEFINE_string('server', 'localhost:8505',
'PredictionService host:port')
tf.app.flags.DEFINE_string('image', 'E:/Data/Docker/tf_serving/cat.jpg', 'path to image')
FLAGS = tf.app.flags.FLAGS
def main(_):
channel = grpc.insecure_channel(FLAGS.server)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
# Send request
with open(FLAGS.image, 'rb') as f:
# See prediction_service.proto for gRPC request/response details.
data = f.read()
request = predict_pb2.PredictRequest()
request.model_spec.name = 'inception'
request.model_spec.signature_name = ''
request.inputs['image'].CopyFrom(tf.contrib.util.make_tensor_proto(data, shape=[1]))
result = stub.Predict(request, 5.0) # 10 secs timeout
print(result)
print("Inception Client Passed")
if __name__ == '__main__':
tf.app.run()
据我了解,你的问题有两个问题。
A) 运行 GPU 上的 tfserving。
B) 发出成功的 grpc 客户端请求。
让我们一个一个开始。
运行 GPU 上的 tfserving
这是简单的两步过程。
正在从 official docker hub page 中提取最新图像。
docker pull tensorflow/serving:latest-gpu
请注意上面拉取请求中的标签 latest-gpu
,因为它会拉取用于 GPU 的图像。
运行 docker 容器。
sudo docker run -p 8502:8500 --mount type=bind,source=/my_model_dir,target=/models/inception --name tfserve_gpu -e MODEL_NAME=inception --gpus device=3 -t tensorflow/serving:latest-gpu
请注意,我已将参数 --gpus device=3
传递给 select 第三个 GPU 设备。将其相应地更改为 select 不同的 GPU 设备。
验证容器是否已通过 docker ps
命令启动。
此外,验证是否已通过 nvidia-smi
命令为 tfserving docker 分配了 gpu。
nvidia-smi 的输出
不过这里好像有点问题。 tfserving docker 已消耗所有 gpu 设备内存。
要限制 gpu 内存使用,请使用 per_process_gpu_memory_fraction
标志。
sudo docker run -p 8502:8500 --mount type=bind,source=/my_model_dir,target=/models/inception --name tfserve_gpu -e MODEL_NAME=inception --gpus device=3 -t tensorflow/serving:latest-gpu --per_process_gpu_memory_fraction=0.02
nvidia-smi 的输出
现在,我们已经成功地在 GPU 设备上配置了 tfserving docker,并且具有合理的 GPU 内存使用率。让我们跳到第二个问题。
发出 GRPC 客户端请求
您的 grpc 客户端请求的格式存在问题。 tfserving docker 图像不会直接以二进制格式获取图像,相反,您必须为该图像制作一个张量,然后将其传递给服务器。
这是发出 grpc 客户端请求的代码。
from __future__ import print_function
import argparse
import time
import numpy as np
from cv2 import imread
import grpc
from tensorflow.contrib.util import make_tensor_proto
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
import tensorflow as tf
def read_tensor_from_image_file(file_name,
input_height=299,
input_width=299,
input_mean=0,
input_std=255):
input_name = "file_reader"
output_name = "normalized"
file_reader = tf.io.read_file(file_name, input_name)
if file_name.endswith(".png"):
image_reader = tf.image.decode_png(
file_reader, channels=3, name="png_reader")
elif file_name.endswith(".gif"):
image_reader = tf.squeeze(
tf.image.decode_gif(file_reader, name="gif_reader"))
elif file_name.endswith(".bmp"):
image_reader = tf.image.decode_bmp(file_reader, name="bmp_reader")
else:
image_reader = tf.image.decode_jpeg(
file_reader, channels=3, name="jpeg_reader")
float_caster = tf.cast(image_reader, tf.float32)
dims_expander = tf.expand_dims(float_caster, 0)
resized = tf.compat.v1.image.resize_bilinear(dims_expander, [input_height, input_width])
normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
sess = tf.Session(config=tf.ConfigProto(gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.01)))
result = sess.run(normalized)
return result
def run(host, port, image, model, signature_name):
# Preparing tensor from the image
tensor = read_tensor_from_image_file(file_name='images/bird.jpg', input_height=224, input_width=224, input_mean=128, input_std=128)
# Preparing the channel
channel = grpc.insecure_channel('{host}:{port}'.format(host=host, port=port))
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
# Preparing grpc request
request = predict_pb2.PredictRequest()
request.model_spec.name = model
request.model_spec.signature_name = signature_name
request.inputs['image'].CopyFrom(make_tensor_proto(tensor, shape=[1, 224, 224, 3]))
# Making predict request
result = stub.Predict(request, 10.0)
# Analysing result to get the prediction output.
predictions = result.outputs['prediction'].float_val
print("Predictions : ", predictions)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--host', help='Tensorflow server host name', default='localhost', type=str)
parser.add_argument('--port', help='Tensorflow server port number', default=8502, type=int)
parser.add_argument('--image', help='input image', default='bird.jpg', type=str)
parser.add_argument('--model', help='model name', default='inception', type=str)
parser.add_argument('--signature_name', help='Signature name of saved TF model',
default='serving_default', type=str)
args = parser.parse_args()
run(args.host, args.port, args.image, args.model, args.signature_name)
我不太确定这是否是发出 tfserving grpc 客户端请求的最佳方式(因为客户端需要 tensorflow 库来准备张量) 但对我有用。
欢迎提出建议
我找不到合适的文档来成功地为 inception 或 mobilenet 模型提供服务并编写 grpc 客户端来连接到服务器并执行图像分类。
到目前为止,我只在 CPU 上成功配置了 tfserving 图像。无法在我的 GPU 上 运行 它。
但是,当我发出 grpc 客户端请求时,请求失败并出现错误。
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.INVALID_ARGUMENT
details = "Expects arg[0] to be float but string is provided"
debug_error_string = "{"created":"@1571717090.210000000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1017,"grpc_message":"Expects arg[0] to be float but string is provided","grpc_status":3}"
我知道请求格式存在一些问题,但我找不到可以准确指出正确方向的 grpc 客户端的适当文档。
这是我用于请求的 grpc 客户端。
from __future__ import print_function
import grpc
import tensorflow as tf
import time
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
tf.app.flags.DEFINE_string('server', 'localhost:8505',
'PredictionService host:port')
tf.app.flags.DEFINE_string('image', 'E:/Data/Docker/tf_serving/cat.jpg', 'path to image')
FLAGS = tf.app.flags.FLAGS
def main(_):
channel = grpc.insecure_channel(FLAGS.server)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
# Send request
with open(FLAGS.image, 'rb') as f:
# See prediction_service.proto for gRPC request/response details.
data = f.read()
request = predict_pb2.PredictRequest()
request.model_spec.name = 'inception'
request.model_spec.signature_name = ''
request.inputs['image'].CopyFrom(tf.contrib.util.make_tensor_proto(data, shape=[1]))
result = stub.Predict(request, 5.0) # 10 secs timeout
print(result)
print("Inception Client Passed")
if __name__ == '__main__':
tf.app.run()
据我了解,你的问题有两个问题。
A) 运行 GPU 上的 tfserving。
B) 发出成功的 grpc 客户端请求。
让我们一个一个开始。
运行 GPU 上的 tfserving
这是简单的两步过程。
正在从 official docker hub page 中提取最新图像。
docker pull tensorflow/serving:latest-gpu
请注意上面拉取请求中的标签 latest-gpu
,因为它会拉取用于 GPU 的图像。
运行 docker 容器。
sudo docker run -p 8502:8500 --mount type=bind,source=/my_model_dir,target=/models/inception --name tfserve_gpu -e MODEL_NAME=inception --gpus device=3 -t tensorflow/serving:latest-gpu
请注意,我已将参数 --gpus device=3
传递给 select 第三个 GPU 设备。将其相应地更改为 select 不同的 GPU 设备。
验证容器是否已通过 docker ps
命令启动。
此外,验证是否已通过 nvidia-smi
命令为 tfserving docker 分配了 gpu。
nvidia-smi 的输出
不过这里好像有点问题。 tfserving docker 已消耗所有 gpu 设备内存。
要限制 gpu 内存使用,请使用 per_process_gpu_memory_fraction
标志。
sudo docker run -p 8502:8500 --mount type=bind,source=/my_model_dir,target=/models/inception --name tfserve_gpu -e MODEL_NAME=inception --gpus device=3 -t tensorflow/serving:latest-gpu --per_process_gpu_memory_fraction=0.02
nvidia-smi 的输出
现在,我们已经成功地在 GPU 设备上配置了 tfserving docker,并且具有合理的 GPU 内存使用率。让我们跳到第二个问题。
发出 GRPC 客户端请求
您的 grpc 客户端请求的格式存在问题。 tfserving docker 图像不会直接以二进制格式获取图像,相反,您必须为该图像制作一个张量,然后将其传递给服务器。
这是发出 grpc 客户端请求的代码。
from __future__ import print_function
import argparse
import time
import numpy as np
from cv2 import imread
import grpc
from tensorflow.contrib.util import make_tensor_proto
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
import tensorflow as tf
def read_tensor_from_image_file(file_name,
input_height=299,
input_width=299,
input_mean=0,
input_std=255):
input_name = "file_reader"
output_name = "normalized"
file_reader = tf.io.read_file(file_name, input_name)
if file_name.endswith(".png"):
image_reader = tf.image.decode_png(
file_reader, channels=3, name="png_reader")
elif file_name.endswith(".gif"):
image_reader = tf.squeeze(
tf.image.decode_gif(file_reader, name="gif_reader"))
elif file_name.endswith(".bmp"):
image_reader = tf.image.decode_bmp(file_reader, name="bmp_reader")
else:
image_reader = tf.image.decode_jpeg(
file_reader, channels=3, name="jpeg_reader")
float_caster = tf.cast(image_reader, tf.float32)
dims_expander = tf.expand_dims(float_caster, 0)
resized = tf.compat.v1.image.resize_bilinear(dims_expander, [input_height, input_width])
normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
sess = tf.Session(config=tf.ConfigProto(gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.01)))
result = sess.run(normalized)
return result
def run(host, port, image, model, signature_name):
# Preparing tensor from the image
tensor = read_tensor_from_image_file(file_name='images/bird.jpg', input_height=224, input_width=224, input_mean=128, input_std=128)
# Preparing the channel
channel = grpc.insecure_channel('{host}:{port}'.format(host=host, port=port))
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
# Preparing grpc request
request = predict_pb2.PredictRequest()
request.model_spec.name = model
request.model_spec.signature_name = signature_name
request.inputs['image'].CopyFrom(make_tensor_proto(tensor, shape=[1, 224, 224, 3]))
# Making predict request
result = stub.Predict(request, 10.0)
# Analysing result to get the prediction output.
predictions = result.outputs['prediction'].float_val
print("Predictions : ", predictions)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--host', help='Tensorflow server host name', default='localhost', type=str)
parser.add_argument('--port', help='Tensorflow server port number', default=8502, type=int)
parser.add_argument('--image', help='input image', default='bird.jpg', type=str)
parser.add_argument('--model', help='model name', default='inception', type=str)
parser.add_argument('--signature_name', help='Signature name of saved TF model',
default='serving_default', type=str)
args = parser.parse_args()
run(args.host, args.port, args.image, args.model, args.signature_name)
我不太确定这是否是发出 tfserving grpc 客户端请求的最佳方式(因为客户端需要 tensorflow 库来准备张量) 但对我有用。
欢迎提出建议