近期组内新增了一些自然语言处理的需求,主要是中文分词和通用文本分类的需求。关于分词已经有很多成熟的方案了(例如利用 ElasticSearch 的分词器),但文本分类的需求就需要更专业的工具来处理,恰好发现百度的 PaddleNLP 是一个不错的选择。
PaddlePaddle 是百度开源的一个深度学习平台,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体。PaddleNLP 是一款简单易用且功能强大的自然语言处理开发库。聚合业界优质预训练模型并提供开箱即用的开发体验,覆盖NLP多场景的模型库,搭配产业实践范例,提供极致的训练与推理性能,可满足灵活定制的开发需求。
本文基于 Python 3.9.18 以及 PaddlePaddle 2.6 + PaddleNLP 2.7.2 在 Windows 系统下进行调研,不同版本可能有所差异。因为是预研测试,暂时安装 CPU 版本的 PaddlePaddle,生产环境可根据服务器配置选择 GPU 版本加快处理速度及训练。
安装 PaddleNLP
由于 Python 相同库的不同版本可能存在不兼容的问题,因此使用 conda 进行环境管理,方便项目管理。
-
安装 MiniConda
Anaconda 商业化使用收费。可前往 MiniConda官网 下载安装
-
配置 conda 环境并安装 PaddleNLP
打开 Miniconda Prompt ,创建一个新的环境并安装 PaddlePaddle 以及 PaddleNLP。
1 2 3 4 5 6 7 8 9 10 11 12
| conda create -n paddle_39 python=3.9
conda activate paddle_39
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --set show_channel_urls yes
conda install paddlepaddle==2.6.2 --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
conda install paddlenlp
|
使用 PaddleNLP
初次使用 PaddleNLP 的 Taskflow 功能可能需要下载官方预训练的模型,默认存储在 $HOME/.paddlenlp 目录下。如果服务器数据磁盘挂载有特殊设置或内网部署,则需要在调用时手动修改指定存储路径。
from paddlenlp import Taskflow ner = Taskflow("ner", home_path="/workspace")
|
- 中文分词
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| (paddle_39) PS C:\Users\aofall> python Python 3.9.18 (main, Sep 11 2023, 14:09:26) [MSC v.1916 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from paddlenlp import Taskflow
>>> seg = Taskflow("word_segmentation") >>> seg("近日国家卫健委发布第九版新型冠状病毒肺炎诊疗方案") ['近日', '国家卫健委', '发布', '第九版', '新型', '冠状病毒肺炎', '诊疗', '方案']
>>> seg_fast = Taskflow("word_segmentation", mode="fast") >>> seg_fast("近日国家卫健委发布第九版新型冠状病毒肺炎诊疗方案") ['近日', '国家', '卫健委', '发布', '第九版', '新型', '冠状病毒', '肺炎', '诊疗', '方案']
>>> seg_accurate = Taskflow("word_segmentation", mode="accurate") >>> seg_accurate("近日国家卫健委发布第九版新型冠状病毒肺炎诊疗方案") ['近日', '国家卫健委', '发布', '第九版', '新型冠状病毒肺炎', '诊疗', '方案']
|
- 零样本文本分类
1 2 3 4 5 6 7 8 9
| (paddle_39) PS C:\Users\aofall> python Python 3.9.18 (main, Sep 11 2023, 14:09:26) [MSC v.1916 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from paddlenlp import Taskflow >>> cls = Taskflow("zero_shot_text_classification", schema=["好评", "差评"]) >>> cls("房间干净明亮,非常不错") [{'text_a': '房间干净明亮,非常不错', 'predictions': [{'label': '好评', 'score': 0.9982299185674333}]}] >>> cls("东西还可以,但是快递非常慢,下次不会再买这家了。") [{'text_a': '东西还可以,但是快递非常慢,下次不会再买这家了。', 'predictions': [{'label': '差评', 'score': 0.8738513034090186}]}]
|
接入 Java 应用
由于 PaddlePaddle 是基于 Python 的应用程序,无法直接与 Java 应用程序互通,则需要考虑接入方案,此处以零样本文本分类功能举例。
-
使用Java的 Runtime API 进行接入
这种方案是最简单,但需要 Java 应用和 PaddlePaddle 部署在同一台服务器上,不方便扩展。
-
使用 Django/Flask 等 Web 框架提供 Restful API 接入或使用 GRPC
这里举例使用 Django 提供 Restful API。
在 myapp/urls.py 中添加 URL 指定路由 /process-cls
1 2 3 4 5 6
| from django.urls import path from .views import ProcessView urlpatterns = [ path('process-cls/', ProcessView.as_view(), name='process'), ]
|
编写Controller逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| from django.http import JsonResponse from django.views import View from paddlenlp import Taskflow import json
class ProcessView(View): def post(self, request, *args, **kwargs): try: data = json.loads(request.body) schema = data.get('schema') text_list = data.get('text') cls = Taskflow("zero_shot_text_classification", schema) response_data = [] for text, label in zip(text_list, schema): handle_data = cls(text) // 取出处理后的数据并组装,此处省略... // [{'text_a': '东西还可以,但是快递非常慢,下次不会再买这家了。', 'predictions': [{'label': '差评', 'score': 0.8738513034090186}]}] response_data.append({ "text": text, "label": label, "score": score }) return JsonResponse({"data": response_data}) except json.JSONDecodeError: return JsonResponse({"error": "Invalid JSON format"}, status=400) except Exception as e: return JsonResponse({"error": str(e)}, status=500)
|
- 使用消息队列进行处理
Java 应用侧在接收到请求后向消息队列中发送处理请求,Python 侧在拉取到请求处理,并将处理后的文本再次发回消息队列给 Java 应用侧消费。这个方案需要做好幂等控制以及消息丢失的超时处理。