基于 Pair-wise 和 CrossEncoder 训练单塔模型

本文分享自华为云社区《语义检索系统排序模块:基于ERNIE-Gram的Pair-wise和基于RocketQA的CrossEncoder训练单塔模型》,作者: 汀丶。
文本匹配任务数据每一个样本通常由两个文本组成(query,title)。类别形式为 0 或 1,0 表示 query 与 title 不匹配; 1 表示匹配。
基于单塔 Point-wise 范式的语义匹配模型 ernie_matching: 模型精度高、计算复杂度高, 适合直接进行语义匹配 2 分类的应用场景。
基于单塔 Pair-wise 范式的语义匹配模型 ernie_matching: 模型精度高、计算复杂度高, 对文本相似度大小的序关系建模能力更强,适合将相似度特征作为上层排序模块输入特征的应用场景。
基于双塔 Point-Wise 范式的语义匹配模型 这 2 种方案计算效率更高,适合对延时要求高、根据语义相似度进行粗排的应用场景。
- Pointwise:输入两个文本和一个标签,可看作为一个分类问题,即判断输入的两个文本是否匹配。
- Pairwise:输入为三个文本,分别为 Query 以及对应的正样本和负样本,该训练方式考虑到了文本之间的相对顺序。
- 单塔:先将输入文本合并,然后输入到单一的神经网络模型。
- 双塔:对输入文本分别进行编码成固定长度的向量,通过文本的表示向量进行交互计算得到文本之间的关系。
1.排序模型任务简介和要求
1.1 技术方案和评估指标
- 技术方案 
双塔模型,使用 ERNIE-Gram 预训练模型,使用 margin_ranking_loss 训练模型。
- 评估指标 
(1)采用 AUC 指标来评估排序模型的排序效果。
效果评估先看
 
 1.2 环境依赖和安装说明
环境依赖
- python >= 3.7 
- paddlepaddle >= 2.3.7 
- paddlenlp >= 2.3 
- pandas >= 0.25.1 
- scipy >= 1.3.1 
1.3 代码结构
项目代码结构及说明:
1.4 数据介绍
- 数据集说明 
样例数据如下:
2.基于 ERNIE-Gram 模型训练
排序模型下载链接:
 
 - 训练环境说明 NVIDIA Driver Version: 440.64.00Ubuntu 16.04.6 LTS (Docker)Intel® Xeon® Gold 6148 CPU @ 2.40GHz 
2.1 单机单卡训练/单机多卡训练
这里采用单机多卡方式进行训练,通过如下命令,指定 GPU 0,1,2,3 卡, 基于 ERNIE-Gram 训练模型,数据量比较大,需要 20 小时 10 分钟左右。如果采用单机单卡训练,只需要把--gpu参数设置成单卡的卡号即可
训练的命令如下:
2.1.1 推荐系统中常用的两种优化损失函数的机器学习范式:pointwise loss 和 pairwise loss
 
 - 精排简介 
Learning to Rank (LTR)是一类技术方法,主要利用机器学习算法解决实际中的排序问题。传统的机器学习主要解决的问题是一个分类或者回归问题,比如对一个样本数据预测对应的类别或者预测一个数值分值。而 LTR 解决的是一个排序问题,对一个 list 的 item 进行一个排序,所以 LTR 并不太关注这个 list 的每个 item 具体得多少分值,更关注所有 item 的相对顺序。排序通常是信息检索的核心成分,所以 LTR 最常见的应用是搜索场景,对召回的 document 进行排序。
- Pointwise 方法 
Pointwise 方法是通过近似为回归问题解决排序问题,输入的单条样本为得分 - 文档,将每个查询 - 文档对的相关性得分作为实数分数或者序数分数,使得单个查询 - 文档对作为样本点 (Pointwise 的由来),训练排序模型。预测时候对于指定输入,给出查询 - 文档对的相关性得分。
pointwise loss :
最小化预测输出与目标值之间的平分损失,具体处理是在处理负样本时:把未观察到的实体(即 user 与 item 没有交互)当作负样本,或者从未观察到的实体中采样负样本。
- Pairwise 方法 
Pairwise 方法是通过近似为分类问题解决排序问题,输入的单条样本为标签 - 文档对。对于一次查询的多个结果文档,组合任意两个文档形成文档对作为输入样本。即学习一个二分类器,对输入的一对文档对 AB(Pairwise 的由来),根据 A 相关性是否比 B 好,二分类器给出分类标签 1 或 0。对所有文档对进行分类,就可以得到一组偏序关系,从而构造文档全集的排序关系。该类方法的原理是对给定的文档全集 S,降低排序中的逆序文档对的个数来降低排序错误,从而达到优化排序结果的目的。
pairwise loss :
最大化观察到的(即正样本)预测输出和未观察到的(负样本)的预测输出的边缘,表现为观察到的实体得分排名高于未观察到的实体。
 
 2.1.2 深度学习框架中的 Ranking Loss 层
- paddlepaddle 
margin_ranking_loss:计算输入 input,other 和 标签 label 间的 margin rank loss 损失。更多内容进行文章跳转看 api 文档
- Caffe 
Constrastive Loss Layer. 限于 Pairwise Ranking Loss 计算. 例如,可以用于训练 Siamese 网络。
PyCaffe Triplet Ranking Loss Layer. 用来训练 triplet 网络,by David Lu。
- PyTorch 
CosineEmbeddingLoss. 使用余弦相似度的 Pairwise Loss。输入是一对二元组,标签标记它是一个正样本对还是负样本对,以及边距 margin。
MarginRankingLoss. 同上, 但使用欧拉距离。
TripletMarginLoss. 使用欧拉距离的 Triplet Loss。
进入 Loss Functions 查看具体没课函数
- TensorFlow 
contrastive_loss. Pairwise Ranking Loss.
triplet_semihard_loss. 使用 semi-hard 负采样的 Triplet loss。
更多内容参考:
- 推荐系统[四]:精排-详解排序算法LTR (Learning to Rank): poitwise, pairwise, listwise相关评价指标,超详细知识指南。 - 推荐系统[4.1]:Ranking Loss 函数:度量学习、Siamese 和 triplet 网络、RankNet、pair-wise、List-wise loss以及在深度学习框架中loss设计 
参数说明:
- – - margin, default=0.2, type=float, help="Margin for pos_score and neg_score.- – - train_file, type=str, required=True, help="The full path of train file- – - test_file, type=str, required=True, help="The full path of test file- – - save_dir, default=’./checkpoint’, type=str, help="The output directory where the model checkpoints will be written.- – - max_seq_length, default=128, type=int, help="The maximum total input sequence length after tokenization. Sequences longer than this will be truncated, sequences shorter will be padded.- – - batch_size, default=32, type=int, help="Batch size per GPU/CPU for training.- – - learning_rate, default=5e-5, type=float, help="The initial learning rate for Adam.- – - weight_decay, default=0.0, type=float, help="Weight decay if we apply some.- – - epochs, default=3, type=int, help="Total number of training epochs to perform.- – - eval_step, default=200, type=int, help="Step interval for evaluation.- – - save_step, default=10000, type=int, help="Step interval for saving checkpoint.- – - warmup_proportion, default=0.0, type=float, help="Linear warmup proportion over the training process.- – - init_from_ckpt, type=str, default=None, help="The path of checkpoint to be loaded.- – - model_name_or_path, default=“ernie-3.0-medium-zh”, help="The pretrained model used for training- – - seed, type=int, default=1000, help="Random seed for initialization.- – - device, choices=[‘cpu’, ‘gpu’], default=“gpu”, help="Select which device to train model, defaults to gpu.
部分结果展示:
2.1.3 更多 ERNIE 3.0 模型选择
官网链接:https://github.com/PaddlePaddle/PaddleNLP/tree/develop/model_zoo/ernie-3.0
- 更多技术细节可以参考论文:ERNIE-Tiny: A Progressive Distillation Framework for Pretrained Transformer CompressionERNIE 3.0 Titan: Exploring Larger-scale Knowledge Enhanced Pre-training for Language Understanding and Generation 
 
 下表汇总介绍了目前 PaddleNLP 支持的 ERNIE 模型对应预训练权重。
 
  
 2.2 模型评估
在排序阶段使用的指标为AUC,AUC反映的是分类器对样本的排序能力,如果完全随机得对样本分类,那么AUC应该接近0.5。分类器越可能把真正的正样本排在前面,AUC越大,分类性能越好。
部分结果展示:
2.3 模型预测
准备预测数据:待预测数据为 tab 分隔的 tsv 文件,每一行为 1 个文本 Pair,和文本 pair 的语义索引相似度,部分示例如下:
部分效果展示:
2.3.1 使用 FastTokenizer 加速
FastTokenizer 是飞桨提供的速度领先的文本处理算子库,集成了 Google 于 2021 年底发布的 LinMaxMatch 算法,该算法引入 Aho-Corasick 将 WordPiece 的时间复杂度从 O(N2) 优化到 O(N),已在 Google 搜索业务中大规模上线。FastTokenizer 速度显著领先,且呈现 batch_size 越大,优势越突出。例如,设置 batch_size = 64 时,FastTokenizer 切词速度比 HuggingFace 快 28 倍。
在 ERNIE 3.0 轻量级模型裁剪、量化基础上,当设置切词线程数为 4 时,使用 FastTokenizer 在 NVIDIA Tesla T4 环境下在 IFLYTEK (长文本分类数据集,最大序列长度为 128)数据集上性能提升了 2.39 倍,相比 BERT-Base 性能提升了 7.09 倍,在 Intel® Xeon® Gold 6271C CPU @ 2.60GHz、线程数为 8 的情况下性能提升了 1.27 倍,相比 BERT-Base 性能提升了 5.13 倍。加速效果如下图所示:
 
  
 使用 FastTokenizer 的方式非常简单,在安装 fast_tokenizer 包之后,仅需在 tokenizer 实例化时直接传入 use_fast=True 即可。目前已在 Linux 系统下支持 BERT、ERNIE、TinyBERT 等模型。
如需设置切词线程数,需要调用fast_tokenizer.set_thread_num接口进行设置:
调用 from_pretrained 时只需轻松传入一个参数 use_fast=True:
2.5 部署
2.5.1 动转静导出:首先把动态图模型转换为静态图:
2.5.2 Paddle Inference
使用 PaddleInference:
部分结果展示:
2.5.3 Paddle Serving 部署
Paddle Serving 的详细文档请参考 Pipeline_Design和Serving_Design,首先把静态图模型转换成 Serving 的格式:
- 参数含义说明 - dirname: 需要转换的模型文件存储路径,Program 结构文件和参数文件均保存在此目录。- model_filename: 存储需要转换的模型 Inference Program 结构的文件名称。如果设置为 None ,则使用- __model__作为默认的文件名- params_filename: 存储需要转换的模型所有参数的文件名称。当且仅当所有模型参数被保>存在一个单独的二进制文件中,它才需要被指定。如果模型参数是存储在各自分离的文件中,设置它的值为 None- server_path: 转换后的模型文件和配置文件的存储路径。默认值为 serving_server- client_path: 转换后的客户端配置文件存储路径。默认值为 serving_client- fetch_alias_names: 模型输出的别名设置,比如输入的 input_ids 等,都可以指定成其他名字,默认不指定- feed_alias_names: 模型输入的别名设置,比如输出 pooled_out 等,都可以重新指定成其他模型,默认不指定
这里需要注意,
dirname参数在 paddle2.5.0 版本中 serving_io.inference_model_to_serving 算子中被移除了,目前使用 paddle2.4.2 版本即可。最后在 serving_sever 会生成 4-5 个文件
也可以运行下面的 bash 脚本:自行修改参数
Paddle Serving 的部署有两种方式,第一种方式是 Pipeline 的方式,第二种是 C++的方式,下面分别介绍这两种方式的用法:
Pipeline 方式部署
- 修改 config_nlp.yml 文件中 model 路径 
- 修改 Tokenizer,web_service.py 
启动 Pipeline Server:
启动客户端调用 Server。
首先修改 rpc_client.py 中需要预测的样本:
 
 模型输出:
 
 如果遇到结果越界等问题,请更改 paddle 版本,目前使用 paddle 2.4.0 develop 版本 【介于 2.40 2.50 之间】
C++的方式部署
启动 C++的 Serving:
 
 遇到相关问题请参考:https://blog.csdn.net/sinat_39620217/article/details/131675175
time to cost :0.006819009780883789 seconds[0.96249247]
也可以使用 curl 方式发送 Http 请求:
3.基于 RocketQA 的 CrossEncoder 训练的单塔模型
基于 RocketQA 的 CrossEncoder(交叉编码器)训练的单塔模型,该模型用于搜索的排序阶段,对召回的结果进行重新排序的作用。
CrossEncoder 和 Pairwise 区别:
- 输入方式: - Pairwise 模型:接受两个文本对作为输入,通常是一个正例和一个负例。正例表示相关的文本对,负例表示不相关的文本对。 - CrossEncoder 模型:接受多个文本对作为输入,可以同时处理多个文本对的相关性判断。 
- 训练方式: - Pairwise 模型:通过训练模型来学习区分正例和负例之间的特征。模型会比较两个文本对之间的相似度或相关性,并为每个文本对产生一个得分或预测标签。 - 通过将文本对转化为三个样本来训练:正样本(相关的文本对),负样本(不相关的文本对),以及参考样本(用于度量两个样本之间的相关性)。这个模型的目标是训练一个二分类器,将正样本得分高于负样本。经过编码器(通常是基于深度学习的模型,如 BERT)进行编码。然后,编码后的文本会通过一个相似度计算方法(如余弦相似度或点积)生成一个相关性得分,用于判断文本对的相关性。 - CrossEncoder 模型:一次性对多个文本对进行编码和判断。模型会将多个文本对作为整体输入,学习捕捉多个文本对之间的关系,并输出它们之间的相关性得分或标签。 - 将一对文本作为单个样本来训练,不需要额外的负样本和参考样本。这个模型的目标是训练一个多分类器,将不同的文本对分为相关的和不相关的类别。它们经过编码器进行编码,并在编码后的表示上应用一个多层感知机或其他类型的全连接网络。该网络将文本对的编码表示映射到相关性得分或概率。 
- 处理效率: - Pairwise 模型:由于是逐对比较,处理效率相对较低。需要遍历每对文本对进行比较和预测,特别是在大规模的文本对数据集上训练和推断时,效率会较低。 - CrossEncoder 模型:可以一次性处理多个文本对,因此在处理大规模文本对任务时具有较高的效率。能够进行批量处理,减少了逐对比较的时间消耗。 
- 应用场景: - Pairwise 模型:常用于文本排序或排名任务,如搜索引擎中的搜索结果排序、推荐系统中的推荐列表排序等。 - CrossEncoder 模型:适用于需要同时处理多个文本对的任务,如阅读理解中的问题-答案匹配、文本匹配中的相似性判断等。 
Pairwise 模型更适用于在大规模数据集上进行训练,因为它可以从大量的正样本和负样本中学习到相关性特征。而 CrossEncoder 模型则不需要额外的负样本,因此在训练数据有限的情况下可能更容易实现。
3.1 代码结构
- [literature_search_rank]数据集情况 
3.2 模型训练
参数情况:
部分结果展示:
3.3 模型评估
3.4 模型预测+FastTokenizer 加速
部分结果展示:
3.5 部署
- 动转静导出:首先把动态图模型转换为静态图 
参数含义说明
- dirname: 需要转换的模型文件存储路径,Program 结构文件和参数文件均保存在此目录。
- model_filename: 存储需要转换的模型 Inference Program 结构的文件名称。如果设置为 None ,则使用- __model__作为默认的文件名
- params_filename: 存储需要转换的模型所有参数的文件名称。当且仅当所有模型参数被保>存在一个单独的二进制文件中,它才需要被指定。如果模型参数是存储在各自分离的文件中,设置它的值为 None
- server_path: 转换后的模型文件和配置文件的存储路径。默认值为 serving_server
- client_path: 转换后的客户端配置文件存储路径。默认值为 serving_client
- fetch_alias_names: 模型输出的别名设置,比如输入的 input_ids 等,都可以指定成其他名字,默认不指定
- feed_alias_names: 模型输入的别名设置,比如输出 pooled_out 等,都可以重新指定成其他模型,默认不指定
终端启动效果如下:
 
  
 C++的方式:Client 可以使用 http 或者 rpc 两种方式参考第二章节相关步骤即可
总结
 
 整体 CrossEncoder 训练方式优于 pairwise,这里我就不长时间训练下去,仅简单增加训练时长进行对比验证了一下。
本项目提供了排序模块有 2 种选择:第一种基于前沿的预训练模型 ERNIE,训练 Pair-wise 语义匹配模型;
第二种是基于 RocketQA 模型训练的 Cross Encoder 模型。
CrossEncoder 和 Pairwise 区别:
输入方式:
Pairwise 模型:接受两个文本对作为输入,通常是一个正例和一个负例。正例表示相关的文本对,负例表示不相关的文本对。
CrossEncoder 模型:接受多个文本对作为输入,可以同时处理多个文本对的相关性判断。
训练方式:
- Pairwise 模型:通过训练模型来学习区分正例和负例之间的特征。模型会比较两个文本对之间的相似度或相关性,并为每个文本对产生一个得分或预测标签。 
通过将文本对转化为三个样本来训练:正样本(相关的文本对),负样本(不相关的文本对),以及参考样本(用于度量两个样本之间的相关性)。这个模型的目标是训练一个二分类器,将正样本得分高于负样本。经过编码器(通常是基于深度学习的模型,如 BERT)进行编码。然后,编码后的文本会通过一个相似度计算方法(如余弦相似度或点积)生成一个相关性得分,用于判断文本对的相关性。
- CrossEncoder 模型:一次性对多个文本对进行编码和判断。模型会将多个文本对作为整体输入,学习捕捉多个文本对之间的关系,并输出它们之间的相关性得分或标签。 
将一对文本作为单个样本来训练,不需要额外的负样本和参考样本。这个模型的目标是训练一个多分类器,将不同的文本对分为相关的和不相关的类别。它们经过编码器进行编码,并在编码后的表示上应用一个多层感知机或其他类型的全连接网络。该网络将文本对的编码表示映射到相关性得分或概率。
处理效率:
- Pairwise 模型:由于是逐对比较,处理效率相对较低。需要遍历每对文本对进行比较和预测,特别是在大规模的文本对数据集上训练和推断时,效率会较低。 
- CrossEncoder 模型:可以一次性处理多个文本对,因此在处理大规模文本对任务时具有较高的效率。能够进行批量处理,减少了逐对比较的时间消耗。 
应用场景:
- Pairwise 模型:常用于文本排序或排名任务,如搜索引擎中的搜索结果排序、推荐系统中的推荐列表排序等。 
- CrossEncoder 模型:适用于需要同时处理多个文本对的任务,如阅读理解中的问题-答案匹配、文本匹配中的相似性判断等。 
Pairwise 模型更适用于在大规模数据集上进行训练,因为它可以从大量的正样本和负样本中学习到相关性特征,但对于噪声数据更为敏感,即一个错误的标注会导致多个 pair 对的错误。而 CrossEncoder 模型则不需要额外的负样本,因此在训练数据有限的情况下可能更容易实现。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/46e1beb4dde8800678b2d5d12】。文章转载请联系作者。











 
    
评论