YangYouji's WebSite

Centos7 + Flask + uwsgi + nginx 部署 TensorFlow

本文介绍了一个采用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服务器端,则会返回具体的分类结果

退出移动版