# Book label

通过AI算法对书籍的流派、风格、题材元素、主角身份、主角姓名、主角性格，以上6个维度进行自动化打标，节省人工标注成本，经人工检验后，准确率稳定在90%以上的维度上线自动化。

目前的标签AI打标流程主要分为：模型训练、模型部署、提供在线服务。规则是由运营方提供，这里不做过多的介绍。

### 1.模型训练

通过已有的标签，进行有监督的训练，做文本分类任务。模型主要做的事情有两个，一个是从复杂的文本信息中抽取出有用的特征，另一个是对抽取出来的特征做分类。

这6个标签维度，都各有不同的特点，因此特征的输入选择也有所不同。每一个维度我们都做了大量的实验，包括模型和特征的选取，以下列出的是最优结果的组合。由于男女频的标签库差别较大，以上6个标签都分别训练了男女频两版模型，但同一标签的做法，男女频较为相似，下文记叙中不区分男女频。

* 流派：输入特征为书名，模型选择xlnet。首先经过规则模块，命中规则即可返回预测结果。若没有命中，将从已有标签的书籍中搜索结果，通过书名的相似度进行匹配，返回相似度大于0.95的结果。若无命中，再调用模型进行预测，返回结果。
* 题材元素：输入特征为书籍内容，模型选择gpt。取书籍原文的前100章，调用hanlp做摘要提取，压缩到300字以内，再输入到gpt中做预测。通过模型得到的预测结果，进入规则模块，最后返回结果。
* 主角姓名：输入特征为书籍内容，模型选择midu-ner模型。取书籍原文前20章，调用米读自研的ner模型，识别每一段落中的人名，维护一个含有所有姓名的set，再分别使用名字在原文做count，得到每一个名字的出现次数，选取次数最高的作为书籍的主角，该方法经验证准确率高达99%。
* 主角身份：输入特征为书籍的基础信息以及内容，模型选择为electra。根据书籍的基础信息和原文内容经过规则模块，命中则直接返回结果。经过模型预测，获取预测标签。
* 主角性格：输入特征为书名+流派+主角身份+主角姓名+题材元素，模型选择roberta。选取前6大类别的标签，覆盖80%以上的书籍，做分类。待检验。
* 风格：待做。

### 2. 模型部署

我们采用 Tensorflow Serving + Flask + Docker 作为部署方案。

Tensorflow Serving 只关心模型的推理，接收Tensor，在gpu上推理计算，输出Tensor；Flask作为前端服务，统一处理所有接口请求，对文本信息进行编解码、异常处理。配合Docker，使得部署和管理更加简易方便。

因为标签接口的qps不高，每一个模型分别部署在一台gpu型的机器上成本较高，于是考虑将多个模型集成在一台单卡机器上。

tfs模型仓库目录如下所示，在model.config文件中定义每一个模型的信息。

```
.
├── docker_run.sh
├── models
│   ├── model.config
│   ├── platform.config
│   ├── book-school-female
│   │   └── ...
│   ├── book-school-male
│   │   └── ...
│   ├── book-theme-female
│   │   └── ...
│   ├── book-theme-male
│   │   └── ...
│   ├── comment-sentiment
│   │   └── ...
│   ├── ner
│   │   └── ...
│   ├── role-id-female
│   │   └── ...
│   └── role-id-male
│       └── ...
└── scripts
    └── ...
```

```
book-school-female
└── 0
    ├── assets
    ├── saved_model.pb
    └── variables
        ├── variables.data-00000-of-00002
        ├── variables.data-00001-of-00002
        └── variables.index
```

执行以下命令启动Tensorflow Serving服务，8500端口提供gRPC调用，8501端口提供REST API方式调用。

```
docker run --gpus '"device=0"' -itd -p 8500:8500 -p 8501:8501 --mount type=bind,source=/data/app/tfs-models/models/,target=/models \
tensorflow/serving:latest-gpu --model_config_file=/models/model.config --platform_config_file=/models/platform.config
```

由于tfs只能处理tensor的运算，将文本输入到模型之前需要对文本做编码，以及对模型输出的tensor做解码。（注：tensorflow-serving nightly版本中即将支持将文本的编解码处理加入动态图中做推理计算）

因此我们在Tensorflow Serving 服务层上创建 Flask 服务，负责分发请求、异常处理以及对输入输出的编解码，并且提供一个统一的域名地址，与调用方代码解耦。

![](https://576935259-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MDzFHPbPyJ1xwxFkx0K%2F-MMA8OofGHKr7XBpg6H6%2F-MMAJtiMa4WvKVPlDi4x%2Fimage.png?alt=media\&token=93838c18-bb96-47c7-8f31-0d85e2014051)

### 3. 在线打标服务

这部分的服务主要处理规则逻辑和获取模型预测的结果，比较偏向业务层面，改动频繁，因此将这个服务分离出来。

crontab启动定时任务，每隔一小时获取待打标签书籍id，对书籍进行自动化打标，并上传至后台。

```
0 * * * * flock -xn /tmp/upload_tags.lock -c 'source $HOME/.bash_profile && /data/app/upload_tags_timing/venv/bin/python3 -u /data/app/upload_tags_timing/main.py prd >> /data/app/upload_tags_timing/nohup.log 2>&1'
```
