TensorFlow 篇 | TensorFlow Serving API

「导语」TensorFlow Serving 提供了 GRPC 接口来高效地完成对模型的预测请求,但是它本身只提供了基于 Python 的 API ,如果我们要使用其它语言进行 GRPC 访问,则需手动生成相应的 GRPC 接口文件方可。本文主要介绍使用 protoc 工具生成 TensorFlow Serving API 文件的方式与方法,并且提供完整的项目示例以供参考。
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二进制压缩包文件,或者使用如下命令直接下载。
然后将该压缩包解压到
/usr/local/protoc目录下。
接着将
/usr/local/protoc/bin目录加入到PATH环境变量中。可以将下面这行语句加入到/etc/profile文件中来达成上述目标。
最后测试安装成功
API 文件生成及使用
一般而言,只要是 Protocol Buffer 和 GRPC 支持的语言,都可以生成 TensorFlow Serving 的 API 文件。在上一篇文章TensorFlow 2.x 模型 Serving 服务中我已经介绍过使用 Python 来进行 GPRC 请求的示例,本文则主要介绍使用 Golang 以及 Java 来生成 TensorFlow Serving 的 API 文件以及进行 GPRC 请求的方法。
为了生成可执行的代码文件,我们首先需要将 TensorFlow 和 TensorFlow Serving 的源码都 clone 到本地。
接下来就可以使用源码中的 proto 文件来生成相应语言的 TensorFlow Serving API 文件了。
Golang
在生成 golang 相关的 API 代码文件时,我们需要安装 golang 环境以及一些 protoc 插件来辅助我们进行文件生成操作。以下的相关操作均在 Linux 系统完成。
安装
golang,流程如下所示。
安装
protoc-gen-go插件,用于生成go文件。
protoc-gen-go 默认会安装在 $GOPATH/bin 目录下,需要确保该目录在 PATH 下以使得 protoc 工具能够找到该插件。
安装
grpc插件,用于生成grpc go文件。
将源码切换到指定分支或标签。
使用
protoc工具生成go文件。
其中 -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文件中可能会出现循环引用错误,如下所示:
此时你需要将 tensorflow_serving/core 目录下 logging.pb.go 文件和 tensorflow_serving/apis 目录下的 prediction_log.pb.go 文件删除以解决上述问题。删除上述代码文件并不影响后续的 GRPC 模型预测请求。
假设我有一个名为
first_model的模型部署在了TensorFlow Serving服务上,它的元数据信息如下所示:
我们需要重点关注上述信息中的 inputs 选项,它定义了该模型输入数据的 key 值(这里为 input_1) 、输入数据的维度(这里为 (-1, 31))以及输入数据的类型 (这里为 DT_INT64 )。在进行 GRPC 预测请求时,代码中指定的输入数据需要与元数据中定义的各种输入信息相匹配,否则就无法获取正确的模型输出。
创建
go项目并向first_model发送GRPC预测请求。具体的项目详情请参见Github上的实现及说明,这里只列出主函数的代码,如下所示:
Github地址为:https://github.com/AlexanderJLiu/tensorflow-serving-api/tree/master/golang
Java
在生成 java 相关的 API 代码文件时,我们需要安装 java 环境以及一些 protoc 插件来辅助我们进行文件生成操作。以下相关操作均在 Linux 系统完成。
安装
OpenJDK。
安装
protoc-gen-grpc-java,用于生成grpc java文件。
将源码切换到指定分支或标签。
使用
protoc工具生成java文件。
其中 -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上的实现及说明,这里只列出主函数的代码,如下所示:
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
参考资料
版权声明: 本文为 InfoQ 作者【Alex】的原创文章。
原文链接:【http://xie.infoq.cn/article/2b89ef611031a8c6ef93a517d】。文章转载请联系作者。
评论