1、背景
最近我们部署服务的时候,使用了Django作为服务,我们写了restful的接口,通过调用我们的接口,我们会把传进来的图片,使用caffemodel 或者 pb 文件计算出结果,再以json 格式返回,具体方法如下:
2、文件持久化加载
当每张图片来了以后,我们会使用模型进行分析。但是模型文件有小又大,从1M到500M,甚至更大。如果没来一张图片就加载一次模型,会耗费很多时间,降低效率。我们的做法是使模型在服务启动时,就加载进来,并且持续保持在内存中。这样就可以迅速处理大量图片。
我们可以把model加载放到一个类中,通过对类的实例化,我们就可以实现一直静态加载。其中,对于tensorflow的pb文件,我们一般都是读到一个静态的图 graph 中。 然后再进行加载为session
#加载默认图
loaded_graph= tf.Graph()
with loaded_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(pb_path, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
return loaded_graph
#把默认的图加载到Session中
sess = tf.Session(graph=loaded_graph)
#然后在调用的时候,通过选择图中的输入输出节点。
x=sess.graph.get_tensor_by_name('x:0')
y=sess.graph.get_tensor_by_name('y:0')
#然后执行
feed_dict = {x:img}
y_pred = sess.run([y], feed_dict=feed_dict)
3、Settings.py 设置
如果只是上面代码的设置,还是不会持续加载的。找了很久,终于发现原因是Django还是要设置一下初始化目录的。就是在初始化的时候,把加载类所在的文件夹也初始化了。比如我的类文件都在mysite文件夹
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#这个加进来很重要!!!!!!
'mysite',
]
4、加上uwsgi和Nginx
为了保证更高效的使用并发,我们可以使用uwsgi和Nginx。通过配置,可以提高使用效率。
5、关于内存泄漏
在部署服务过程中,我们发现过几个小时,服务速度就会变慢。经过排查,发现即使我们把graph定义了静态变量,但是每次都创建的session 都是动态的,虽然是 with tf.Session as sess:
这样调用,但是感觉依然有内存溢出。
同时可以参考这篇文字:Tensorflow 内存泄露问题