腾讯 800 万中文词向量 API Demo 搭建
作者:李大雷
原文链接:
https://zhuanlan.zhihu.com/p/94124468
1. 前言
鹅厂 18 年 10 月开源了一份包含 800 万中文词的词向量模型。
官方的介绍中显示其能覆盖一些很低频的词。如 喀拉喀什河 ,一些网络新词如 因吹斯汀 竟然也可以查到对应的词向量,以及输入 马云也 可以在最相似词中找到 马爸爸 等词。
总体来说这个模型在 覆盖率 、 新鲜度 、 准确性 上都有不错的表现。
比较欠缺的是,其训练模型中有一定比例的词并非是词。如马云的 top 相似词结果中有 :马云和、马云说、如马云等词。以及对于未登录词无法增量训练。
本文尝试基于 python 3 + flask + gensim 搭建一个简易的 api 服务,让你可以在实验环境中试玩这个模型。
2. 模型下载
该模型压缩后 6.4 GB ,解压后 16 GB,在内存中展开 18.5 GB,全量模型加载需要 26 min 左右。
搭建前确保机器资源充足,另外如果只是试玩建议对原始模型做裁剪,如只加载前 10 w 词。
全量模型下载:https://ai.tencent.com/ailab/nlp/embedding.html
精简版下载(全量模型的前 10w 个词):
链接: https://pan.baidu.com/share/init?surl=NidB4Rsy-tqY49QsysUgMw
提取码: tmda
第3、4步骤是虚拟环境搭建以及依赖安装,已经就绪的同学可以直接跳到步骤 5 运行代码。
3. virtualenv 环境搭建
-
安装 virtualenv
pip3 install virtualenv
-
创建 virtualenv(以 /tmp/work 为例)
cd /tmp/work/ virtualenv -p python3 w2v_venv
-
进入 virtualenv
source w2vAPI/bin/activate
4. 依赖安装
-
将以下数据,保存为 requirements.txt 。
boto==2.49.0 boto3==1.10.26 botocore==1.13.26 certifi==2019.9.11 chardet==3.0.4 Click==7.0 docutils==0.15.2 Flask==1.1.1 gensim==3.8.1 idna==2.8 itsdangerous==1.1.0 Jinja2==2.10.3 jmespath==0.9.4 MarkupSafe==1.1.1 numpy==1.17.4 python-dateutil==2.8.0 requests==2.22.0 s3transfer==0.2.1 scipy==1.3.3 six==1.13.0 smart-open==1.9.0 urllib3==1.25.7 Werkzeug==0.16.0
-
执行安装
pip3 install -r requirements.txt
5. 运行
-
将以下数据,保存为 w2v.py 。
import json from flask import Flask, request from gensim.models import KeyedVectors from flask import jsonify import argparse import sys import socket import time import logging logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) formatter = logging.Formatter("%(asctime)s;%(levelname)s: %(message)s", "%Y-%m-%d %H:%M:%S") console = logging.StreamHandler() console.setLevel(logging.DEBUG) console.setFormatter(formatter) logger.addHandler(console) app = Flask(__name__) app.config['JSON_AS_ASCII'] = False def isNoneWords(word): if word is None or len(word)==0 or word not in model.vocab: return True else: return False @app.route("/", methods=['GET']) def welcome(): vecAPI="http://"+localIp+":"+str(port)+"/vec?word=淘宝" simAPI="http://"+localIp+":"+str(port)+"/sim?word1=淘宝&word2=京东" topSimAPI="http://"+localIp+":"+str(port)+"/top_sim?word=淘宝" return "Welcome to word2vec api .
\ try this api below:
\ 1. vec api: "+vecAPI+"
\ 2. sim api: "+simAPI+"
\ 3. top sim api: "+topSimAPI+"
\ " @app.route("/vec", methods=['GET']) def vec_route(): word = request.args.get("word") if isNoneWords(word): return jsonify("word is null or not in model!") else: return jsonify({'word':word,'vector': model.word_vec(word).tolist()}) @app.route("/sim", methods=['GET']) def similarity_route(): word1 = request.args.get("word1") word2 = request.args.get("word2") if isNoneWords(word1) or isNoneWords(word2): return jsonify("word is null or not in model!") else: return jsonify({'word1':word1,'word2':word2,'similarity':float(model.similarity(word1, word2))}) @app.route("/top_sim", methods=['GET']) def top_similarity_route(): word = request.args.get("word") if isNoneWords(word): return jsonify("word is null or not in model!") else: return jsonify({'word':word,'top_similar_words':model.similar_by_word(word, topn=20, restrict_vocab=None)}) def getLocalIP(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip=s.getsockname()[0] s.close() return ip def main(): global model global port global localIp for arg in sys.argv[1:]: logger.debug(arg) p = argparse.ArgumentParser() p.add_argument("--model", help="Path to the trained model") p.add_argument("--host", help="Host name (default: localhost)") p.add_argument("--port", help="Port (default: 8888)") args = p.parse_args() host = args.host if args.host else "localhost" port = int(args.port) if args.port else 8888 localIp = getLocalIP() if not args.model: logger.debug("Usage: w2v.py --model model_path [--host host --port 8888]") sys.exit(1) logger.debug("start load model:" + str(args.model)) start_time = time.time() model = KeyedVectors.load_word2vec_format(args.model, binary=False) logger.debug("end load model:" + str(args.model)) # app.run(host=host, port=port,debug=True) app.run(host=host, port=port) if __name__ == "__main__": main()
-
启动 api 服务
nohup python3 w2v.py --model /opt/cuiyulei/Tencent_AILab_ChineseEmbedding.txt --host 你的ip 2>&1 &
6. 结果
-
浏览器中键入
http://你的ip:8888/
-
提示如下,表示搭建完成
Welcome to word2vec api . try this api below: 1. vec api: http://ip:8888/vec?word=淘宝 2. sim api: http://ip:8888/sim?word1=淘宝&word2=京东 3. top sim api: http://ip:8888/top_sim?word=淘宝
-
运行效果
input:
http://ip:8888/top_sim?word=红烧肉
output:
{ "top_similar_words":[ [ "糖醋排骨", 0.8907967209815979 ], [ "红烧排骨", 0.8726683259010315 ], [ "回锅肉", 0.858664333820343 ], [ "红烧鱼", 0.8542774319648743 ], [ "梅菜扣肉", 0.8500987887382507 ], [ "糖醋小排", 0.8475514650344849 ], [ "小炒肉", 0.8435966968536377 ], [ "红烧五花肉", 0.8424086570739746 ], [ "红烧肘子", 0.8400496244430542 ], [ "糖醋里脊", 0.8381932377815247 ], [ "红烧猪蹄", 0.8374584913253784 ], [ "青椒炒肉", 0.8344883918762207 ], [ "粉蒸肉", 0.8337559700012207 ], [ "水煮肉片", 0.8311598300933838 ], [ "青椒肉丝", 0.8294434547424316 ], [ "鱼香茄子", 0.8291393518447876 ], [ "烧茄子", 0.8272593021392822 ], [ "梅干菜扣肉", 0.8267726898193359 ], [ "土豆炖牛肉", 0.8263725638389587 ], [ "红烧茄子", 0.8244959115982056 ] ], "word":"红烧肉" }
7. 相关文章
腾讯AI Lab开源大规模高质量中文词向量数据,800万中文词随你用 AINLP 的公众号接口
本文由作者授权AINLP原创发布于公众号平台,点击’阅读原文’直达原文链接,欢迎投稿,AI、NLP均可。
推荐阅读
关于AINLP
AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLP君微信(id:AINLP2),备注工作/研究方向+加群目的。