tensorflow serving api
背景介绍
tensorflow serving 在客户端和服务端之间的通信采用的是RPC/REST协议。在TFS提供的REST协议接口存在一定的局限性,REST和RPC对比如下:
- 1、REST在实际应用中不能支持运行过程动态模型发布。
- 2、REST预测过程中组装报文格式复杂。
- 3、RPC接口提供TFS的所有核心能力。
基于以上原因且考虑我们主要使用java进行编程,因此我们必须具备能够编译TFS JAVA API的能力,这篇文章主要目的就是提供编译TFS JAVA API的方法。
编译方法
step_1 安装protoc
protoc 3 已经有编译好的版本, 直接从protoc官网 下载编译好的安装包 protoc-3.6.1-osx-x86_64.zip
, 然后将命令复制到 /usr/local/bin
即可。
cd /tmp
mv protoc-3.5.1-osx-x86_64.zip .
unzip protoc-3.5.1-osx-x86_64.zip
cd bin
cp protoc /usr/local/bin/
lebron374$ protoc --version
libprotoc 3.6.1
step_2 maven构建工程
参考TFS API编译文章,核心操作的主要步骤都在文章里面写的明白。核心步骤主要是:
- 1、下载TF和TFS的代码,切换相同版本的分支保证TFS和TF的代码兼容,参考tensorflow-serving-api。
- 2、拷贝TF和TFS的proto文件到指定目录,参考tensorflow-serving-api initialize.sh文件
- 3、修改pom.xml依赖,参考tensorflow-serving-api,实际视具体依赖添加mvn依赖。
核心过程注解
拷贝proto文件
#!/bin/sh
SUBMODULE_PATH_TENSOR_FLOW="src/external/tensorflow"
SUBMODULE_PATH_TENSOR_SERV="src/external/tensorflow-serving"
DEST_SRC_PATH="src/main/proto"
function copy_proto_files()
{
dest_path=$1
src_path=$2
cd ${src_path}
proto_files=`find . | grep '\.proto$' | grep -v 'host'`
cd -
for file in ${proto_files}
do
echo ${file}
sub_file_path=`echo ${file} | awk 'BEGIN{FS=OFS="/";}{seg=$2; for(i=3; i<NF; ++i){seg=seg"/"$i;}}END{print seg;}'`
sub_file_name=`echo ${file} | awk 'BEGIN{FS=OFS="/";}{print $NF;}'`
src_file_name=${src_path}/${sub_file_path}/${sub_file_name}
dest_file_path=${dest_path}/${sub_file_path}
if [ ! -f ${dest_file_path} ]
then
mkdir -p ${dest_file_path}
fi
cp ${src_file_name} ${dest_file_path}
done
}
copy_proto_files ${DEST_SRC_PATH} ${SUBMODULE_PATH_TENSOR_FLOW}
copy_proto_files ${DEST_SRC_PATH} ${SUBMODULE_PATH_TENSOR_SERV}
说明:
- proto_files=
find . | grep '\.proto$' | grep -v 'host'
负责拷贝proto文件,实际过程中因为编译冲突动态排除几个冲突的proto文件。
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<tensor.jar.version>1.8.0-SNAPSHOT</tensor.jar.version>
<tensor.version>1.8.0</tensor.version>
<grpc.version>1.12.0</grpc.version>
<protobuf.version>3.5.1</protobuf.version>
<protobuf.plugin.version>0.5.1</protobuf.plugin.version>
</properties>
<groupId>tensorflow.serving</groupId>
<artifactId>tensorflow-serving-api</artifactId>
<version>${tensor.jar.version}</version>
<packaging>jar</packaging>
<distributionManagement>
<repository>
<id>nexus</id>
<name>xxx nexus</name>
<url>http://maven.repos.xxx.com/nexus/content/repositories/snapshots/</url>
</repository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>proto</artifactId>
<version>${tensor.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.0</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf.plugin.version}</version>
<configuration>
<protocArtifact>
com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
参考文章

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
tensorflow serving java案例
背景介绍 这篇文章是tensorflow serving java api使用的参考案例,基本上把TFS的核心API的用法都介绍清楚。案例主要分为三部分: 动态更新模型:用于在TFS处于runtime时候动态加载模型。 获取模型状态:用于获取加载的模型的基本信息。 在线模型预测:进行在线预测,分类等操作,着重介绍在线预测。 因为模型的预测需要参考模型内部变量,所以可以先行通过TFS的REST接口获取TF模型的元数据然后才能构建TFS的RPC请求对象。 TFS 使用入门 模型源数据获取 curl http://host:port/v1/models/${MODEL_NAME}[/versions/${MODEL_VERSION}]/metadata 说明: 参考TFS REST API 返回结果参考TF模型结构。 public static void getModelStatus() { // 1、设置访问的RPC协议的host和port ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).use...
-
下一篇
Java线程池,你了解多少?
Java线程池,你了解多少? 阅读目录 一、前言 二、那么线程池有哪些作用呢? 三、线程池中核心类:ThreadPoolExecutor 四、关于线程池使用的注意事项 五、总结&推荐学习 六、参考资料 回到顶部 一、前言 随着业务的发展,单线程已经远远不能满足,随即就有多线程的出现。多线程虽然能解决单线程解决不了的事情,但是它也会给你带来额外的问题。比如成千上万甚至上百万的线程时候,你系统就会出现响应延迟、卡机、甚至直接卡死的情况。为什么会出现这样的原因呢?因为为每个请求创建一个新线程的开销很大:在创建和销毁线程上花费的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多。 除了创建和销毁线程的开销之外,活动的线程也消耗系统资源。在一个 JVM里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”。所以为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时刻处理的请求数目。而线程池为线程生命周期开销问题和资源不足问题提供了解决方案。 回到顶部 二、那么线程池有哪些作用呢? 1、降低资源消耗,防止资源不足。合理配置线程池中的线程大小,防止请求线程猛...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7,8上快速安装Gitea,搭建Git服务器
- MySQL8.0.19开启GTID主从同步CentOS8