Created 03/28/2020 at 08:50PM

前言

tensorflow serving是tensorflow推出的一个用于模型部署的工具,它可以让你基于docker快速部署你的模型,方便地进行版本迭代和容器管理,此外tensorflow serving基于C++构建,摒弃了一些模型训练之中的冗余参数和设计,让你的模型可以高性能地运行在CPU/GPU服务器上。这几天在尝试将公司基于tensorflow 1.9.0的TTS模型跑在CPU服务器上,已经存在一个基于tornado构建的web服务,但由于直接使用了training时期保存的模型,性能损失比较大,于是我尝试着用tensorflow serving将模型部署起来,希望能提高性能。(这些都是导师让我练练手的,实际上公司的TTS服务是用C++代码写的超大的项目,性能很强)

踩坑

由于是tensorflow 1.9.0,tf2.0的那套简便的方法就用不了了,我参考了知乎大神的文章,大体思路就是:

  1. 首先export model,准备计算图的代码,将保存的参数restore进入计算图;
  2. 然后调用export model的方法,导出模型
  3. 模型导出之后就直接拉取tensorflow serving的镜像然后创建,这里注意如果是tensorflow-serving-1.x.0的镜像,docker run之后就直接可以访问容器服务,tensorflow-serving-1.x.0-devel的镜像需要docker run之后,再进入容器运行tensorflow_model_server指定容器映射的端口,model_name等等,如果计算图没有其他依赖,直接拉取tensorflow-serving-1.x.0就行
  4. 创建tensorflow serving镜像时需要指定端口映射,然后你可以通过这个端口访问serving服务,还需要将宿主机自身模型的path挂载到容器的/models
  5. 如何使用运行好的容器服务?可以通过RESTful API访问,也可以通过gRPC API访问
  6. 最后模型部分已经全部交给了tensorflow-server,再去写一个web服务包装一下就可以快速部署了

失败

tensorflow 1.9.0作为一个“上古”版本的tensorflow,很多文档都是不全的或者说是难以找到,好不容易摸清楚了涉及到哪些API,我被一个报错给弄懵了,“Op type not registered ‘PyFunc’ in binary running on xxxxxx”,后来查了一下才知道,原来tensorflow-serving基于C++构建,将模型参数保存下来后,全部用C++来运行,所以不支持一些原生python的操作,比如tensorflow.py_func,然而需要部署的那一份代码里面有大量py_func,除非将全部的py_func用tensorflow原生方法代替,不然没办法用tensorflow-serving。

成功

最终我还是成功用起来了tensorflow serving啦!把代码里面的用到了tensorflow.py_func的全部替换成tensorflow原生操作就可以了,这里不需要重新训练模型,只需要参数能和计算图匹配就行。不过经过测试,发现tensorflow-serving并没有加速多少(用的是RNN型模型),不过对于版本管理和加载模型方面确实优秀了很多。成功运行容器之后还遇到了一个坑,就是RESTful api的端口和gRPC的端口不一样,前者对应8501,后者需要另设8500,大家可以参考文章