资讯 文档
技术能力
语音技术
文字识别
人脸与人体
图像技术
语言与知识
视频技术

实战演练:使用文心训练模型

这里我们以一个在智能对话场景中识别用户情绪的任务为例,来介绍如何使用文心进行模型训练。

分析场景、选定任务

  • 任务目标:识别智能对话场景中用户的情绪,针对智能对话场景中的用户文本,自动判断该文本的情绪类别并给出相应的置信度,情绪类型分为积极和消极两种。
  • 任务数据:未经处理的智能对话场景中的用户文本如下所示:
你的这个建议不错,谢谢你。
你这是什么意思?是不是没听懂我在问什么。
你们这个产品怎么回事?怎么一用就死机?
  • 任务分析

    • 经过分析上述目标和数据,可以发现这是一个经典的NLP文本二分类任务。
    • 可以通过文心提供的BOW文本分类模型以及ERNIE预训练模型来实现较为高效的对话情感检测(ERNIE预训练模型性能优于BOW文本分类模型)。
    • 文心的文本分类任务在./tasks/text_classification/目录下。

环境安装

环境安装与配置

BOW文本分类模型

准备数据

  • 根据上述场景,我们现有的数据集为未经处理的原始数据,无法直接用于文心文本分类任务,因此我们需要做以下两件事:

    • 查看文心文本分类任务非ERNIE示例数据集,了解数据集格式;
    • 修改我们现有的数据集格式,保持与文心示例数据集格式统一。

查看BOW模型(非ERNIE)数据集示例

  • 文心文本分类任务非ERNIE的训练数据、测试数据、验证数据和预测数据分别存放在./data文件夹中的train_data、test_data、dev_data和predict_data文件夹下,对应的示例词典存放在dict文件夹下。在真实训练场景时,请将数据放置上述位置。
  • 示例数据为二分类,标签标注分别为0和1,文本经过分词预处理。
  • 训练数据、测试数据和验证数据格式相同。数据分为两列,第一列为分词处理后的文本,第二列为标签。列与列之间用\t进行分隔,如下所示:
 房间 太 小 。 其他 的 都 一般 。 。 。 。 。 。 。 。 。   0
LED屏 就是 爽 , 基本 硬件 配置 都 很 均衡 , 镜面 考 漆 不错 , 小黑 , 我喜欢 。   1
差 得 要命 , 很大 股霉味 , 勉强 住 了 一晚 , 第二天 大早 赶紧 溜   0

预测数据没有标签预占位,其格式如下所示:

USB接口 只有 2个 , 太 少 了 点 , 不能 接 太多 外 接 设备 ! 表面 容易 留下 污垢 !
平时 只 用来 工作 , 上 上网 , 挺不错 的 , 没有 冗余 的 功能 , 样子 也 比较 正式 !
还 可以 吧 , 价格 实惠   宾馆 反馈   2008417日   :   谢谢 ! 欢迎 再次 入住 其士 大酒店 。

词表分为两列,第一列为词,第二列为id(从0开始),列与列之间用\t进行分隔。文心的词表中[PAD]、[CLS]、[SEP]、[MASK]、[UNK]这5个词是必须要有的,若用户自备词表,需保证这5个词是存在的。部分词表示例如下所示:

[PAD]    0
[CLS]    1
[SEP]    2
[MASK]    3
[UNK]    4
郑重    5
天空    6
工地    7
神圣    8

处理现有数据

  • 首先,对数据进行分词、构建词表等预处理,可以使用文心提供的小工具。
  • 对数据进行分割,根据需要留下预测数据后,其余样本按照6:2:2的比例分割为训练集、测试集和验证集。
  • 根据上述场景,我们需要对训练集、测试集和验证集进行标注,0表示“消极”,1表示“积极”。
  • 标注结束后,我们将预处理好的各数据集分别存放于文心文本分类任务非ERNIE的示例数据文件夹下。
  • 将准备好的词表文件vocab.txt放到文心文本分类任务的dict文件夹下面,或者你可以选择采用文心提供的示例词典。

配置参数:通过json进行模型配置

文心中模型的训练、预测、评估等都是通过Python脚本来运行的,需要的参数都是配置在json文件中,运行过程中传入配置好的json文件,文心会自动解析json文件,解析出各个模块需要用的参数,根据这些参数实例化需要用到的对象实例,具体原理详见文心中的注册机制。 json配置文件主要分为三个部分:dataset_reader(数据部分)、model(网络部分)、trainer或inference(执行部分),在模型训练的时候,json文件中需要配置dataset_reader、model和trainer这三个部分;在预测推理的时候,json文件中需要配置dataset_reader、inference这两个部分。以下部分就以BOW文本分类模型为例,着重介绍文心中的json配置文件。 BOW中文文本分类模型训练的预置json文件为./examples/目录下的cls_bow_ch.json,我们主要对其中的三个部分,即dataset_reader部分、model部分和trainer部分进行配置。

  • dataset_reader部分:用于配置模型训练或者预测时的数据相关配置,训练任务的dataset_reader中必须有train_reader、test_reader、dev_reader,预测推理任务的dataset_reader仅需要predict_reader。以下为cls_bow_ch.json中抽取出来的dataset_reader部分配置,通过注释说明。
{
      "dataset_reader": {
        "train_reader": {   ## 训练、验证、测试各自基于不同的数据集,数据格式也可能不一样,可以在json中配置不同的reader,此处为训练集的reader。
          "name": "train_reader",
          "type": "BasicDataSetReader",  ## 采用BasicDataSetReader,其封装了常见的读取csv、txt文件、组batch等操作。这里的取值是对应dataset_reader的类名,关于各个dataset_reader的区别详见http://wiki.baidu.com/display/TOne/6.Reader
          "fields": [  ## 域(field)是文心的高阶封装,对于同一个样本存在不同域的时候,不同域有单独的数据类型(文本、数值、整型、浮点型)、单独的词表(vocabulary)等,可以根据不同域进行语义表示,如文本转id等操作,field_reader是实现这些操作的类。
            {
              "name": "text_a",   ## 文本分类只有一个文本特征域,命名为"text_a""data_type": "string",  ## data_type定义域的数据类型,文本域的类型为string,整型数值为int,浮点型数值为float。
              "reader": {  
                "type": "CustomTextFieldReader"  ## 采用针对文本域的通用reader "CustomTextFieldReader"。数值数组类型域为"ScalarArrayFieldReader",数值标量类型域为"ScalarFieldReader",这里的取值是对应FieldReader的类名,关于各个FieldReader的区别详见http://wiki.baidu.com/display/TOne/6.Reader
              },
              "tokenizer": {
                "type": "CustomTokenizer",  ## 指定该文本域的tokenizer为CustomTokenizer,type的取值是对应Tokenizer的类名,关于各个Tokenizer的区别详见http://wiki.baidu.com/display/TOne/6.Reader
                "split_char": " ",  ## 非Ernie任务需要自己切词,切词之后的明文使用的分隔符在这里设置,默认是通过空格区分不同的token。
                "unk_token": "[UNK]",  ## unk标记为"[UNK]", 即词表之外的token所对应的默认id,unk必须是词表文件中存在的token。
                "params": null   ## 如果需要一些额外的参数传入tokenizer的时候可以使用该字段
              },
              "need_convert": true, ## "need_convert"true说明数据格式是明文字符串,需要通过词表转换为id。
              "vocab_path": "./dict/vocab.txt", ## 指定该文本域的词表,"need_convert"true时一定要设置
              "max_seq_len": 512,  ## 设定当前域转为id之后的最大长度
              "truncation_type": 0, ## 选择文本超长截断的策略,0为从头开始到最大长度截断,1为从头开始到max_len-1的位置截断,末尾补上最后一个id(词或字),2为保留头和尾两个位置,然后按从头开始到最大长度方式截断。
              "padding_id": 0  ## 设定padding时对应的id值,文心内部会按batch中的最长文本大小对整个batch中的数据进行padding补齐。
            },     ## 如果每一个样本有多个特征域(文本类型、数值类型均可),可以仿照前面对每个域进行设置,依次增加每个域的配置即可。此时样本的域之间是以\t分隔的。
            {
              "name": "label",   ## 标签也是一个单独的域,在当前例子中命名为"label"。如果多个不同任务体系的标签存在于多个域中,则可实现最基本的多任务学习。
              "data_type": "int",  ## 标签是整型数值。
              "reader": {
                "type": "ScalarFieldReader"   ## 整型数值域的reader为"ScalarFieldReader"},
              "tokenizer": null,   ## 如果你的label是明文文本,且需要分词的话,这里就需要配置对应的tokenizer,规则如上方文本域的tokenizer配置
              "need_convert": false,  ## "need_convert"true说明数据格式是明文字符串,需要通过词表转换为id。
              "vocab_path": "",  ## ”need_convert“为true的时候需要填词表路径	。
              "max_seq_len": 1,  ## 设定每个域的最大长度,当前例子中的label域是一个int数值,所以最大长度是1"truncation_type": 0,  ## 超过max_seq_len长度之后的截断策略,同上。
              "padding_id": 0,   ## 设定padding时对应的id值。
              "embedding": null   ## 历史遗留参数,设置为null即可。
            }
          ],
          "config": {
            "data_path": "./data/train_data",    ## 训练数据train_reader的数据路径,写到文件夹目录。
            "shuffle": false,   ## 数据在读取过程中是否需要打乱顺序。
            "batch_size": 8,    ## 超参数之一,表示每个step训练多少个样本。
            "epoch": 10,        ## 超参数之一,表示这个数据集中的数据会被重复训练多少轮。
            "sampling_rate": 1.0  ## 数据集的采样率,文心预留参数,暂时不起作用,后续版本会升级。
          }
        },
        "test_reader": {                                    ## 若要评估测试集,需配置test_reader,其配置方式与train_reader类似, 需要注意的是shuffle参数要设置为false,epoch参数必须是1。
        ……
        },
    	"dev_reader": {      ## 若要评估验证集,需配置dev_reader,其配置方式与test_reader类似,需要注意的是shuffle参数要设置为false,epoch参数必须是1。
        ……
        },
      ……
    }
  • model部分:用于配置模型训练时的预置网络,包括预置网络的类别及其优化器的参数等。以下为cls_bow_ch.json中抽取出来的model部分配置,通过注释说明。
{
...
"model": {
  "type": "BowClassification",  ## 文心采用模型(models)的方式定义神经网络的基本操作,本例采用预置的模型BowClassification实现文本分类,具体网络可参考models目录。
  "is_dygraph": 1,             ## 区分动态图模型和静态图模型,1表示动态图,0表示静态图
  "optimization": {
    "learning_rate": 2e-05    ## 预置模型的优化器所需的参数配置,如学习率等。
  },
  "vocab_size": 33261,       ## 该模型(model)使用的词表大小,必填参数。
  "num_labels": 2            ## 该分类模型的类别数目是多少,必填参数,不填则默认是二分类
},
...

trainer部分:用于配置模型训练的启动器,包括保存模型时的间隔步数、进行测试集或验证集评估的间隔步数等。以下为cls_bow_ch.json中抽取出来的trainer部分配置,通过注释说明。

{
      ...
  "trainer": {
    "type": CustomDynamicTrainer,                               ## 使用哪个trainer对象,由对应的task中trainer目录下的trainer类决定,主要是区分使用动态图trainer还是静态图trainer,与model中的is_dygraph参数取值要对应。
    "PADDLE_PLACE_TYPE": "CPU",      ## 运行的硬件环境,CPU机器填CPU,GPU机器填GPU。
        "PADDLE_IS_FLEET": 0,                         ## 是否使用FLEET训练方式,1表示使用,0表示不使用,目前文心的单机多卡和多机多卡都采用的是FLEET方式,所以在运行多卡任务时记得将改参数设置为1,并配合fleetrun命令进行启动。
    "train_log_step": 20,                              ## 训练时打印训练日志的间隔步数。
    "is_eval_dev": 0,                                  ## 是否在训练的时候评估验证集,如果取值为1,则一定需要配置dev_reader及其数据路径。
    "is_eval_test": 1,                                 ## 是否在训练的时候评估测试集,如果取值为1,则一定需要配置test_reader及其数据路径。
    "eval_step": 100,                                  ## 进行测试集或验证集评估的间隔步数。
    "save_model_step": 10000,                          ## 保存模型时的间隔步数,建议设置为eval_step的整数倍。
    "load_parameters": "",                             ## 加载包含各op参数值的训练好的模型,用于热启动。此处填写checkpoint路径。不填则表示不使用热启动。
    "load_checkpoint": "",                             ## 加载包含学习率等所有参数的训练模型,用于热启动。此处填写checkpoint路径。不填则表示不使用热启动。
    "pre_train_model": [],   ## 加载预训练模型的参数,ERNIE任务的必填参数,非ERNIE任务将当前参数置为[]即可。                   
    "output_path": "./output/cls_bow_ch"           ## 保存模型的输出路径,如置空或者不配置则默认输出路径为"./output""extra_param": {                                   ## 除核心必要信息之外,需要额外标明的参数信息,比如一些meta信息可以作为日志统计的关键字。
          "meta":{
            "job_type": "text_classification"
          }
    }
  }

    }

启动训练

  • 将数据集存放妥当,并配置好cls_bow_ch.json,返回至./text_classification目录下,我们就可以运行模型训练的命令:python run_trainer.py ,如下所示,使用基于BOW的中文文本分类模型在训练集上进行本地模型训练。
# Bow 中文文本分类模型
# 基于json实现预置网络训练。其调用了配置文件./examples/cls_bow_ch.json
# 单卡训练
python run_trainer.py --param_path ./examples/cls_bow_ch.json
# 如果需要使用多卡训练,则使用以下命令
# --gpus参数指定的显卡号需要是$CUDA_VISIBLE_DEVICES的子集
fleetrun --gpus=0,1 run_trainer.py --param_path ./examples/cls_bow_ch.json
  • 训练运行的日志会自动保存在./log/test.log文件中,内容大致如下所示:
INFO: 02-24 08:00:35: base_dataset_reader.py:96 * 139822175426304 set data_generator and start.......
INFO: 02-24 08:00:35: custom_trainer.py:64 * 139822175426304 epoch 2 progress 176/199 pyreader queue size 50                                                          ## epoch:当前训练轮次;progress:当前训练进度;pyreader queue size:当前pyreader队列大小
DEBUG: 02-24 08:00:35: bow_classification.py:148 * 139822175426304 phase = training acc = 0.75 precision = 0.375 step = 20 time_cost = 0.499283075333                 ## phase:该log类型,train为训练log,test为测试log,dev为评估log;acc、precision等:评估指标;step:当前训练步数;time_cost:当前batch所消耗的时间
...
INFO: 02-24 08:00:38: base_dataset_reader.py:96 * 139822175426304 set data_generator and start.......
DEBUG: 02-24 08:00:38: bow_classification.py:152 * 139822175426304 phase = test acc = 0.53 precision = 0.267676767677 time_cost = 0.105578899384                                  
...
INFO: 02-24 08:00:41: custom_trainer.py:64 * 139822175426304 epoch 9 progress 198/199 pyreader queue size 9
DEBUG: 02-24 08:00:41: bow_classification.py:148 * 139822175426304 phase = training acc = 0.75 precision = 0.375 step = 240 time_cost = 0.474550008774
INFO: 02-24 08:00:42: custom_trainer.py:104 * 139822175426304 Final test result:                                                                                        ## 此次运行结束时的最终评估
INFO: 02-24 08:00:42: base_dataset_reader.py:96 * 139822175426304 set data_generator and start.......
DEBUG: 02-24 08:00:42: bow_classification.py:152 * 139822175426304 phase = test acc = 0.53 precision = 0.267676767677 time_cost = 0.0935051441193
INFO: 02-24 08:00:42: run_trainer.py:96 * 139822175426304 end of run train and eval .....
INFO: 02-24 08:00:42: run_trainer.py:98 * 139822175426304 os exit.
  • 训练中以及结束后产生的模型文件会默认保存在./output/cls_ bow_ch/目录下,其中save_inference_model/文件夹会保存用于预测的模型文件,save_checkpoint/文件夹会保存用于热启动的模型文件,动态图和静态图的checkpoints文件格式不一样,需要注意,结果如下所示:

    • 动态图:
├── save_checkpoints            ## 神经网络中的所有参数文件,可以用来做热启动。
│   └── checkpoints_step_251
│       ├── model.meta          ## meta文件,存放了文心自定义的网络基本介绍信息。
│       ├── wenxin.pdopt        ## 优化器学习率等参数信息
│       └── wenxin.pdparams     ## 网络参数信息
└── save_inference_model
    └── inference_step_251
        ├── infer_data_params.json ## 模型预测过程中需要解析的字段,模型训练过程中自动生成,模型预测过程中自动解析。其写入内容由model文件(组网文件)中的forward方法的返回值决定。
        ├── model.meta
        ├── wenxin.pdiparams   ## 经过优化裁剪之后的参数文件(所有参数压缩保存在一个文件中)
        └── wenxin.pdmodel     ## paddle框架保存出来的模型网络结构文件
  • 静态图:
├── save_checkpoints
│   ├── checkpoints_step_251      ## 神经网络中的所有参数文件,可以用来做热启动。
│        │   ├── embedding_0.w_0
│        │   ├── embedding_0.w_0_beta1_pow_acc_0
│        │   ├── ....
│        │   ├── fc_0.b_0
│        │   ├── ....
│        │   ├── model.meta          ## meta文件,存放了文心自定义的网络基本介绍信息。
│        │   ├── ....
├── save_inference_model
│        ├── inference_step_251
│        │   ├── infer_data_params.json  ## 模型预测过程中需要解析的字段,模型训练过程中自动生成,模型预测过程中自动解析。其写入内容由model文件(组网文件)中的forward方法的返回值决定。
│        │   ├── wenxin.pdmodel    ## paddle框架保存出来的模型网络结构文件
│        │   ├── model.meta  ## meta文件,存放了文心自定义的网络基本介绍信息。同checkpoints中的model.meta
│         │   ├── wenxin.pdiparams   ## 经过优化裁剪之后的参数文件(所有参数压缩保存在一个文件中)

ERNIE预训练模型

ERNIE预训练模型的选择与配置

  • ERNIE版本的选择:为方便起见,我们先使用ernie2.0作为预训练模型,结合BOW模型来提升我们的分类效果。若想查看不同版本ERNIE之间的差别,请移步ERNIE简介
  • ERNIE2.0的下载与配置

    • 通过运行下述脚本下载ERNIE2.0的预训练参数文件。
# ernie_2.0_base 模型下载
# 进入models_hub目录
cd wenxin_appzoo/models_hub/
# 运行下载脚本
sh download_ernie_2.0_base_ch.sh
  • 下载完成后,修改cls_ernie_fc_ch.json中的dataset_reader、model和trainer的部分配置。

    • dataset_reader部分:
{  ## 配置情况大体上与上述的非ERNIE BOW模型一致,仅标注不同的地方
"dataset_reader": {
  "train_reader": {
    "name": "train_reader",
    "type": "BasicDataSetReader",
    "fields": [
      {
        "name": "text_a",
        "data_type": "string",
        "reader": {
          "type": "ErnieTextFieldReader"   ## 使用ERNIE特有的FieldReader
        },
        "tokenizer": {
          "type": "FullTokenizer",   ## 使用FullTokenizer按字进行切分
          "split_char": " ",
          "unk_token": "[UNK]"
        },
        "need_convert": true,
        "vocab_path": "../model_files/dict/vocab_ernie_2.0_base_ch.txt", ## 设置ERNIE模型对应的词表文件
        "max_seq_len": 512, ## 最大文本长度,不能超过512
        "truncation_type": 0,
        "padding_id": 0,
        "embedding": null
      },
      {
        "name": "label",
        "data_type": "int",
        "reader": {
          "type": "ScalarFieldReader"
        },
        "tokenizer": null,
        "need_convert": false,
        "vocab_path": "",
        "max_seq_len": 1,
        "truncation_type": 0,
        "padding_id": 0,
        "embedding": null
      }
    ],
    "config": {
      "data_path": "./data/train_data",
      "shuffle": false,
      "batch_size": 8,
      "epoch": 5,
      "need_data_distribute": false,
      "need_generate_examples": false
    }
  },
 "test_reader": {                                    ## 若要评估测试集,需配置test_reader,其配置方式与train_reader类似, 需要注意的是shuffle参数要设置为false,epoch参数必须是1。
    ……
    },
"dev_reader": {      ## 若要评估验证集,需配置dev_reader,其配置方式与test_reader类似,需要注意的是shuffle参数要设置为false,epoch参数必须是1。
    ……
    },
  ……
}
  • model部分
{
...  ## 配置情况大体上与上述的非ERNIE BOW模型一致,仅标注不同的地方
"model": {
      "type": "ErnieClassification",  ## 对应的模型网络类名为
            "is_dygraph": 1,             
    "optimization": { ## 优化器设置,文心ERNIE推荐的默认设置。
      "learning_rate": 5e-05,
        "use_lr_decay": true,
        "warmup_steps": 0,
        "warmup_proportion": 0.1,
        "weight_decay": 0.01,
        "use_dynamic_loss_scaling": false,
        "init_loss_scaling": 128,
        "incr_every_n_steps": 100,
        "decr_every_n_nan_or_inf": 2,
        "incr_ratio": 2.0,
        "decr_ratio": 0.8
    },
    "embedding": {     ## ERNIE中的embedding参数设置,必填参数。
      "type": "ErnieTokenEmbedding",  ## embedding类型,务必设置为ErnieTokenEmbedding
      "emb_dim": 768,  ## 当前ERNIE模型的词向量维度,不同版本ERNIE维度不同,具体数值参考对应的config.json中的emb_size参数。
      "config_path": "../model_files/config/ernie_2.0_base_ch_config.json",  ## 当前ERNIE模型的配置文件,下载需要的ERNIE模型压缩包即可看到。
      "other": ""   ## 预留字段,用来传递一些额外信息。
    },
    "num_labels": 2
  },
...
}
  • trainer部分
{
  ...
  "trainer": {
              "type": "CustomDynamicTrainer",                          
    "PADDLE_PLACE_TYPE": "GPU",                               
              "PADDLE_IS_FLEET": 0,                               ## 是否使用分fleet。
    "train_log_step": 20,                ## 训练时打印训练日志的间隔步数,同上。
    "is_eval_dev": 0,                                  ## 是否在训练的时候评估开发集,如果取值为1,则一定需要配置dev_reader及其数据路径,同上。
    "is_eval_test": 1,                                 ## 是否在训练的时候评估测试集,如果取值为1,则一定需要配置test_reader及其数据路径,同上。
    "eval_step": 100,                                  ## 进行测试集或验证集评估的间隔步数,同上。
    "save_model_step": 10000,                          ## 保存模型时的间隔步数,建议设置为eval_step的整数倍,同上。
    "load_parameters": "",                             ## 加载包含各op参数值的训练好的模型,用于热启动。此处填写checkpoint路径。不填则表示不使用热启动,同上。
    "load_checkpoint": "",                             ## 加载包含学习率等所有参数的训练模型,用于热启动。此处填写checkpoint路径。不填则表示不使用热启动,同上。
    "pre_train_model": [                               ## 加载预训练模型,ERNIE任务的必填参数,非ERNIE任务将当前参数置为[]即可。
        {
              "name": "ernie_2.0_base_ch",               ## 预训练模型的名称name
              "params_path": "../model_files/ernie_2.0_base_ch_dir/params"   ## 预训练模型的目录params_path
        }
    ],                             
    "output_path": "./output/cls_ernie_fc_ch"           ## 保存模型的输出路径,如置空或者不配置则默认输出路径为"./output",同上。
    "extra_param": {                                   ## 除核心必要信息之外,需要额外标明的参数信息,比如一些meta信息可以作为日志统计的关键字,同上。
          "meta":{
            "job_type": "text_classification"
          }
    }
  }
}

数据准备

  • 若使用ernie作为预训练模型,则所需数据集与非ernie的区别为文本不需要分词,且无需额外准备词典。因此我们需要使用处理之前分好的词的数据。

启动训练

  • 将数据集存放妥当,在./examples配置好cls_ernie_fc_ch.json,然后回到文本分类任务的主目录./text_classification下我们就可以运行如下命令,使用带ernie2.0的中文文本分类模型在训练集上进行本地模型训练。
## 选择ernie相关json即可实现
python run_trainer.py --param_path ./examples/cls_ernie_fc_ch.json
# 如果需要使用多卡训练,则使用以下命令
# --gpus参数指定的显卡号需要是$CUDA_VISIBLE_DEVICES的子集
export CUDA_VISIBLE_DEVICES=0,1
fleetrun --gpus=0,1 run_trainer.py --param_path ./examples/cls_ernie_fc_ch.json
上一篇
目录结构
下一篇
实战演练:使用动态图训练