开发准备:
- docker run -it -p 8208:8208 --privileged --cap-add sys_ptrace tensorflow/serving:latest-devel,privileged与cap-add为必选参数;
- dd if=/dev/zero of=/swapfile bs=1024k count=131072,mkswap /swapfile,swapon /swapfile,启用swap交换;swapoff /swapfile禁止swap交换,然后删除/swapfile文件;
- 复制模型目录与文件至容器中目录,当TensorFlow Serving启动的时候加载,路径如:/models/rank,应包含模型和model.config配置文件;
- apt-get update、apt-get install vim,上传gdb-8.3.tar.gz并解压,./configure、make、make install,gdb-8.3/gdb/python/lib/gdb复制到/usr/local/share/gdb/python下;
- 执行“bazel build -c dbg tensorflow_serving/...“命令进行编译,其中参数dbg为必选参数,要求编译器在编译的时候写入调试信息,以便gdb时进行调试与跟踪;
- /tensorflow-serving/bazel-out/k8-opt/bin/tensorflow_serving/model_servers/tensorflow_model_server --port=8208 --model_config_file=/models/rank/model.config启动;
- ln -s /tensorflow-serving/bazel-out/k8-dbg/bin/tensorflow_serving/model_servers/tensorflow_model_server /tensorflow-serving/tensorflow_model_server,创建软链接;
- TensorFlow Serving → TensorFlow调用边界函数为Status TensorflowPredictor::Predict(const RunOptions& run_options, ServerCore* core, const PredictRequest& request, PredictResponse* response);
断点函数:TensorflowPredictor::Predict
编译命令:bazel build -c opt tensorflow_serving/...
启动参数:--port=8208 --model_config_file=/models/rank/model.config
进程列表:
1 pts/0 Ss+ 0:00 /bin/bash /usr/bin/tf_serving_entrypoint.sh --model_config_file=/models/rank/model.config
8 pts/0 Sl+ 0:01 tensorflow_model_server --port=8500 --rest_api_port=8501 --model_name=model --model_base_path=/models/model --model_config_file=/models/rank/model.config
返回结果:
key: prob, value: dtype: DT_FLOAT
tensor_shape {
dim {
size: 5
}
}
float_val: 0.19764844
float_val: 0.45535076
float_val: 0.3033661
float_val: 0.04150483
float_val: 0.033859164
log4cpp安装:
- 上传log4cpp-1.1.3.tar.gz,解压缩,./configure、make、make install完成编译与安装;
- log4cpp/src/Properties.hh文件复制到/usr/local/inclue/log4cpp下,并修改第12行头为Portability.hh;
- log4cpp/src/DailyRollingFileAppender.cpp文件屏蔽或删除120行unlink函数,解决日志按天滚动删除文件问题;
- docker中log4cpp库可能不可用,可用操作系统下同名库覆盖,解决log4cpp函数未引用的问题;
开发清单:
- 新建Global.h头文件,定义常用内存长度、数据类型和函数宏定义;
- 新建UtilsDef.h头文件,定义字符串、字符串流、集合容器和向量容器;
- 新建UtilsLog.h头文件,定义UtilsLog类,声明静态变量、方法和常量参数;
- 新建UtilsLog.cc文件,实现了类方法,包括初始化、日志写入等;
- 修改main.cc文件,在主监听服务启动前,对日志系统进行初始化和加载;
- 修改predict_impl.cc文件,在模型计算结束后增加代码块,解析请求和应答对象,序列化为JSON格式写入日志;
- 日志输出采用抽样方式,主要目的是降低磁盘IO对服务器的压力,抽样比例为万分之一,在代码中实现;
配置清单:
- 创建properties配置文件,定义root、server和cstime项;
- 配置项采用滚动增加模式,滚动周期为一天,历史数据保留;
- 输出格式采用JSON,在代码中拼装特征值,配置项补充时间戳字段;
系统编译:
- docker run -it -p 8208:8208 tensorflow/serving:latest-devel,版本需与生产环境保持一致;
- apt-get update、apt-get install vim,安装log4cpp组件,详情见“log4cpp安装”说明;
- 从git下载代码,上传覆盖tensorflow_serving目录,bazel build -c opt tensorflow_serving/...开始编译;
- 目标文件tensorflow_model_server(约140MB),覆盖生产环境同名文件,重启服务即可;
- chmod +x tensorflow_serving/tools/pip_package/build_pip_package.sh,增加可执行权限;
系统部署:
- 文件:liblog4cpp.so.5.0.6、tensorflow_model_server、TfsLogs.properties;
- liblog4cpp.so.5.0.6复制到/lib/x86_64-linux-gnu,ln -s liblog4cpp.so.5.0.6 liblog4cpp.so.5;
- tensorflow_model_server复制到/usr/bin路径下,覆盖同名文件;
- TfsLogs.properties复制到/根目录下,日志文件也位于根目录下;
- 部署操作务必确认,否则docker将启动失败,只能重建容器;
- sudo docker restart CONTAINER_ID,重启容器(重启进程);
日志样例:
(好大一片马赛克)
比例采样:
- main.cc启动初始化比例配置信息CMdlCfg::getMdlCfg(CMdl);
- 配置文件位于根下,文件名为TfsModel.properties;
- 在predict_impl.cc文件补充实验名称逻辑判断,返回采样比例;
- 当条件满足的时候,将该记录追加到日志文件中去;
比例配置:
# model list
others=99999
models=_A_,_B_
# model info
_A_=9999
_B_=9999
容器时间:
- 进入容器执行date -R,查看docker时间,显示+0000,表示0时区,比当前北京时间慢八小时;
- 在容器内/usr/share路径下,创建zoneinfo/Asia,并将容器外系统文件Shanghai复制到该目录下;
- 执行命令cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime,复制一份至/etc路径下;
- 重启容器,再次进入查看docker内部时间,与宿主机时间保持一致,修改完成;