"Введение"TensorFlow Serving предоставляет интерфейс GRPC для эффективного выполнения запросов прогнозирования к модели, но он предоставляет только API на основе Python. Если мы хотим использовать другие языки для доступа к GRPC, нам нужно вручную сгенерировать соответствующий файл интерфейса GRPC. В этой статье в основном представлены метод и метод использования инструмента protoc для создания файла API обслуживания TensorFlow, а также приведен полный пример проекта для справки.
Компиляция файла ProtoBuf
TensorFlow Serving
основан наProtocol Buffer
согласие на выполнениеGPRC
общение, исходный код которого начинается сproto
Ряд структур данных определен для файлов с суффиксами (message
) а такжеRPC
Служить (service
), которые используются для представления формата обмена данными и интерфейса для выполнения удаленных операций соответственно.proto
Сами файлы нельзя использовать непосредственно в коде, их необходимо дополнительно преобразовать в файлы кода, зависящие от языка, для нормальной компиляции и запуска.
Protocol Buffer
официально предоставленProtocol Buffer Compiler
(protoc
) скомпилировать инструменты дляproto
файл для компиляции и создания файлов кода, зависящих от языка, инструмент в настоящее время поддерживает работу по генерации кода на нескольких языках, включаяgolang
,java
,c++
а такжеc#
Ждать. использоватьprotoc
Инструменты могут значительно сократить наши усилия по кодированию, позволяя нам больше сосредоточиться на конкретных бизнес-реализациях без хлопот, связанных с определением различных структур данных, зависящих от языка.
Поэтому при использовании других языков сTensorFlow Serving
провестиGRPC
При общении мы должны полагаться наprotoc
инструменты для создания зависимых от языкаAPI
файл для последующего использования. Следует отметить, что из-заTensorFlow Serving
часть исходного кодаproto
файл должен зависеть отTensorFlow
серединаproto
файл, поэтому нам нужно использовать исходный код обоих для создания необходимогоAPI
документ.
Ниже краткое введениеprotoc
инструменты вLinux
Процесс установки под систему:
-
первый в
Protocol Buffer
изGithub
Загрузите последнюю версию страницы выпуска программного обеспеченияprotoc
Двоичный сжатый файл пакета или используйте следующую команду для прямой загрузки.wget https://github.com/protocolbuffers/protobuf/releases/download/v3.12.3/protoc-3.12.3-linux-x86_64.zip
-
Затем распакуйте архив в
/usr/local/protoc
Под содержанием.unzip protoc-3.12.3-linux-x86_64.zip -d /usr/local/protoc
-
Тогда будет
/usr/local/protoc/bin
каталог добавлен вPATH
в переменных окружения. Вы можете добавить следующую строку в/etc/profile
документ для достижения вышеуказанных целей.export PATH=$PATH:/usr/local/protoc/bin
-
Окончательная тестовая установка прошла успешно
protoc --version
Генерация и использование файла API
Вообще говоря, покаProtocol Buffer
иGRPC
Поддерживаемые языки могут быть сгенерированыTensorFlow Serving
изAPI
документ. в предыдущей статьеTensorFlow 2.x 模型 Serving 服务中
Я уже представил использованиеPython
выполнятьGPRC
Пример запроса, эта статья в основном знакомит с использованиемGolang
а такжеJava
генерироватьTensorFlow Serving
изAPI
файл и провестиGPRC
способ запроса.
Чтобы сгенерировать исполняемый файл кода, нам сначала нужноTensorFlow
иTensorFlow Serving
исходный кодclone
к местному.
mkdir tensorflow-serving-api && cd tensorflow-serving-api
git clone https://github.com/tensorflow/tensorflow.git
git clone https://github.com/tensorflow/serving.git
Затем вы можете использовать исходный кодproto
файл для создания соответствующего языкаTensorFlow Serving API
файл.
Golang
в созданииgolang
СвязанныйAPI
файл кода, нам нужно установитьgolang
окружающая среда и некоторыеprotoc
Плагины, помогающие нам в операциях по созданию файлов. Следующие связанные операцииLinux
Система завершена.
-
Установить
golang
, процесс выглядит следующим образом.wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz tar zxvf go1.14.4.linux-amd64.tar.gz -C /usr/local export PATH=$PATH:/usr/local/go/bin go version
-
Установить
protoc-gen-go
плагин для генерацииgo
документ.go get -u google.golang.org/protobuf/cmd/protoc-gen-go # or go get -u github.com/golang/protobuf/protoc-gen-go
protoc-gen-go
По умолчанию он будет установлен в$GOPATH/bin
каталог, вам нужно убедиться, что каталог находится вPATH
ниже, чтобыprotoc
Инструмент может найти плагин. -
Установить
grpc
плагин для генерацииgrpc go
документ.go get -u google.golang.org/grpc
-
Переключите исходный код на указанную ветку или тег.
cd tensorflow-serving-api/tensorflow git checkout tags/v2.2.0 cd tensorflow-serving-api/serving git checkout tags/2.2.0
-
использовать
protoc
создание инструментаgo
документ.cd tensorflow-serving-api protoc -I=serving -I=tensorflow --go_out=plugins=grpc:golang serving/tensorflow_serving/*/*.proto protoc -I=serving -I=tensorflow --go_out=plugins=grpc:golang serving/tensorflow_serving/sources/storage_path/*.proto protoc -I=serving -I=tensorflow --go_out=plugins=grpc:golang tensorflow/tensorflow/core/framework/*.proto protoc -I=serving -I=tensorflow --go_out=plugins=grpc:golang tensorflow/tensorflow/core/example/*.proto protoc -I=serving -I=tensorflow --go_out=plugins=grpc:golang tensorflow/tensorflow/core/protobuf/*.proto protoc -I=serving -I=tensorflow --go_out=plugins=grpc:golang tensorflow/tensorflow/stream_executor/*.proto
в
-I
указанныйproto
Путь к файлу для поиска зависимых файлов, который можно указать несколько раз.--go_out
сохранение указаноgo
каталог файла (здесьgolang
) и используемыйgrpc
плагин. Последний элемент команды указан как подстановочный знакproto
Входное местоположение файла.Что касается того, почему выберите выше
proto
файл дляAPI
создано, основано на фактическом использовании иproto
Зависимости между файлами определяются. можно начать сserving
изproto
Начните с исходного кода и обратитесь к егоPython GRPC
Реализация кода примера, найти записьproto
файл, то по себе и своим зависимостямproto
файл для создания соответствующегоAPI
кодовые файлы, а затем выполнять тесты кодирования для проверки недостатков и заполнения упущений до тех пор, пока все кодовые файлы не будут скомпилированы без ошибок. -
После выполнения вышеуказанной команды
golang
Под каталогом создаются два каталога, а именноgithub.com
иtensorflow_serving
, первый содержит отtensorflow
в исходном кодеproto
файл созданgo
файл, последний содержит изserving
в исходном кодеproto
файл созданgo
документ. так какtensorflow
в исходном кодеproto
файлы содержатgo_package
варианты, такие какoption go_package = "github.com/tensorflow/tensorflow/tensorflow/go/core/framework/tensor_go_proto";
, которые определяют сгенерированныйgo
выходной каталог файла, поэтому он сгенерированgo
файл будет вgithub.com
каталог иserving
в исходном кодеproto
файл не содержит этой опции, поэтомуgo
Выходной каталог файла по умолчанию находится в том же каталоге, что и исходный файл. -
tensorflow_serving
создается в каталогеgo
Ошибки циклических ссылок могут возникать в файлах следующим образом:import cycle not allowed package github.com/alex/tensorflow-serving-api-go imports tensorflow_serving/apis imports tensorflow_serving/core imports tensorflow_serving/apis
В этот момент вам нужно
tensorflow_serving/core
Под содержаниемlogging.pb.go
документы иtensorflow_serving/apis
в каталогеprediction_log.pb.go
удаление файла для решения вышеуказанной проблемы. Удаление вышеуказанных файлов кода не влияет на последующиеGRPC
Запрос предсказания модели. -
Предположим, у меня есть файл с именем
first_model
Модель развернута вTensorFlow Serving
Информация о метаданных службы выглядит следующим образом:$ curl http://localhost:8501/v1/models/first_model/versions/0/metadata { "model_spec": { "name": "first_model", "signature_name": "", "version": "0" }, "metadata": { "signature_def": { "signature_def": { "serving_default": { "inputs": { "input_1": { "dtype": "DT_INT64", "tensor_shape": { "dim": [ { "size": "-1", "name": "" }, { "size": "31", "name": "" } ], "unknown_rank": false }, "name": "serving_default_input_1:0" } }, "outputs": { "output_1": { "dtype": "DT_FLOAT", "tensor_shape": { "dim": [ { "size": "-1", "name": "" }, { "size": "1", "name": "" } ], "unknown_rank": false }, "name": "StatefulPartitionedCall:0" } }, "method_name": "tensorflow/serving/predict" }, "__saved_model_init_op": { "inputs": {}, "outputs": { "__saved_model_init_op": { "dtype": "DT_INVALID", "tensor_shape": { "dim": [], "unknown_rank": true }, "name": "NoOp" } }, "method_name": "" } } } } }
Нам нужно сосредоточиться на приведенной выше информации.
inputs
параметры, которые определяют входные данные для этой моделиkey
значение (здесьinput_1
) , размерность входных данных (здесь(-1, 31)
) и тип входных данных (здесьDT_INT64
). в ходе выполненияGRPC
При прогнозировании запроса входные данные, указанные в коде, должны совпадать с различной входной информацией, определенной в метаданных, иначе не удастся получить правильный вывод модели. -
Создайте
go
проект кfirst_model
ОтправитьGRPC
Прогноз запросов. Для получения подробной информации о конкретных проектах см.Github
Реализация и описание выше, здесь указан только код основной функции, а именно:package main import ( "context" "log" apis "tensorflow_serving/apis" "time" "github.com/golang/protobuf/ptypes/wrappers" "github.com/tensorflow/tensorflow/tensorflow/go/core/framework/tensor_go_proto" "github.com/tensorflow/tensorflow/tensorflow/go/core/framework/tensor_shape_go_proto" "github.com/tensorflow/tensorflow/tensorflow/go/core/framework/types_go_proto" "google.golang.org/grpc" ) var ( // TensorFlow serving grpc address. address = "127.0.0.1:8500" ) func main() { // Create a grpc request. request := &apis.PredictRequest{ ModelSpec: &apis.ModelSpec{}, Inputs: make(map[string]*tensor_go_proto.TensorProto), } request.ModelSpec.Name = "first_model" request.ModelSpec.SignatureName = "serving_default" // request.ModelSpec.VersionChoice = &apis.ModelSpec_VersionLabel{VersionLabel: "stable"} request.ModelSpec.VersionChoice = &apis.ModelSpec_Version{Version: &wrappers.Int64Value{Value: 0}} request.Inputs["input_1"] = &tensor_go_proto.TensorProto{ Dtype: types_go_proto.DataType_DT_INT64, TensorShape: &tensor_shape_go_proto.TensorShapeProto{ Dim: []*tensor_shape_go_proto.TensorShapeProto_Dim{ &tensor_shape_go_proto.TensorShapeProto_Dim{ Size: int64(2), }, &tensor_shape_go_proto.TensorShapeProto_Dim{ Size: int64(31), }, }, }, Int64Val: []int64{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, } // Create a grpc connection. conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(10*time.Second)) if err != nil { log.Fatalf("couldn't connect: %s", err.Error()) } defer conn.Close() // Wrap the grpc uri with client. client := apis.NewPredictionServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() // Send the grpc request. response, err := client.Predict(ctx, request) if err != nil { log.Fatalf("couldn't get response: %v", err) } log.Printf("%+v", response) }
-
Github
Адрес:https://github.com/AlexanderJLiu/tensorflow-serving-api/tree/master/golang
Java
в созданииjava
СвязанныйAPI
файл кода, нам нужно установитьjava
окружающая среда и некоторыеprotoc
Плагины, помогающие нам в операциях по созданию файлов. Следующие связанные операцииLinux
Система завершена.
-
Установить
OpenJDK
.# centos yum-config-manager --enable rhel-7-server-optional-rpms yum install java-11-openjdk-devel # ubuntu apt-get install openjdk-11-jdk # test java -version
-
Установить
protoc-gen-grpc-java
, генерироватьgrpc java
документ.wget https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.30.2/protoc-gen-grpc-java-1.30.2-linux-x86_64.exe mv protoc-gen-grpc-java-1.30.2-linux-x86_64.exe /usr/local/protoc/bin/protoc-gen-grpc-java
-
Переключите исходный код на указанную ветку или тег.
cd tensorflow-serving-api/tensorflow git checkout tags/v2.2.0 cd tensorflow-serving-api/serving git checkout tags/2.2.0
-
использовать
protoc
создание инструментаjava
документ.cd tensorflow-serving-api protoc -I=serving -I=tensorflow --plugin=/usr/local/protoc/bin/protoc-gen-grpc-java --grpc-java_out=java --java_out=java serving/tensorflow_serving/*/*.proto protoc -I=serving -I=tensorflow --plugin=/usr/local/protoc/bin/protoc-gen-grpc-java --grpc-java_out=java --java_out=java serving/tensorflow_serving/sources/storage_path/*.proto
в
-I
указанныйproto
Путь к файлу для поиска зависимых файлов, который можно указать несколько раз.--plugin
указано для использованияgrpc
Путь к плагину.--grpc-java_out
указанныйgrpc java
Каталог, в котором сохранен файл.--java_out
указанныйjava
Каталог, в котором сохранен файл. Последний элемент команды указан как подстановочный знакproto
Входное местоположение файла.так как
TensorFlow
Официально на основеproto
файл созданTensorFlow
изjava
файл, поэтому нам не нужно генерировать его самостоятельно и использовать непосредственно изmaven
Склад может быть импортирован:implementation("org.tensorflow:proto:1.15.0")
. -
Создайте
java
проект кfirst_model
ОтправитьGRPC
Прогноз запросов. Для получения подробной информации о конкретных проектах см.Github
Реализация и описание выше, здесь указан только код основной функции, а именно:package com.github.alex; import java.util.Arrays; import java.util.concurrent.TimeUnit; import com.google.protobuf.Int64Value; import org.tensorflow.framework.DataType; import org.tensorflow.framework.TensorProto; import org.tensorflow.framework.TensorShapeProto; import org.tensorflow.framework.TensorShapeProto.Dim; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.stub.StreamObserver; import tensorflow.serving.Model.ModelSpec; import tensorflow.serving.Predict.PredictRequest; import tensorflow.serving.Predict.PredictResponse; import tensorflow.serving.PredictionServiceGrpc; import tensorflow.serving.PredictionServiceGrpc.PredictionServiceBlockingStub; import tensorflow.serving.PredictionServiceGrpc.PredictionServiceStub; public class App { public String getGreeting() { return "Hello world."; } public static void main(String[] args) { PredictRequest.Builder requestBuilder = PredictRequest.newBuilder(); ModelSpec.Builder modelSpecBuilder = ModelSpec.newBuilder(); modelSpecBuilder.setSignatureName("serving_default"); modelSpecBuilder.setName("first_model"); modelSpecBuilder.setVersion(Int64Value.newBuilder().setValue(0L)); requestBuilder.setModelSpec(modelSpecBuilder.build()); TensorProto.Builder tensorProtoBuilder = TensorProto.newBuilder(); tensorProtoBuilder.setDtype(DataType.DT_INT64); Dim[] dim = {Dim.newBuilder().setSize(1).build(), Dim.newBuilder().setSize(31).build()}; tensorProtoBuilder .setTensorShape(TensorShapeProto.newBuilder().addAllDim(Arrays.asList(dim))); // tensorProtoBuilder.setTensorShape(TensorShapeProto.newBuilder() // .addDim(Dim.newBuilder().setSize(1)).addDim(Dim.newBuilder().setSize(31))); Long[] inputs = {1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L}; tensorProtoBuilder.addAllInt64Val(Arrays.asList(inputs)); requestBuilder.putInputs("input_1", tensorProtoBuilder.build()); PredictRequest request = requestBuilder.build(); System.out.println(request); String target = "127.0.0.1:8500"; // Create a communication channel to the server, known as a Channel. Channels are // thread-safe and reusable. It is common to create channels at the beginning of your // application and reuse them until the application shuts down. ManagedChannel channel = ManagedChannelBuilder.forTarget(target) // Channels are secure by default (via SSL/TLS). For the example we disable TLS to // avoid needing certificates. .usePlaintext().build(); PredictionServiceBlockingStub stub = PredictionServiceGrpc.newBlockingStub(channel); try { PredictResponse response = stub.predict(request); System.out.println(response); channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } }
-
Github
Адрес:https://github.com/AlexanderJLiu/tensorflow-serving-api/tree/master/java
Другие языки
я здесьGithub
создалtensorflow-serving-api
проект, который предназначен для созданияProtocol Buffer
иGRPC
всех поддерживаемых языковTensorFlow Serving API
файл, а пример использования приведен в виде готового проекта.
Проект постепенно совершенствуется и был реализованGolang
,Java
а такжеPython
лингвистическийTensorFlow Serving API
И примеры проектов, в будущем будет добавлено больше языковых реализаций, и каждый может принять участие и внести свой вклад.
Адрес ссылки на проект:https://github.com/AlexanderJLiu/tensorflow-serving-api