本文介绍了一个采用Flask + uwsgi + nginx 部署TensorFlow应用的方法。以此可以搭建一个简单的机器学习云服务器
一. 创建虚拟环境
由于本人安装的电脑带有显卡,所以安装了2个版本的tensorflow,一个带gpu,一个不带gpu。不同版本的tensorflow使用虚拟环境进行分割
pip install virtualenv
mkdir tf_gpu
virtualenv tf_gpu –system-site-packages
mkdir tf_cpu
virtualenv tf_cpu –system-site-packages
注:添加 –system-site-packages 是将系统site-packages里的包 包含进去; 虚拟目录的位置按需设
二.tensorflow安装
tensorflow的安装可以参考官网上的连接通过pip安装或者自己编译
https://www.tensorflow.org/install/pip 或 https://www.tensorflow.org/install/source
三.nginx,flask,uwsgi,supervisor安装
yum install nginx
pip install flask uwsgi supervisor
注:flask是一个轻量级的web服务组件,用来做TensorFlow的接口。
uwsgi用来部署flask。
nginx是uwgsi的前端,后续可以做负载均衡等配置
supervisor用来启动uwsgi
四.flask,uwsgi, supervisor ,nginx配置
假设训练好的模型文件为”ocr.pb”
flask导入tensorflow的python 代码如下
from flask import Flask,request
import tensorflow as tf
from tensorflow.core.framework
import graph_pb2
import numpy as np
input_graph = "ocr.pb"//pb文件位置
input_graph_def = graph_pb2.GraphDef()
mode = "rb"
with tf.gfile.FastGFile(input_graph, mode) as f:
input_graph_def.ParseFromString(f.read())//读取pb文件
_ = tf.import_graph_def(input_graph_def,name="")//导入pb文件
sess = tf.Session() init = tf.global_variables_initializer()
sess.run(init)//初始化session
//模型pb文件的输入/输出在建立pb时给出,具体方法可以参考
//https://www.programcreek.com/python/example/104504/tensorflow.python.framework.graph_util.convert_variables_to_constants
//导出pb文件的核心函数是graph_util.convert_variables_to_constants
input_x = sess.graph.get_tensor_by_name("cv-input:0")//模型的入口
out_softmax = sess.graph.get_tensor_by_name("cv-output:0")//模型的输出口
app = Flask(__name__)
@app.route('/')
def hello_world()://定义根目录的回复,用来测试web服务是否启动,可以忽略
return 'hello_world'
@app.route('/analysis_ocr', methods=['GET', 'POST'])//定义模型预测的入口
def analysis():
if request.method == 'POST':
try:
decoded_image = np.frombuffer(request.stream.read(),dtype = np.float32).reshape(10,1,32,32)//通过post接收客户端传来的图片,这个demo的输入为10张单通道 32X32 大小的图片
_result = sess.run([out_softmax],feed_dict={input_x:decoded_image})
return str(_result[0])//返回预测出的分类
except:
return "[-1]"
if __name__ == '__main__':
app.run()
uwsgi ini配置文件
[uwsgi]
socket=/run/uwsgi/u_madian.sock //使用unix socket通信,centos7貌似不能定义在/tmp目录
chown-socket = nginx:nginx //前端用的是nginx,所以用户定义为nginx
chmod-socket = 664
chdir = /home/vision/uwsgi_project/madian //这样使用在python文件中使用相对路径来载入pb文件
wsgi-file=/home/vision/uwsgi_project/madian/flask_madian.py //要运行的pb文件位置
virtualenv = /home/vision/python_env/tf_gpu //使用的python虚拟环境,这个demo定义使用前文安装的gpu版本的tensorflow
enable-threads = true
callable=app //python文件中的 app = Flask(__name__) flask具体的使用可以参考其官网
processes=1 //测试中发现 多线程启动会导致预测失败 原因没有深究
supervisor 配置
编辑supervisor的配置文件
vi /etc/supervisord.conf
在文件最后添加
[program:madian] ;command后为uwsgi启动命令
command = /usr/local/bin/uwsgi --ini /home/vision/uwsgi_project/madian/u_madian.ini
;环境变量中添加了cuda相关的LD_LIBRARY_PATH
environment=HOME="/home/vision",LD_LIBRARY_PATH=":/usr/local/extras/CUPTI/lib64:/usr/lib/TensorRT-5.0.2.6/lib:/usr/local/cuda/lib64"
autostart = true
autorestart = true
startretries = 3
user = root
stdout_logfile=/home/vision/uwsgi_project/madian/logs/out.log
stderr_logfile=/home/vision/uwsgi_project/madian/logs/err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=10
stopsignal=QUIT
nginx配置
新建一个文件 /etc/nginx/conf.d/uwsgi.conf
server {
listen 7000;
server_name _;
root /usr/share/nginx/html;
index index.php index.html;
location / {
try_files $uri @app;
}
location @app {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/u_madian.sock;
}
}
5.各服务启动
supervisor ,nginx
supervisor启动
systemctl start supervisord
systemctl enable supervisord
nginx启动
systemctl start nginx
systemctl enable nginx
6.测试
通过网址,http://127.0.0.1:7000/analysis_ocr 将图片二进制流post到web服务器端,则会返回具体的分类结果