【ML&DEV】
这是大家没有看过的船新栏目!ML表示机器学习,DEV表示开发,本专栏旨在为大家分享作为算法工程师的工作,机器学习生态下的有关模型方法和技术,从数据生产到模型部署维护监控全流程,预备知识、理论、技术、经验等都会涉及,近期内容以入门线路为主,敬请期待!
往期回顾:
ML&DEV[4] | 机器学习进阶线路
ML&DEV[5] | 系统理解特征工程
ML&DEV[6] | 算法工程师 Linux必知必会
ML&DEV[7] | 浅谈算法工程师的工程能力
ML&DEV[8] | 算法在岗一年的经验总结
假期肯定要拿点东西来学的,由于空白时间大大增加,所以适合拿来攻坚,最近开始学起了比较复杂的gRPC框架,很多人可能对这个比较陌生,我先来个引子,tensorflow的在线服务tensor serving底层,就是通过gRPC框架实现的,来看看证据:
首先可以训练一个tensorflow模型并且保存,然后通过ModelServer的模型进行部署,这里就是使用的c++环境。
今天终于把他的hello world给跑通了(虽然这个远远不够),那我就来给大家总结一波。
官方一句话解释:
A high-performance, open-source universal RPC framework.
看到这句话,说白了就是RPC框架的一种升级版,那么RPC是什么呢。来看一张图:
这里分为两种结构,一个是server,一个是client,(简单地说就是一个server/client模型,即CS结构)前者可以理解为一个服务,当然的也可以理解为一个函数,后者则是一个客户端,也可以理解为一个对函数的应用。启动一个服务,可以有很多客户端去调用,建立一个函数,可以有很多的别的项目可以调用,而且这两个东西互相独立,可以互不干扰,无论是应用上还是开发上,例如一个算法我要做更新,只需要在服务端更新,客户端无需感知。
这里面涉及有关服务端和客户端的概念,大家可以自行补充哈。
他的常用场景如下:
低延迟、高拓展性、分布式系统。
同云服务器进行通信的移动应用客户端。
设计语言独立、高效、精确。
便于各方面扩展的分层设计,如认证、负载均衡、日志记录、监控等。
一种部署模型的方案就是通过单独设立模型服务,需要该模型的其他服务调用该模型的时候可以向这个模型进行请求,这样可以保证模型和具体业务独立,在进行相关迭代的时候不需要单独上线(除非更新接口,获取新特征),这种场景是将本来一个服务拆成了两个,而服务之间需要通信,为了不降低性能,服务的请求时间必须大量缩短,gRPC框架就非常适合,在工业应用上请求时长可以控制在5ms一下甚至更低。
既然他这么厉害,事不宜迟,搞起来!
gRPC涉及的环境会相对复杂,我一一和大家说一下。
首先说一下我现在的环境吧:
操作系统:macOS,另外安装macOS专属包管理器,homebrew
c++环境:gcc-5.5.0。
用homebrew比较简单。当然linux有apt-get之类的。
$ brew install protobuf
查看自己的安装目录。
$ which protobuf
/usr/local/bin/protoc
配置环境变量,在 ~/.bash_profile
中添加变量 exportPROTOC="/usr/local/bin/protoc"
然后执行如下。
source ~/.bach_profile
然后来看是否安装成功:
$ protoc --version
libprotoc 3.7.0
如果有,说明protobuf安装成功。
protobuf是一个比较特殊的包,其他的都可以快速安装了。
brew install autoconf automake libtool shtool
brew install gflags
安装成功后,基本环境就已经配置好了。
首先当然是拉项目下来,当然的还有一些必要的依赖:
git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
cd grpc
git submodule update --init
然后就是构建了,这个是c++目前比较流行的构建方法,make系列(我这里踩了个坑,需要保证protobuf版本一致,一般你直接整最新的即可)。
# cd ./example/cpp/helloworld
make
# make -j8 可多个编译命令并行,提升速度。
成功构建后,你会多几个二进制文件,其中一个是server,另一个是client,greeterserver用于启动服务,greeterclient是客户端,用来发请求。
nohup ./greeter_server &
启动服务一般用nohup与&组合放在后台,你把它停了,服务就停了。然后发出请求。
./greeter_client
# 期望返回是:Greeter received: Hello world
如果能有期望返回,说明成功啦。
最终,还需要把服务停下来,首先是看一下你的服务的进程号是多少。
ps -ef | grep greeter_server
一般看到的结果会是这样的:
5013335441308:23下午 ttys000 0:00.66./greeter_server
50136360413011:04下午 ttys000 0:00.00 grep --color=auto greeter
一个是我们启动的服务,另一个是我们刚执行的命令,我们看第一行第二列,执行:
kill 33354
整个流程完成!
后续还是要继续看看内部这个项目是怎么嵌入内容的,原理可能我还没有太多时间来处理,但是我至少想知道这个服务内部怎么加代码,调整接口。
这里参考的资料非常多,大都基于linux,我把一些比较有参考意义的或者是比较关键的给大家放出来,大家参考。
Mac安装protobuf:https://www.jianshu.com/p/24ac2300bf1d
gRPC详解:https://www.jianshu.com/p/9c947d98e192
Building Standard TensorFlow ModelServer:https://tensorflow.google.cn/tfx/serving/serving_advanced?hl=en
gRPC源码路径:https://github.com/grpc/grpc。
gRPC构建建议:https://github.com/grpc/grpc/blob/master/BUILDING.md