Python解决gensim加载doc2vec或work2vec向量训练模型文件太慢甚至无法访问的情况
项目中使用了gensim计算帖子向量和相似度,model文件已经训练好,但是在运行的过程中发现,模型加载十分缓慢,需要大约1-2分钟,我们不能让用户等那么长时间,于是得想办法
想法,是否可以将其打包为api的方式,资源只需加载一次模型,然后利用即可,消耗小,速度快
查找各方资料比较中意的有2个方案Django和Flask,2者都是python的web服务框架,区别 Django 是一个重量级的框架,Flask是一个轻量型的框架;
这里我们尝试利用Flask解决该问题
首先安装需要的依赖
pip install Flask
然后写了一段测试代码
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run()
运行代码
python hello.py
Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
Running on http://localhost:5000/
这里有一个警告,flask需要使用 WSGI 启动,这里测试代码可以先不管,我这边是编写完之后解决的这个问题
利用WSGI启动(这块可以最后操作)
pip install Gevent
from gevent.pywsgi import WSGIServer http_server = WSGIServer(('', 5000), app) http_server.serve_forever()
下面是我编写的完整代码
# coding=utf-8 import re, json, time, sys, os import gensim curPath = os.path.abspath(os.path.dirname(__file__)) rootPath = os.path.split(curPath)[0] sys.path.append(rootPath) from setting.default import * from flask import Flask, request, jsonify from gensim.models.doc2vec import Doc2Vec, TaggedDocument from gevent.pywsgi import WSGIServer app = Flask(__name__) app.config['JSON_AS_ASCII'] = False @app.route("/") def index(): return 'hello word!' @app.route("/get_content_similar", methods=['GET']) def get_content_similar(): # 请求参数接收 words = request.args.get("words") # 分割为数组 seg_list = words.split(',') # 预测向量 vector = model_dm.infer_vector(seg_list, steps=5, epochs=70) # 提取数据 sims = model_dm.docvecs.most_similar([vector], topn=100) post_id_dict = [] for i in sims: post_id_dict.append([i[0], i[1]]) return jsonify(post_id_dict) def main(): # 初始化模型 global model_dm model_dm = Doc2Vec.load(WORDS_PATH + 'doc2vec_0619last_300_3_15_paddle', mmap='r') print('--------------初始化模型完成--------------') # 开发模式启动服务 # app.run(host='0.0.0.0') # WSGI启动服务 http_server = WSGIServer(('', 5000), app) http_server.serve_forever() if __name__ == "__main__": main()
在启动的时候加载model文件,到内存中,定义了2个路由,1个请求参数,然后处理结果返回为json,目前请求参数为逗号隔开的分词,如果需要在服务中分词,可自行修改
亲测使用访问
http://localhost:5000/get_content_similar?words=水族,龙鱼
速度提升至200ms左右,效果显著
参考资料
https://dormousehole.readthedocs.io/en/latest/deploying/wsgi-standalone.html#gevent
https://zhuanlan.zhihu.com/p/94124468
https://blog.csdn.net/goddavide/article/details/103712131
作者:旧旧的 <393210556@qq.com> 解决问题的方式,就是解决它一次