zoukankan      html  css  js  c++  java
  • 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> 解决问题的方式,就是解决它一次 

  • 相关阅读:
    Java中的Stream流
    JDK1.8之后的新特性和新接口
    IOS6和IOS7的屏幕适配问题
    OC特有语法-分类(category)
    UIApplication的作用
    IO中手机旋转事件的传递
    代码,显示IPhone剩余磁盘空间
    iOS程序的加载过程
    TableView数据源方法的执行顺序
    多线程之线程死锁
  • 原文地址:https://www.cnblogs.com/widgetbox/p/13432493.html
Copyright © 2011-2022 走看看