聊聊层次多标签分类NLP任务的实践
概述
这次要做的就是基于PaddleNLP库,微调一个针对层次多标签文本分类的领域模型。从当前趋势看,算法的落地路径主要分两条:一条是用机器学习或传统算法走通,另一条是依托预训练模型这类深度学习方案。所以做技术调研时,两个方向都得盯着——后者对硬件资源比较挑剔,但胜在预训练模型微调提供了一整套数据标注、模型训练、模型分析、模型压缩到预测部署的闭环,能大幅压缩开发周期,低成本迁移到实际场景。话说回来,现在的大多数算法,其实都是基于某个预训练模型做微调来实现的。

那为什么最终选了PaddleNLP?一开始在modelscope[1]上翻了不少NLP模型,发现两个硬伤:一是不少模型不支持微调,或者微调文档写得一团模糊;二是压根不支持层次多标签文本分类任务。这两个问题直接把modelscope筛掉了——也许是我没找对地方,但结果就是否了。
接着试了NeuralClassifier[2],它对英语的支持还可以,但文档不够清晰,全英文而且讲解偏少,对层次多标签场景的支撑也不太到位,所以也放弃了。
最终找到PaddleNLP库。虽说这个库的应用范围不算最广,但有大厂背书,对NLP各种任务的支持很到位,社区活跃度也不错,最关键的是——它是一个工业级别的库。
数据标注平台
环境搭建
doccano[3]是一个轻量的数据标注平台,PaddleNLP的训练数据需要借助它生成数据文件。说实话,搭建环境踩了不少坑:先在阿里云上装,失败;换到centos虚拟机上装,又失败;最后在Windows电脑上一次搞定。所以经验是——环境不对就果断换,别死磕。
安装部署其实只需要几个命令:
# 安装依赖
pip install doccano==1.6.2
# 初始化数据库
doccano init
# 创建用户
doccano createuser --username admin --password pass
# 开启web服务
doccano webserver --port 8000
# 在另一个终端启动任务队列
doccano task
浏览器打开http://127.0.0.1:8000/[4],用创建的用户名密码登录,就能开始标注了。
上传数据集
点击数据集 → 操作 → 导入数据集,就可以把本地待标注的数据集导入进来:
doccano支持TextFile、TextLine、JSONL和CoNLL四种上传格式。对于文本分类本地数据集定制训练,
统一使用TextLine
上传时
选择TextLine
标签构建
点击标签 → 操作 → 创建标签,开始添加分类类别:
填入类别标签名称,选个颜色(不同标签选不同颜色会方便区分),最后点击保存或保存并添加下一个。
对于
层次分类任务
叶结点标签路径作为标签
##作为分隔符来区分不同层级:任务标注
标注时,选好对应的分类类别标签,按回车(Enter)键确认即可:
数据导出
数据集 → 操作 → 导出数据集,默认假设所有数据已经标注完成且正确:
选择导出文件类型为JSONL,导出后文件命名为doccano.jsonl:
数据转换
doccano导出的数据集还不能直接喂给PaddleNLP训练,需要先做一次转换。
在源码路径/PaddleNLP/applications/text_classification下,把导出的JSONL文件上传到这个目录,然后根据任务类型执行对应的脚本。层次多标签分类任务的转换命令是:
python doccano.py
--doccano_file doccano.jsonl
--sa ve_dir ./data
--splits 0.8 0.2
--task_type "hierarchical"
执行完后会自动生成data文件夹,内容如下:
层次分类训练与推理
微调训练
在源码路径/PaddleNLP/applications/text_classification/hierarchical下执行。
预训练模型微调默认基于GPU训练,脚本如下:
python train.py
--dataset_dir "data"
--device "gpu"
--max_seq_length 128
--model_name "ernie-3.0-medium-zh"
--batch_size 32
--early_stop
--epochs 100
训练结束后会生成checkpoint文件夹,内容如下:
问题及解决
这里想多说一句:如果数据集的格式准备得不够恰当,训练时可能不报错,但checkpoint文件夹里却是空的——没有生成任何参数文件。这个坑我踩过,所以后来老老实实通过doccano来生成训练数据。具体问题可以看这个issue[5]。
模型评估
可忽略。
模型预测
训练结束后,准备待预测数据文件data.txt和类别标签对照列表label.txt,用训练好的模型进行预测,默认在GPU环境下:
python predict.py --device "gpu" --max_seq_length 128 --batch_size 32 --dataset_dir "data"
脚本会自动读取data.txt,基于微调后的模型做预测。
微调模型的导出
将微调好的模型导出到指定目录保存:
python export_model.py --params_path ./checkpoint/ --output_path ./export
微调模型的推理
基于导出的微调模型做推理,也就是实际提供给外部使用的环节。推理脚本在路径/PaddleNLP/applications/text_classification/hierarchical/deploy/predictor下:
python infer.py
--device "gpu"
--model_path_prefix "../../export/float32"
--model_name_or_path "ernie-3.0-medium-zh"
--max_seq_length 128
--batch_size 32
--dataset_dir "../../data"
执行结果如下:
总结
整个训练推理流程用的是阿里云的人工智能平台PAI(之前写过申请试用的文章,这里就不展开了)。走完一遍流程,对实现原理也就有了直观理解。核心还是基于预训练模型ERNIE做微调——现在诸多的文本分类任务、NLP任务基本都靠预训练模型(BERT等)来微调,这已经是不可逆的趋势。所以要是以后买新电脑,尽量选个显卡够用的。
当然,为了保证数据的准确性,整个流程需要更工程化一些。对于很多NLP任务,如果能识别出可以用NLP解决,建议直接借助这类成熟的NLP算法库,这会是未来的方向。
Reference
[1] modelscope: https://modelscope.cn/my/overview
[2] NeuralClassifier: https://github.com/Tencent/NeuralNLP-NeuralClassifier
[3] doccano: https://github.com/PaddlePaddle/PaddleNLP/blob/develop/applications/text_classification/doccano.md
[4] http://127.0.0.1:8000/: http://127.0.0.1:8000/
[5] issue: https://github.com/PaddlePaddle/PaddleNLP/issues/8286
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名