Предположим, у вас есть собственный оценщик, обученный и готовый служить, как тот, который указан в вашем вопросе.Процедура сохранения и обслуживания обученной модели оценщика:
- Экспорт оценщика в формат SavedModel.
- Служение SavedModel с помощью TensorFlow ModelServer.
- Feedвходные данные для обслуживаемой модели и наблюдение результатов прогнозирования.
В некоторых случаях ваша обученная модель оценки может быть лучше развернута и повторно использована без ее обслуживания.Иногда лучше заморозить модель и развернуть ее непосредственно внутри программы.Или иногда вы хотите конвертировать модель в javascript или облегченную версию TensorFlow.Есть много способов повторно использовать обученный оценщик, не обслуживая его.Но поскольку в вашем вопросе конкретно говорится об обслуживании, этот ответ о конкретном обслуживании со стандартным ModelServer.
1.Экспорт в формат SavedModel
Из документов :
Чтобы подготовить обученного оценщика к обслуживанию, вы должны экспортировать его в стандартном формате SavedModel.
Для этого мы можем использовать функцию export_saved_model
, и для этого необходимо сначала определить функцию приемника обслуживающего входа.Функция приемника обслуживающего входа определяет и присваивает имена всем тензорам, которые становятся входными данными для модели во время обслуживания.
Существует два вида функций приемника обслуживающего входа, и каждый тип сообщает TensorFlow, как следует ожидать ввода на шаге 3:
Анализ функций приемника обслуживающего входа : Входы предоставляются в виде сериализованных Example
protobufs.Этот тип говорит TensorFlow ожидать, что вход модели будет поступать от строкового тензора, который будет проанализирован в элементах.Этот приемник может быть построен с использованием tf.estimator.export.build_parsing_serving_input_receiver_fn
.
Функции приемника необработанных входных сигналов : входы предоставляются непосредственно как Tensor
protobufs.Этот приемник может быть построен с использованием tf.estimator.export.build_raw_serving_input_receiver_fn
.
Ваш код colab создает две функции приемника, которые выполняют одно и то же:
serving_fn = tf.estimator.export.build_raw_serving_input_receiver_fn(
{'input_tensors': tf.placeholder(tf.float32, I_SHAPE(None), name="input_tensors")})
и:
def serving_input_receiver_fn():
input_tensors = tf.placeholder(tf.float32, I_SHAPE(None), name="input_tensors")
features = {'input_tensors' : input_tensors}
receiver_tensors = {'input_tensors': input_tensors}
return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)
Но экспорт выполняется только одним:
est.export_savedmodel('./here', serving_input_receiver_fn)
Вы можете удалить свой метод serving_input_receiver_fn
и использовать первое определение:
est.export_savedmodel('./here', serving_fn)
и
exporter = tf.estimator.BestExporter(
name="best_exporter",
serving_input_receiver_fn=serving_fn,
exports_to_keep=5
)
2.Служите SavedModel
В вашем вопросе говорилось, что вы предпочитаете обслуживать свою модель без использования докера.Согласно его Dockerfile , образ docker просто запускает двоичный файл TensorFlow ModelServer , который вы можете установить или собрать из источника вне контейнера, как описано в его README, или вы можете скопировать егоиз контейнера tensorflow/serving
.
Как только вы установили двоичный файл, запустите его, чтобы запустить сервер gRPC, прослушивающий порт, который вы хотите, например, 8500:
tensorflow_model_server --port=8500 --model_name=my_model --model_base_path=/path/to/export/dir
Теперь вы«обслуживаем» модель.Если вы хотите только запустить модель, не требуя ничего от репозитория tenorflow_serving, вы можете вместо этого использовать интерфейс командной строки сохраненной модели *1081* для запуска SavedModel без сервера модели.Он должен быть уже установлен вместе с TensorFlow, если вы установили из готового двоичного файла.
3.Запрос работающего сервера модели
Стандартный способ запроса модели - это служба gRPC, предоставляемая ModelServer.gRPC - это платформа RPC , которая использует формат буфера протокола Google для определения сервисов и связи между хостами.Он разработан, чтобы быть быстрым, кроссплатформенным и масштабируемым.Это особенно удобно, когда все ваши данные уже обработаны в формате protobuf, например, при работе с файлами TFRecord.
Существуют библиотеки gRPC для многих разных языков, и вы даже можете общаться с вашим сервером, например, cURL, нопоскольку ваш вопрос помечен для Python, я буду использовать пакеты Python grpcio и tenorflow-Обслуживание-api для выполнения вызовов gRPC, необходимых для прогнозирования с помощью обслуживаемой модели.
После запуска сервера и установки пакетов Python вы можете проверить соединение, запросив метаданные def сигнатуры модели:
from __future__ import print_function
import grpc
from tensorflow_serving.apis import get_model_metadata_pb2
from tensorflow_serving.apis import model_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
with grpc.insecure_channel("localhost:8500") as channel:
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
request = get_model_metadata_pb2.GetModelMetadataRequest(
model_spec=model_pb2.ModelSpec(name="my_model"),
metadata_field=["signature_def"])
response = stub.GetModelMetadata(request)
sigdef_str = response.metadata["signature_def"].value
print ("Name:", response.model_spec.name)
print ("Version:", response.model_spec.version.value)
print (get_model_metadata_pb2.SignatureDefMap.FromString(sigdef_str))
С моделью из вашего колаба вы увидите
Name: my_model
Version: ...
signature_def {
key: "labels"
value {
inputs {
key: "input_tensors"
value {
name: "input_tensors:0"
dtype: DT_FLOAT
tensor_shape {
dim {
size: -1
}
dim {
size: 20
}
dim {
size: 7
}
}
}
}
outputs {
key: "output"
value {
name: "Sigmoid:0"
dtype: DT_FLOAT
tensor_shape {
dim {
size: -1
}
dim {
size: 20
}
dim {
size: 4
}
}
}
}
method_name: "tensorflow/serving/predict"
}
}
signature_def {
key: "serving_default"
value {
inputs {
key: "input_tensors"
value {
name: "input_tensors:0"
dtype: DT_FLOAT
tensor_shape {
dim {
size: -1
}
dim {
size: 20
}
dim {
size: 7
}
}
}
}
outputs {
key: "output"
value {
name: "Sigmoid:0"
dtype: DT_FLOAT
tensor_shape {
dim {
size: -1
}
dim {
size: 20
}
dim {
size: 4
}
}
}
}
method_name: "tensorflow/serving/predict"
}
}
Таким образом, согласно определению сигнатуры, модель ожидает словарь, сопоставляющий ключ input_tensors
с протоколом Tensor типа и формы с плавающей точкой [-1, 20, 7]
, и выводит словарь, сопоставляющий ключ output
с протоколом Tensor с плавающей точкой. тип и форма точки [-1, 20, 4]
. Мы можем создать прототип Tensor в Python из массива numpy, используя tf.make_tensor_proto
и преобразовать обратно, используя tf.make_ndarray
:
from __future__ import print_function
import grpc
import numpy as np
import tensorflow as tf
from tensorflow_serving.apis import model_pb2
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
# Dummy input data for batch size 3.
batch_input = np.ones((3, 20, 7), dtype="float32")
with grpc.insecure_channel("localhost:8500") as channel:
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
request = predict_pb2.PredictRequest(
model_spec=model_pb2.ModelSpec(name="my_model"),
inputs={"input_tensors": tf.make_tensor_proto(batch_input)})
response = stub.Predict(request)
batch_output = tf.make_ndarray(response.outputs["output"])
print (batch_output.shape)
Действительно, у вас должен быть массив формы с плавающей точкой (3, 20, 4)
, возвращаемый вашей службой оценочной модели.
Для получения дополнительной информации о том, как службы gRPC определены и используются в Python, см. Учебное пособие на веб-сайте gRPC . Подробные сведения об API * 1120 см. В определениях протокола .proto
.
.