针对App内大量问题咨询场景,PAI提供搭建NLP智能客服的解决方案。本文介绍如何基于BERT模型,快速构建符合业务的NLP文本分类模型,从而实现智能客服QA平台。

前提条件

  • 已开通PAI(Studio、DSW、EAS)后付费,详情请参见开通
  • 已开通MaxCompute,用于存储训练数据和测试数据。关于如何开通MaxCompute,请参见快速体验MaxCompute
    说明 由于本文的解决方案需要使用PAI-Studio计算资源,而PAI-Studio使用MaxCompute存储结构化数据,因此您必须将训练数据和测试数据导入至MaxCompute中。
  • 已创建OSS存储空间(Bucket),用于存储标签文件和训练获得的模型文件。关于如何创建存储空间,请参见创建存储空间
  • 在DataWorks中,已创建ODPS SQL节点,用于执行PAI命令。关于如何创建ODPS SQL节点,请参见创建ODPS SQL节点
  • 已配置好EASCMD客户端工具,本文使用该工具部署模型。关于如何配置EASCMD客户端工具,请参见下载并认证客户端
  • 已创建PAI-EAS专属资源组,本文训练好的模型会部署至该资源组。关于如何创建专属资源组,请参见创建资源组

背景信息

App内每天有大量用户咨询问题,问题种类不仅多,而且类别相似度高。如果采用人工解答,则人力成本过高。针对该问题,阿里云机器学习PAI提供如下解决方案,助力您有效降低人工服务成本。您仅需执行几段命令,即可在极小开发量下快速搭建智能客服QA平台:
  • 解决方案:在App内自建NLP智能客服QA平台,将数据集中的用户问题分为多种不同类别的QA问题。当用户在线提问时,首先通过基于NLP领域的预训练BERT模型的文本分类算法,将用户问题定位到某一类别。然后通过人机对话形式,将提前准备的答案反馈给用户。
  • 方案架构:NLP智能客服的架构图如下所示。智能客服架构图
  • BERT模型:利用Wikipedia和BooksCorpus的海量大数据语料预训练获得的NLP迁移学习模型,在具体任务中仅需要根据自己的业务数据进行Fine-tune即可。
  • 场景示例:智能客服在真实场景下的示例如下图所示。场景示例
  • 效果提升:该方案无需人工客服解答用户问题,在通常场景下,训练的NLP智能客服模型解答问题的准确率高达94%左右,响应时间在30 ms左右。如果使用更小的预训练模型,响应时间甚至降低到了10 ms,极大满足App内用户的问题咨询需求。

操作流程

基于阿里云机器学习PAI平台,搭建NLP智能客服的流程如下:
  1. 步骤一:准备数据

    使用的训练集和测试集需要导入至MaxCompute,标签文件需要上传至OSS。

  2. 步骤二:训练模型

    基于BERT进行业务数据的模型训练,您只需要输入自己的业务相关数据,并根据业务配置训练任务的相关参数,即可完成模型训练,从而获得训练好的NLP文本分类模型。

  3. 步骤三:评估模型

    对训练好的NLP文本分类模型进行评估,查看模型效果(例如,预测准确率)。

  4. 步骤四:模型预测

    对训练好的NLP文本分类模型输入测试数据集或评估数据集,获得预测的分类结果。

  5. 步骤五:导出模型

    将训练满意的模型导出至文件夹中,以便后续将模型部署为在线服务。

  6. 步骤六:部署模型

    通过PAI-EAS的EASCMD工具,将导出的模型部署为RESTful API。

  7. 步骤七:调试模型服务

    您可以通过PAI-EAS控制台在线调用,或Python脚本批量调用的方式调式模型服务。

  8. 步骤八:监控服务指标

    调用模型服务后,您可以查看模型调用的相关指标水位,包括QPS、RT、CPU、GPU及Memory。

步骤一:准备数据

本文使用公开数据集TNews的数据进行实验,具体数据集如下:
  • 训练集和测试集:已经上传到MaxCompute的公共项目pai_online_project中,训练表名为tnews_bert_et_train,测试表名为tnews_bert_et_dev。您可以在后续的PAI命令中直接查看或调用这两张表。在实际应用中,您需要将自己的数据上传至MaxCompute中,详情请参见导入数据
  • 标签文件:下载标签文件tnews_labels_ext.txt,并将其上传至您的OSS目录中。关于如何上传文件至OSS,请参见上传文件
本文使用的数据集包含五个字段,如下图所示。数据集字段
表 1. 数据集字段说明
字段 描述
example_id 索引编号。
sentence 用于文本分类的文本内容。
keywords 文本关键词。
label 标签代号。
label_desc 标签详情。

步骤二:训练模型

基于BERT进行业务数据的模型训练,您只需要输入自己业务的相关数据,并根据业务配置训练任务的相关参数,即可完成模型训练,从而获得训练好的NLP文本分类模型。模型训练的输入数据及训练完成后的输出数据分别如下:
  • 输入:在PAI命令中,将inputTable参数配置为训练集tnews_bert_et_train和测试集tnews_bert_et_dev,将labelEnumerateValues参数配置为标签文件tnews_labels_ext.txt
  • 输出:在PAI命令checkpointDir参数配置的路径中,输出模型文件和中间结果。
在DataWorks的ODPS SQL节点中,执行如下模型训练的PAI命令。
pai -name easy_transfer_app_ext
  -Dmode=train
  -DinputTable="odps://pai_online_project/tables/tnews_bert_et_train,odps://pai_online_project/tables/tnews_bert_et_dev"
  -DfirstSequence=sentence
  -DsecondSequence=keywords
  -DlabelName=label
  -DlabelEnumerateValues='oss://tongxin-demo1/EasyTransfer/tnews_labels_ext.txt'
  -DsequenceLength=64
  -DcheckpointDir='oss://tongxin-demo1/EasyTransfer/ckp_dir/'
  -DbatchSize=32
  -DnumEpochs=5
  -DdistributionStrategy=ExascaleStrategy
  -DworkerCount=2
  -DworkerGPU=2
  -DworkerCPU=2
  -DoptimizerType=adam
  -DlearningRate=2e-5
  -DmodelName=text_classify_bert
  -DuserDefinedParameters='pretrain_model_name_or_path=google-bert-base-zh'
  -Dbuckets="oss://atp-modelzoo-sh.oss-cn-shanghai-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole,oss://tongxin-demo1.oss-cn-beijing-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -Darn="acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -DossHost="oss-cn-beijing-internal.aliyuncs.com"
表 2. 命令参数说明
参数 是否必选 描述 类型 示例值 默认值
name PAI命令调用的算法包。本文使用迁移学习算法包,因此该参数配置为固定值easy_transfer_app_ext STRING easy_transfer_app_ext
mode 使用模式。进行模型训练时,需要配置为固定值train STRING train
inputTable 输入数据,即MaxCompute中的训练集表和测试集表,两张表之间使用英文逗号(,)分隔。 STRING "odps://<your_project_name>/tables/<your_train_table_name>,odps://<your_project_name>/tables/<your_test_table_name>"
firstSequence 进行文本分类的内容在输入表中对应的列名。 STRING sentence
secondSequence 进行辅助分类的文本内容在输入表中对应的列名。如果您需要提高文本分类的准确率,可以添加另外的文本相关字段进行辅助分类。例如,文本关键词。 STRING keywords
labelName 标签在输入格式中对应的列名。 STRING label
labelEnumerateValues 标签枚举值,支持以下两种方式:
  • 以英文逗号(,)分隔。
  • 一个TXT文件的OSS路径,该TXT文件中的枚举值以换行符分隔。
STRING
  • 1001,1003,1005,1007,1009
  • "oss://<your_bucket_name>/<path_to_your>/labels.txt"
sequenceLength 序列整体最大长度,范围为1~512。 INT 128 128
checkpointDir 模型存储路径。 STRING "oss://<your_bucket_name>/<path_to_your>/ckp_dir/"
batchSize 训练过程中的批处理大小。如果使用多机多卡,则表示每个GPU上的批处理大小。 INT 32 32
numEpochs 训练总Epoch的数量。 INT 1 1
distributionStrategy 分布式策略,支持以下取值:
  • MirroredStrategy:单机多卡。
  • ExascaleStrategy:多机多卡。
STRING "MirroredStrategy" "MirroredStrategy"
workerCount 分布式服务器的数量,默认值表示1个Worker。 INT 2 1
workerGPU 每个Worker下的GPU卡数量。 INT 2 1
workerCPU 每个Worker下的CPU卡数量。 INT 2 1
optimizerType 优化器类型,支持以下取值:
  • adam
  • lamb
  • adagrad
  • adadeleta
STRING "adam" "adam"
learningRate 学习率。 FLOAT 2e-5 2e-5
modelName 模型名称。 STRING text_classify_bert text_match_bert
userDefinedParameters 用户自定义参数,可以配置预训练模型pretrain_model_name_or_path。常用如下三种预训练模型:
  • pai-bert-base-zh
  • google-bert-base-zh
  • cro-roberta-tiny-zh
STRING "google-bert-base-zh"
buckets OSS Buckets信息,格式为oss://atp-modelzoo-sh.oss-cn-shanghai-internal.aliyuncs.com/?role_arn=<your_arn>,oss://<your_bucket>.<your_host>/?role_arn=<your_arn>。您需要将如下字段替换为实际值,其他部分使用上述的固定值:
  • <your_arn>:替换为您的ARN,取值与arn参数相同。
  • <your_bucket>:替换为您创建的OSS存储空间(Bucket)的名称。
  • <your_host>:替换为您OSS地域的Endpoint,取值与ossHost参数相同。
STRING oss://atp-modelzoo-sh.oss-cn-shanghai-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole,oss://tongxin-demo1.oss-cn-beijing-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
arn 权限认证。您可以在PAI-Studio项目空间的左侧导航栏,选择设置 > 基本设置,即可查看ARN。 STRING "acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
ossHost OSS地域的Endpoint。OSS地域与Endpoint的对应关系,请参见公共云下OSS Region和Endpoint对照表 STRING "oss-cn-beijing-internal.aliyuncs.com"

步骤三:评估模型

获得训练好的模型后,您可以通过模型评估的PAI命令,一键查看模型效果(例如模型预测准确率)。模型评估的输入数据及输出数据分别如下:
  • 输入:在PAI命令中,将inputTable参数配置为测试集tnews_bert_et_dev,将checkpointPath参数配置为训练好的模型的路径。
  • 输出:在运行日志Logview中可以查看评估结果。
在DataWorks的ODPS SQL节点中,执行如下PAI命令进行模型评估。
pai -name easy_transfer_app_ext
  -Dmode=evaluate
  -DinputTable="odps://pai_online_project/tables/tnews_bert_et_dev"
  -DcheckpointPath='oss://tongxin-demo1/EasyTransfer/ckp_dir/model.ckpt-2085'
  -DbatchSize=64
  -Dbuckets="oss://atp-modelzoo-sh.oss-cn-shanghai-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole,oss://tongxin-demo1.oss-cn-beijing-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -Darn="acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -DossHost="oss-cn-beijing-internal.aliyuncs.com"
该命令涉及的主要参数如下表所示,其他参数解释请参见表 2
参数 是否必选 描述 类型 示例值 默认值
mode 使用模式。进行模型评估时,需要配置为固定值evaluate STRING evaluate
inputTable 输入数据,即MaxCompute中的测试集表。 STRING "odps://pai_online_project/tables/tnews_bert_et_dev"
checkpointPath
训练好的模型的存储路径,对应模型训练PAI命令中的checkpointDir参数。但是这个参数存在如下区别:
  • checkpointDir:指定至模型文件的上层文件夹。
  • checkpointPath:需要指定到模型名称,不能只到上层文件夹。
STRING “oss://tongxin-demo1/EasyTransfer/ckp_dir/model.ckpt-2085”

步骤四:模型预测

对训练好的模型输入测试数据集或评估数据集,可以获得预测的分类结果。模型预测的输入数据和输出数据如下所示:
  • 输入:在PAI命令中,将inputTable参数配置为测试集tnews_bert_et_dev,将checkpointPath参数配置为训练好的模型的路径。
  • 输出:在PAI命令outpuTable参数配置的MaxCompute表中,输出预测结果。
在DataWorks的ODPS SQL节点中,执行如下PAI命令进行模型预测。
pai -name easy_transfer_app_ext
  -Dmode=predict
  -DinputTable="odps://pai_online_project/tables/tnews_bert_et_dev"
  -DoutputTable="odps://tongxin_demo/tables/tnews_dev_pred"
  -DfirstSequence=sentence
  -DsecondSequence=keywords
  -DappendCols=example_id,label
  -DoutputSchema=predictions,probabilities,logits
  -DcheckpointPath='oss://tongxin-demo1/EasyTransfer/ckp_dir/'
  -Dbuckets="oss://atp-modelzoo-sh.oss-cn-shanghai-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole,oss://tongxin-demo1.oss-cn-beijing-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -Darn="acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -DossHost="oss-cn-beijing-internal.aliyuncs.com"
该命令涉及的主要参数如下表所示,其他参数解释请参见表 2
参数 是否必选 描述 类型 示例值 默认值
mode 使用模式。进行模型预测时,需要配置为固定值predict STRING predict
inputTable 输入数据,即MaxCompute中的测试集表。 STRING "odps://pai_online_project/tables/tnews_bert_et_dev"
checkpointPath 训练好的模型的存储路径,与模型训练PAI命令中的checkpointDir参数取值相同。 STRING "oss://tongxin-demo1/EasyTransfer/ckp_dir/"
outputTable 预测结果输出表。 STRING "odps://tongxin_demo/tables/tnews_dev_pred"
appendCols 输入表中需要添加到输出表的列,多个列之间使用英文逗号(,)分隔。 STRING example_id,label
outputSchema 需要输出的预测值,支持输出以下三种预测值:
  • predictions:数据预测结果。
  • probabilities:该数据属于每个Label的概率。
  • logits:预测的原始值,即probabilities = softmax(logits)

通常需要同时输出以上三种预测值,多个预测值之间使用英文逗号(,)分隔。

STRING predictions,probabilities,logits

步骤五:导出模型

将训练满意的模型导出至文件夹中,以便后续将模型部署为在线服务。模型导出的输入数据和输出数据分别为:
  • 输入:在PAI命令中,将checkpointPath配置为已训练好的模型。
  • 输出:在PAI命令exportDirBase参数配置的路径下,输出导出的模型及相关配置文件。
在DataWorks的ODPS SQL节点中,执行如下PAI命令导出模型。
pai -name easy_transfer_app_ext
  -Dmode=export
  -DcheckpointPath='oss://tongxin-demo1/EasyTransfer/ckp_dir/model.ckpt-2085'
  -DexportType=app_model
  -DexportDirBase='oss://tongxin-demo1/EasyTransfer/export/'
  -Dbuckets="oss://atp-modelzoo-sh.oss-cn-shanghai-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole,oss://tongxin-demo1.oss-cn-beijing-internal.aliyuncs.com/?role_arn=acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -Darn="acs:ram::1664081xxxxxxxx:role/aliyunodpspaidefaultrole"
  -DossHost="oss-cn-beijing-internal.aliyuncs.com"
该命令涉及的主要参数如下表所示,其他参数解释请参见表 2
参数 是否必选 描述 类型 示例值 默认值
mode 使用模式。进行模型导出时,需要配置为固定值export STRING export
checkpointPath
训练好的模型的存储路径,对应模型训练PAI命令中的checkpointDir参数。但是这个参数存在如下区别:
  • checkpointDir:指定至模型文件的上层文件夹。
  • checkpointPath:需要指定到模型名称,不能只到上层文件夹。
STRING 'oss://tongxin-demo1/EasyTransfer/ckp_dir/model.ckpt-2085'
exportType 导出类型,支持以下类型:
  • app_model:导出Finetune模型自身。
  • ez_bert_feat:导出文本向量化组件所需模型。
STRING app_model
exportDirBase 导出模型的目录。 STRING "oss://<your_bucket_name>/<path_to_your>/export/"

步骤六:部署模型

  1. 打包导出的模型文件。
    将OSS输出目录export(导出模型PAI命令中的exportDirBase参数配置的目录)下的saved_model.pbvocab.txtvariables文件夹及模型目录ckp_dir下的label_mapping.json文件打包为bert_model.tar.gz。打包文件的详细信息如下图所示。打包文件
  2. 使用PAI-EAS的在线部署工具EASCMD,将bert_model.tar.gz包上传至OSS。关于EASCMD工具中的命令使用方法,请参见命令使用说明
    上传命令如下所示。
    $ eascmd64 upload bert_model.tar.gz
    该命令执行成功后,系统返回如下类似的模型地址。
    oss://eas-model-beijing/16640818xxxxxxxxx/bert_model.tar.gz
  3. 创建如下服务描述文件service_desc_json.json
    {
      "name": "easynlp_tongxin_demo1",
      "generate_token": "true",
      "model_path": "oss://eas-model-beijing/16640818xxxxxxxxx/bert_model.tar.gz",
      "processor": "easy_nlp_gpu_tf1.12",
      "model_config": "{\"type\":\"text_classify_bert\"}",
      "metadata": {
        "resource": "eas-r-a47xufufi6yxxxxx",
        "cuda": "9.0",
        "instance": 1,
        "memory": 4000,
        "gpu": 1,
        "cpu": 4,
        "rpc.worker_threads" : 5
      }
    }
    该文件的核心参数如下(其他参数的含义请参见创建服务):
    • name:在线服务的名称,您可以自定义。
    • model_path:上传打包的模型文件后,系统返回的模型地址。
    • processor:本文的模型需要使用PAI-EAS提供的EasyNLP Processor进行部署,该Processor Code为easy_nlp_gpu_tf1.12。关于PAI-EAS提供的预置Processor及其Processor Code对应关系请参见预置Processor使用说明
    • resource:推荐使用PAI-EAS专属资源组部署模型服务,该参数为部署服务的专属资源组名称。
  4. 在EASCMD工具中,执行以下命令部署模型。
    $ eascmd64 create service_desc_json.json

步骤七:调试模型服务

您可以通过如下任何一种方式调式模型服务:
通过PAI-EAS控制台在线调用服务的详细步骤如下。
  1. 进入PAI EAS模型在线服务页面。
    1. 登录PAI控制台
    2. 在左侧导航栏,选择模型部署 > 模型在线服务(EAS)
  2. PAI EAS模型在线服务页面,单击上一步中已部署服务操作列下的在线调试
  3. 在调试页面的在线调试请求参数区域,配置参数。
    参数 描述
    接口地址 系统自动填入,无需手动配置。
    Token 系统自动填入,无需手动配置。
    Request Body 请求数据的样式如下所示。
    {"id": "110","first_sequence": "想赢勇士想到发疯?格林新发现吓呆众人","sequence_length": 128}
  4. 单击发送请求,即可在调试信息区域查看预测结果。在线调试结果
编写Python脚本,通过公网地址调用模型服务,详情请参见公网地址调用。通过Python脚本批量调试服务的详细步骤如下。
  1. 进入PAI EAS模型在线服务页面。
    1. 登录PAI控制台
    2. 在左侧导航栏,选择模型部署 > 模型在线服务(EAS)
  2. PAI EAS模型在线服务页面,单击已部署服务服务方式列下的调用信息
  3. 调用信息对话框的公网地址调用页签,查看公网调用的访问地址Token
  4. 创建如下Python脚本eas_bert_demo.py
    #!/usr/bin/env python
    from eas_prediction import PredictClient
    from eas_prediction import StringRequest
    if __name__ == '__main__':
        #下面的client = PredictClient()入参源于公网调用的访问地址。
        client = PredictClient('http://1664081855xxxxxx.cn-beijing.pai-eas.aliyuncs.com/api/predict/easynlp_gpu_demo1')
        #Token可以在公网地址调用信息中获取。
        client.set_token('MGJmODcxY2Q4ZDc2NGNlZDIxMjJhNGE0Zmxxxxxxxxxxxxxxx')    
        client.init()
        request = StringRequest('[{"id": "110","first_sequence": "想赢勇士想到发疯?格林新发现吓呆众人","sequence_length": 128},{"id": "112","first_sequence": "互金协会成立个人信用信息共享平台","sequence_length": 128}]')    
        for x in range(0, 1):
            resp = client.predict(request)
            print(resp)
  5. eas_bert_demo.py脚本上传至您的任意环境,并在脚本上传后的当前目录执行如下调用命令。
    $ python3 eas_bert_demo.py

步骤八:监控服务指标

调用模型服务后,您可以查看模型调用的相关指标水位,包括QPS、RT、CPU、GPU及Memory。

  1. 进入PAI EAS模型在线服务页面。
    1. 登录PAI控制台
    2. 在左侧导航栏,选择模型部署 > 模型在线服务(EAS)
  2. PAI EAS模型在线服务页面,单击已调用服务服务监控列下的服务监控图标图标。
  3. 服务监控页签,即可查看模型调用的指标水位。
    从服务监控的水位图中可以看到部署的BERT文本分类模型的时延在30 ms左右。RT图如果您需要在准确率损失较小的情况下,提升调用效率,建议模型训练时,配置pretrain_model_name_or_path参数为cro-roberta-tiny-zh模型,可以将时延降低到10 ms。