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> 解决问题的方式,就是解决它一次 

原文地址:https://www.cnblogs.com/widgetbox/p/13432493.html