腾讯 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),备注工作/研究方向+加群目的。