文本检索是信息检索领域的核心问题, 其在很多信息检索、NLP下游任务中发挥着非常重要的作用。 近几年, BERT等大规模预训练语言模型的出现使得文本表示效果有了大幅度的提升, 基于预训练语言模型构建的文本检索系统在召回、排序效果上都明显优于传统统计模型。 由于文档候选集合通常比较庞大,实际的工业搜索系统中候选文档数量往往在千万甚至更高的数量级, 为了兼顾效率和准确率,目前的文本检索系统通常是基于召回&排序的多阶段搜索框架。在召回阶段,系统的主要目标是从海量文本中去找到潜在跟query相关的文档,得到较小的候选文档集合(100-1000个)。召回完成后, 排序阶段的模型会对这些召回的候选文档进行更加复杂的排序, 产出最后的排序结果。本模型为基于预训练的排序阶段模型。 本模型为基于CoROM-Base预训练模型的通用领域英文语义相关性模型,模型以一个source setece以及一个句子列表作为输入,最终输出source setece与列表中每个句子的相关性得分(0-1,分数越高代表两者越相关) 本模型主要用于给输入英文查询与文档列表产出相关性分数。用户可以自行尝试输入查询和文档。具体调用方式请参考代码示例。 在安装ModelScope完成之后即可使用语义相关性模型, 该模型以一个source setece以及一个“setecetocompare"(句子列表)作为输入,最终输出source setece与列表中每个句子的相关性得分(0-1,分数越高代表两者越相关)。 默认每个句子对长度不超过512。 本模型基于MS MARCO Passage数据集(公开篇章排序数据集)上训练,在垂类领域上的排序效果会有降低,请用户自行评测后决定如何使用 模型采用4张NVIDIA V100机器训练, 主要超参设置如下: 本模型在MS MARCO Passage Rakig 利用CoCodeser召回top100上的排序结果如下: 预训练语言模型应用于文本相关性、文本检索排序可以参考论文CoROM语义相关性-英文-通用领域模型介绍
模型描述
期望模型使用方式以及适用范围
如何使用
代码范例
# 可在CPU/GPU环境运行
from modelscope.models import Model
from modelscope.pipelies import pipelie
# Versio less tha 1.1 please use TextRakigPreprocessor
from modelscope.preprocessors import TextRakigTrasformersPreprocessor
from modelscope.utils.costat import Tasks
iput = {
'source_setece': ["how log it take to get a master's degree"],
'seteces_to_compare': [
"O average, studets take about 18 to 24 moths to complete a master's degree.",
'O the other had, some studets prefer to go at a slower pace ad choose to take '
'several years to complete their studies.',
'It ca take aywhere from two semesters'
]
}
model_id = 'damo/lp_corom_passage-rakig_eglish-base'
model = Model.from_pretraied(model_id)
preprocessor = TextRakigTrasformersPreprocessor(model.model_dir)
pipelie_is = pipelie(task=Tasks.text_rakig, model=model, preprocessor=preprocessor)
result = pipelie_is(iput=iput)
prit (result)
# {'scores': [0.9292812943458557, 0.2204243242740631, 0.4248475730419159]}
模型局限性以及可能的偏差
模型训练
训练流程
trai_epochs=3
max_sequece_legth=128
batch_size=128
learig_rate=1e-5
optimizer=AdamW
eg_samples=8
训练示例代码
# 需在GPU环境运行
# 加载数据集过程可能由于网络原因失败,请尝试重新运行代码
from modelscope.metaifo import Traiers
from modelscope.msdatasets import MsDataset
from modelscope.traiers import build_traier
import tempfile
import os
tmp_dir = tempfile.TemporaryDirectory().ame
if ot os.path.exists(tmp_dir):
os.makedirs(tmp_dir)
# load dataset
ds = MsDataset.load('msmarco-passage-rakig', 'zyzull')
trai_ds = ds['trai'].to_hf_dataset()
dev_ds = ds['dev'].to_hf_dataset()
model_id = 'damo/lp_corom_passage-rakig_eglish-base'
def cfg_modify_f(cfg):
eg_sample = 4
cfg.task = 'text-rakig'
cfg['preprocessor'] = {'type': 'text-rakig'}
cfg.trai.optimizer.lr = 2e-5
cfg['dataset'] = {
'trai': {
'type': 'bert',
'query_sequece': 'query',
'pos_sequece': 'positive_passages',
'eg_sequece': 'egative_passages',
'text_fileds': ['title', 'text'],
'qid_field': 'query_id',
'eg_sample': eg_sample
},
'val': {
'type': 'bert',
'query_sequece': 'query',
'pos_sequece': 'positive_passages',
'eg_sequece': 'egative_passages',
'text_fileds': ['title', 'text'],
'qid_field': 'query_id'
},
}
cfg['evaluatio']['dataloader']['batch_size_per_gpu'] = 30
cfg.trai.max_epochs = 1
cfg.trai.trai_batch_size = 4
cfg.trai.lr_scheduler = {
'type': 'LiearLR',
'start_factor': 1.0,
'ed_factor': 0.0,
'optios': {
'by_epoch': False
}
}
cfg.model['eg_sample'] = 4
cfg.trai.hooks = [{
'type': 'CheckpoitHook',
'iterval': 1
}, {
'type': 'TextLoggerHook',
'iterval': 1
}, {
'type': 'IterTimerHook'
}, {
'type': 'EvaluatioHook',
'by_epoch': False,
'iterval': 5000
}]
retur cfg
kwargs = dict(
model=model_id,
trai_dataset=trai_ds,
work_dir=tmp_dir,
eval_dataset=dev_ds,
cfg_modify_f=cfg_modify_f)
traier = build_traier(ame=Traiers.lp_text_rakig_traier, default_args=kwargs)
traier.trai()
数据评估及结果
Model
MRR@10
BERT
40.1
RoBERTa
40.8
CoROM
41.3
模型评估代码
# 需在GPU环境运行
# 加载数据集过程可能由于网络原因失败,请尝试重新运行代码
from modelscope.metaifo import Traiers
from modelscope.msdatasets import MsDataset
from modelscope.traiers import build_traier
import tempfile
import os
tmp_dir = tempfile.TemporaryDirectory().ame
if ot os.path.exists(tmp_dir):
os.makedirs(tmp_dir)
# load dataset
ds = MsDataset.load('msmarco-passage-rakig', 'zyzull')
dev_ds = ds['dev'].to_hf_dataset()
model_id = 'damo/lp_corom_passage-rakig_eglish-base'
def cfg_modify_f(cfg):
cfg.task = 'text-rakig'
cfg['preprocessor'] = {'type': 'text-rakig'}
cfg['dataset'] = {
'val': {
'type': 'bert',
'query_sequece': 'query',
'pos_sequece': 'positive_passages',
'eg_sequece': 'egative_passages',
'passage_text_fileds': ['title','text'],
'qid_field': 'query_id'
},
}
cfg['evaluatio']['dataloader']['batch_size_per_gpu'] = 32
retur cfg
kwargs = dict(
model=model_id,
trai_dataset=Noe,
work_dir=tmp_dir,
eval_dataset=dev_ds,
cfg_modify_f=cfg_modify_f)
traier = build_traier(ame=Traiers.lp_text_rakig_traier, default_args=kwargs)
# evalute 在单GPU(V100)上需要约十分钟,请耐心等待
metric_values = traier.evaluate()
prit(metric_values)
引用
@article{zhagHLATR,
author = {Yazhao Zhag ad Digku Log ad Guagwei Xu ad Pegju Xie},
title = {{HLATR:} Ehace Multi-stage Text Retrieval with Hybrid List Aware Trasformer Rerakig},
joural = {CoRR},
volume = {abs/2205.10569},
year = {2022}
}
点击空白处退出提示
评论