如何使用tensorflowServing进行模型部署
TensorFlow Serving是用于机器学习的灵活,高性能的服务系统,针对生产环境而设计。 TensorFlow服务 可以轻松部署新算法和实验,同时保持不变服务器体系结构和API。TensorFlow Serving开箱即用 与TensorFlow模型集成,但可以轻松扩展以服务于其他 模型类型
关键概念
Key Conception
Loaders
Loaders管理Servables的生命周期。Loader API 是一种支持独立于特定算法,数据或产品用例的通用基础架构。具体来说,Loaders标准化了用于加载和卸载Servable的API。
Sources
Sources 是可以寻找和提供 Servables 的模块,每个 Source 提供了0个或者多个Servable streams,对于每个Servable stream,Source 都会提供一个Loader实例。
Managers
管理 Servable 的整个的生命周期,包括:
- loading Servables
- serving Servables
- unloading Servables
Managers监听Sources并跟踪所有版本。Managers尝试满足、响应Sources的请求,但是如果所请求的资源不可用,可能会拒绝加载相应版本。Managers也可以推迟“卸载”。例如,Managers可能会等待到较新的版本完成加载之后再卸载(基于保证始终至少加载一个版本的策略)。
Servables
Servable是Tensorflow Serving的核心抽象,是客户端用于执行计算的基础对象,其大小和粒度是灵活的。Tensorflow serving可以在单个实例的生命周期内处理一个或多个版本的Servable,这样既可以随时加载新的算法配置,权重或其他数据;也能够同时加载多个版本的Servable,支持逐步发布和实验。由此产生另外一个概念:Servable stream,即是指Servable的版本序列,按版本号递增排序。Tensorflow Serving 将 model 表示为一个或者多个Servables,一个Servable可能对应着模型的一部分,例如,a large lookup table 可以被许多 Tensorflow Serving 共享。另外,Servable不管理自己的生命周期
Core
Tensorflow Serving core 负责管理Servables的Lifecycle和metrics,将Servables和loaders看作黑箱(opaque objects)。
广义地说:
- Sources create Loaders for Servable Versions.
- Loaders are sent as Aspired Versions to the Manager, which loads and serves them to client requests.
例子:
- Source 为指定的服务(磁盘中检测模型权重的新版本)创建Loader,Loader里包含了服务所需要的元数据(模型);
- Source 使用回调函数通知 Manager 的 Aspired Version(Servable version的集合);
- Manager 根据配置的Version Policy决定下一步的操作(是否 unload 之前的Servable,或者 load 新的Servable);
- 如果 Manager 判定是操作安全的,就会给 Loader 要求的resource并让 Loader 加载新的版本;
- 客户端向 Manager 请求服务,可以指定服务版本或者只是请求最新的版本。Manager 返回服务端的处理结果;
Extensibility
Tensorflow Serving提供了几个可扩展的entry point,用户可以在其中添加自定义功能。
Version Policy
Version Policy(版本策略)可以指定单个Servable stream中的版本加载和卸载顺序。它包括Availability Preserving Policy(在卸载旧版本之前加载并准备好新版本)和Resource Preserving Policy(在加载新版本之前先卸载旧版本)。
Source
New Sources可以支持新的文件系统,云产品和算法后端,这主要和创建自定义Source有关。
Loaders
Loaers是添加算法、数据后端的扩展点。Tensorflow就是这样一种算法后端。例如,用户将实现一个新的Loader,以便对新的Servable机器学习模型实例的访问和卸载。
Batcher
将多个请求批处理为单个请求可以显着降低计算成本,尤其是在存在诸如GPU的硬件加速器的情况下。Tensorflow Serving包括一个请求批处理小部件,它允许客户端轻松地将请求中特定类型的计算进行批量处理。
系统环境搭建
系统及软硬件说明
系统:Ubuntu16.04
软件
- 驱动 450.23.05
- cuda 11.1
- cudnn 8.0.5
- tensorflow nightly-gpu(2.4)
- python 3.7.9
硬件
- RTX 3090
导出Keras模型
将keras中以model.save(filepath)
保存的模型h5文件,转为tensorflow的xx格式,加载模型时,使用✔️tf.keras.models.load_model
而不是❌keras.models.load_model
,
1 | from keras import backend as K |
导出之后,有以下目录结构
导出之后,使用以下命令查看模型的signature、input、output,后续客户端调用需要这些信息。
1 | saved_model_cli show --dir tfs/0/ --all |
1 | signature_def['serving_default']: |
以上可以确定,signature、input、output分别为:serving_default,input_1,activation_49
saved_model_cli为tensorflow的python工具包,位于tensorflow/python/tools/saved_model_cli.py
下,一般安装了tensorflow,可以直接找到该命令。
Docker部署模型
拉取tfs的docker镜像
1.安装docker
安装过程参考官方安装文档Install Docker Engine on Ubuntu
2.安装nvidia-docker
在docker上安装nvidia插件,以便使得应用在GPU上运行,安装过程参考:Installation Guide
3.拉取tfs镜像
docker官网上包含不同版本的tfs镜像,根据需求需要版本,使用以下命令拉取tfs镜像
1 | sudo docker pull tensorflow/serving:nightly-gpu |
启动tfs容器
使用以下命令启动tfs容器
1 | sudo nvidia-docker run -p 8500:8500 \ |
其中9e73a1470b72为tfs镜像的id,可通过docker image ls查看
tfs容器可用参数解释:
1 | --port = 8500 用于侦听gRPC API的端口 |
客户端的编写
基于Python编写客户端时,需要安装tensorflow_serving、grpc库包
1 | import cv2 |
Web服务
1 | TensorFlow模型的计算图,一般输入的类型都是张量,你需要提前把你的图像、文本或者其它数据先进行预处理,转换成张量才能输入到模型当中。而一般来说,这个数据预处理过程不会写进计算图里面,因此当你想使用TensorFlow Serving的时候,需要在客户端上写一大堆数据预处理代码,然后把张量通过gRPC发送到serving,最后接收结果。现实情况是你不可能要求每一个用户都要写一大堆预处理和后处理代码,用户只需使用简单POST一个请求,然后接收最终结果即可。因此,这些预处理和后处理代码必须由一个“中间人”来处理,这个“中间人”就是Web服务。 |
可以使用Tornado来搭建web服务
版本管理
待完善
应用例子
例子来源于美团技术团队基于TensorFlow Serving的深度学习在线预估
该例子针对广告精排的业务场景,使用tfs进行模型部署,针对高速的推断进行逐步的优化,并突破现有tfs的束缚,解决模型切换的毛刺问题,使得tfs部署后在性能上满足业务场景
性能优化措施
请求端优化:使用OpenMP多线程并行处理请求,时间从5ms降低到2ms
构建模型的ops优化:分析构建模型的ops中的耗时操作,将其分离出去,或者使用低阶API替代高阶API
XLA,JIT优化:优化Tensorflow的计算图,剪除荣誉的计算
模型切换毛刺问题
模型切换时,大量的请求超时,原因有两个:一是更新、加载模型和处理请求的线程共用线程池,切换模型时无法处理请求;二是模型采用Lazy Initialization加载,第一次请求需要等待计算图初始化。
问题一的解决办法:
将uint32 num_load_threads = 0; uint32 num_unload_threads = 0;
设置为1,
问题2的解决办法:
模型加载后进行一次预热
参考资料
Tensorflow Serving部署tensorflow、keras模型详解_jeffery0207的博客-CSDN博客
TensorFlow Serving + Docker + Tornado机器学习模型生产级快速部署 - 知乎
SignatureDefs in SavedModel for TensorFlow Serving | TFX
使用tensorflow serving部署keras模型(tensorflow 2.0.0) - 知乎
基于TensorFlow Serving的深度学习在线预估 - 美团技术团队
TensorFlow Serving入门 - 简书
TensorFlow Serving 入门教程(Windows)_I’m George 的博客-CSDN博客
TensorFlow Serving 使用 及 部署_Eric’s Blog-CSDN博客