Press "Enter" to skip to content

腾讯 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 . <br/>\
    try this api below:<br/> \
    1. vec api:    <a href='"+vecAPI+"'>"+vecAPI+"</a> <br/>\
    2. sim api:    <a href='"+simAPI+"'>"+simAPI+"</a> <br/>\
    3. top sim api:    <a href='"+topSimAPI+"'>"+topSimAPI+"</a> <br/>\
    "
@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":"红烧肉"
  }

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注